代理模式和装饰者模式非常之像,简直就是一样的感觉。想了很久,看了很多终于能够理解代理模式和装饰者模式的异同。网上有很多的文章说代理模式和装饰者模式的区别和相同,总是感觉差点意思,自己写一片文章去说明这个东西。
我想理解一种设计模式,不能光看其代码是什么样子的。而是了解其应用场景,应用场景,应用的地方,什么时候用,远比设计模式是什么样子的更加重要和实用,毕竟设计模式学了就是为了写代码服务,为了看源码服务。
代理模式和装饰者模式都是用来,在对 对象 进行动态的扩展。 这句话怎么理解呢, 首先理解对象的含义,对象我理解就是 jvm内存中的 含有数据的 一个整体,其实 对象在运行时候 含有的东西 只是它的成员变量所赋值的数据,当然还有方法。这里的 这句话的理解 就是在运行时候对 对象建立起来了,运行着呢 对它的方法和成员变量进行拓展,以使对象更加好用。想想一种场景你运行着程序呢,跑到这里了,需要进行一些操作 但是这些操作只和这个对象有关,你会怎么办呢???? 你肯定会想 在对象所处的类中用这个对象一些方法和成员变量进行操作,然而这种扩展方式是比较low的,假如这种操作代码有几百行,怎么办。这个时候就是需要代理模式和装饰者模式的出现了。
应用场景
代理模式 是 代替这个对象 在这个对象基础上进行拓展这个拓展包含成员变量的拓展和方法的拓展,你所拿到的对象也是一个。
装饰者模式是 在这个对象基础上增加一些成员变量和拓展方法,可以装饰出来一个对象,也可以装饰出来的类型有多个。而且,更加厉害的是 你在原来装饰的基础之上还可以再装饰。这个就比较厉害了。
区别 两点 1,代理模式 单一 装饰者模式多 2,装饰者模式 可以装饰再装饰 多层装饰。
这下我们知道了, 其实没什么区别,不过是 设计的应用的思想不一样,所选的设计模式不一样,本质上都是 一个新的类里面含有原对象,拓展方法和成员变量。然而 当你需要一个对象去拓展原对象时候,这个对象代替原对象去行事 这个时候就需要代理模式 当你需要一个对象也是去拓展原对象 ,但是呢 你需要的对象 可能是好几种类型的,可能拓展完了再拓展。这个时候 你需要装饰者模式。
All Right 附上代码说话。
代理模式
public interface Animal { void run(); }
package com.mrchen.mythirdspring.proxytest; public class Dog implements Animal{ @Override public void run() { System.out.println("dog run"); } }
package com.mrchen.mythirdspring.proxytest; public class DogProxy implements Animal{ Animal animal; public DogProxy(Animal animal) { this.animal = animal; } @Override public void run() { animal.run(); System.out.println("run happy"); } public void jump(){ System.out.println("dog jump"); } }
package com.mrchen.mythirdspring.proxytest; public class TestProxy { public static void main(String[] args){ Dog dog=new Dog(); DogProxy dogProxy=new DogProxy(dog); dogProxy.run(); } }
装饰者模式
package com.mrchen.mythirdspring.decortest; public interface Animal { void run(); }
package com.mrchen.mythirdspring.decortest; public class Dog implements Animal { @Override public void run() { System.out.println("dog run"); } }
package com.mrchen.mythirdspring.decortest; public abstract class DecorAbstract implements Animal{ private Animal animal; public DecorAbstract(Animal animal) { this.animal = animal; } @Override public void run() { animal.run(); } }
package com.mrchen.mythirdspring.decortest; public class GoodDog extends DecorAbstract{ public GoodDog(Animal animal) { super(animal); } @Override public void run() { super.run(); System.out.println("goo dog run"); } }
package com.mrchen.mythirdspring.decortest; public class SongDog extends DecorAbstract{ public SongDog(Animal animal) { super(animal); } @Override public void run() { super.run(); System.out.println("dog song 狗会唱歌"); } }
package com.mrchen.mythirdspring.decortest; public class TestDecor { public static void main(String[] args){ Animal animal=new Dog(); Animal goodDog=new GoodDog(animal); goodDog.run(); System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Animal songDog=new SongDog(goodDog); songDog.run(); } }