适配器模式(连接):允许因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
装饰器模式(增强):原有的不能满足现有的需求,对原有的进行增强。
代理模式(限制):同一个类而去调用另一个类的方法,不对这个方法进行直接操作。
这里,我们用一个狼外婆的故事:一只狼假装成狼外婆,最后失败的故事,来讲解着三种的联系
故事1:狼要假装成外婆,所以,需要穿上人的衣服
public interface HighAnimal { void highAnimal(String body, String think, String clothes); }
public class HighAnimalImpl implements HighAnimal { @Override public void highAnimal(String body, String think, String clothes) { System.out.println("这只动物具有"+body+"、"+think+"、"+clothes+",从外形上看,这是个人类。"); } }
public interface LowAnimal { void lowAnimal(String body); }
public class LowAnimalImpl implements LowAnimal { @Override public void lowAnimal(String body) { System.out.println("这只动物具有"+body+",从外形上看,这是个动物。"); } }
适配器模式:狼开始穿人的衣服,假装人类
public class Wolf1 implements LowAnimal { HighAnimal highAnimal; public Wolf1(){ highAnimal = new HighAnimalImpl(); } @Override public void lowAnimal(String body) { highAnimal.highAnimal(body, "伪装的思维", "伪装的衣服"); } }
验证:
public class Story1 { public static void main(String[] args) { LowAnimal wolf = new Wolf1(); wolf.lowAnimal("狼的身体"); } }
结果(控制台输出如下):
这只动物具有狼的身体、伪装的思维、伪装的衣服,从外形上看,这是个人类。
故事2:穿上衣服还不够,还需要能说会骗,要不然怎么让小红帽开门
装饰模式:对行为进行扩展,让狼说话
public class Wolf2 implements LowAnimal { LowAnimal lowAnimal; public Wolf2(Wolf1 wolf1){ this.lowAnimal = wolf1; } @Override public void lowAnimal(String body) { lowAnimal.lowAnimal(body); System.out.println("Ta学习了说话!"); } }
验证:
public class Story2 { public static void main(String[] args) { LowAnimal wolf = new Wolf2(new Wolf1()); wolf.lowAnimal("狼的身体"); } }
控制台输出:
这只动物具有狼的身体、伪装的思维、伪装的衣服,从外形上看,这是个人类。
Ta学习了说话!
故事3:因为自新中国成立以来,就不许动物成精了,所以,在入口的时候,加以控制,狼虽然学了说话,但是,还是死在了新中国的关辉中
代理模式:为其他对象提供一种代理控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
public class Wolf3 implements LowAnimal { LowAnimal lowAnimal; public Wolf3(){ lowAnimal = new Wolf2(new Wolf1()); } @Override public void lowAnimal(String body) { if(body.contains("狼")){ lowAnimal.lowAnimal(body); System.out.println("自新中国成立以来,就不许动物成精了!!!所以,狼死在了党的光辉中"); }else{ System.out.println("通过了代理的验证!"); } } }
验证:
public class Story3 { public static void main(String[] args) { LowAnimal wolf = new Wolf3(); wolf.lowAnimal("狼的身体"); } }
控制台输出:
这只动物具有狼的身体、伪装的思维、伪装的衣服,从外形上看,这是个人类。
Ta学习了说话!
自新中国成立以来,就不许动物成精了!!!所以,狼死在了党的光辉中
装饰模式 VS 代理模式
装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。
换句话说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。