其实每个模式的名称就表明了该模式的作用,代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对改地区的房屋信息掌握不够全面,希望找一个更熟悉的人帮你去做,此处的代理就是这个意思。再如果我们有的时候打官司,我们需要请律师,因为律师在法律方面有专长,可以替我们操作,表达我们的想法。
1、UML
可以看到代理模式跟装饰者模式基本上一样的UML,但是实现是不同的,装饰者模式是将要装饰的对象传到到装饰者中,然后对对象进行额外操作,但是代理模式是直接在代理类中new对象,不需要外部传进来,全程交由代理模式解决。这个使他们的区别点。
2、装饰者模式和代理模式的区别
1、装饰模式:
在不改变接口的前提下,动态扩展对象的访问。
动态继承,让类具有在运行期改变行为的能力。
装饰模式,突出的是运行期增加行为,这和继承是不同的,继承是在编译期增加行为。
强调:增强
2、代理模式:
在不改变接口的前提下,控制对象的访问。
从封装的角度讲,是为了解决类与类之间相互调用而由此导致的耦合关系,可以说是接口的另外一个层引用。比如:在a类->b代理->c类这个关系中,c类的一切行为都隐藏在b中。即调用者不知道要访问的内容与代理了什么对象。
从复用的角度讲,可以解决不同类调用一个复杂类时,仅仅因较小的改变而导致整个复杂类新建一个类。比如:a类->c类1;b类->c类2。可以变为a类->ca代理类->c类;b类->cb代理类-c类。
代理模式,是类之间的封装和(某方面的)复用。
强调:限制
装饰模式可以让使用者直观的看到增强了哪些功能,而代理模式完全限制了使用者。客户端是看不到被代理类的任何操作。
3、Sourceable
/**
* 共同的接口
* @author suibibk.com
*/
public interface Sourceable {
public void method();
}
4、被代理类Source
/**
* 被代理类
* @author suibibk.com
*/
public class Source implements Sourceable{
@Override
public void method() {
System.out.println("打官司");
}
}
5、代理类Proxy
/**
* 代理模式:这里跟装饰者模式的区别是,不需要传入source对象
* @author suibibk.com
*/
public class Proxy implements Sourceable{
private Source source;
public Proxy() {
super();
source = new Source();
}
@Override
public void method() {
System.out.println("收集资料");
source.method();
System.out.println("法庭辩论");
}
}
这里就可以很明显的看到代码上跟装饰者模式的区别了,不需要外部传入Source,直接new实例。
6、测试类Test
/**
* 测试类:在客户端看不到Source的实例
* @author suibibk.com
*/
public class Test {
public static void main(String[] args) {
new Proxy().method();
}
}
可以看到,我们的客户端完全看不到Source的存在,运行结果如下:
收集资料
打官司
法庭辩论
总结
其实我上面的例子不是很符合,输出结果没有很好的区分装饰者模式和代理模式,但是呢,通过代码应该可以区分开来,其实按我的理解来说,代理模式,只需要一个代理,而装饰者模式,可能需要很多装饰者,可能是一个团队,就比如Java的IO来说,就有超级多装饰者,主要侧重于功能的增强,但是代理模式,感觉是侧重于委托。可能理解有误,望指正。