浅谈设计模式(二):装饰器模式|中介模式|原型模式
装饰器模式
- 装饰器模式更灵活:继承时父子类的关系是静态的,而装饰器模式是动态的,装饰类和被装饰类的关系是运行时候确认的
- 装饰类和被装饰类的耦合关系是松散的,各自可以独立变化
// 1.首先我们有一个Pen接口 public interface Pen { public void write(); } // 2.Pencil类实现了Pen这个接口 public class Pencil implements Pen { public void write () { System.out.print("写"); } } // 3.装饰类PencilDecorator也实现了Pen这个接口,且代理调用Pencil的方法 public class PencilDecorator implements Pen{ Pen pen; public PencilDecorator(Pen pen) { this.pen = pen; } public void write () { pen.write(); } } // 4.用具体装饰类继承PencilDecorator,这样就可以做扩展变化 public class BluePencilDecorator extends PencilDecorator{ public BluePencilDecorator (Pen pen) { super(pen); } public void writeBlue () { this.write(); System.out.println("写出来是蓝色的"); } } // 同4.用具体装饰类继承PencilDecorator,这样就可以做扩展变化 public class RedPencilDecorator extends PencilDecorator{ public RedPencilDecorator (Pen pen) { super(pen); } public void writeRed () { this.write(); System.out.println("写出来是红色的"); } } // 测试 public class Test { public static void main(String args []) { Pen pencil = new Pencil(); RedPencilDecorator redPencil = new RedPencilDecorator(pencil); BluePencilDecorator bluePencil = new BluePencilDecorator(pencil); redPencil.writeRed(); bluePencil.writeBlue(); } }
- 第一,从构成上看,装饰器模式 = 代理模式 + 类继承。 也就是在代理模式的基础上,加了一堆继承[代理类]的子类,从而进行扩展变化,并且还尽量减少了和原有类的联系。
- 第二,从功能上看,代理模式侧重的是“控制”,而装饰器模式侧重的是“扩展”。比如说,类A代理了类B,那么这两个类由于同一个接口的约束,它们的方法和实现的功能其实是一样的。而类C装饰了类D,那么这个时候类C不仅仅具备了类D的方法,同时还能加入自己的特殊逻辑。
中介者模式
// Colleague接口 public interface Colleague { public void handleExternal(Mediator mediator); public void handleInternal(); } // 中介者接口 public abstract class Mediator { public Colleague A; public Colleague B; public Colleague C; public Mediator (Colleague A, Colleague B, Colleague C) { super(); this.A = A; this.B = B; this.C = C; } public abstract void handleA (); public abstract void handleB (); public abstract void handleC (); } // 实现了中介者接口的中介者类,封装了不同Colleague类的对象间的复杂操作 public class ConcreteMediator extends Mediator{ public ConcreteMediator(Colleague A, Colleague B, Colleague C) { super(A,B,C); } public void handleA() { B.handleInternal(); C.handleInternal(); } public void handleB() { A.handleInternal(); C.handleInternal(); } public void handleC() { A.handleInternal(); B.handleInternal(); } } // Colleague类在涉及其他Colleague类的复杂操作的时候,通过中介者调用 public class A implements Colleague { public void handleExternal(Mediator mediator) { mediator.handleA(); System.out.println("---------------"); } public void handleInternal() { System.out.println("A"); } } // Colleague类在涉及其他Colleague类的复杂操作的时候,通过中介者调用 public class B implements Colleague { public void handleExternal(Mediator mediator) { mediator.handleB(); System.out.println("---------------"); } public void handleInternal() { System.out.println("B"); } } // Colleague类在涉及其他Colleague类的复杂操作的时候,通过中介者调用 public class C implements Colleague { public void handleExternal(Mediator mediator) { mediator.handleC(); System.out.println("---------------"); } public void handleInternal() { System.out.println("C"); } } // 测试 public class main { public static void main(String args []) { Colleague a = new A(); Colleague b = new B(); Colleague c = new C(); Mediator mediator = new ConcreteMediator(a,b,c); a.handleExternal(mediator); b.handleExternal(mediator); c.handleExternal(mediator); } }
- 你有很多杂乱的物品摆放在房间的不同地方,找起来很不好找,现在把这些物品统一放到一个柜子里,方便集中管理。
- 一群人去食堂打饭的时候,如果各自去取菜那么食堂可能乱做一团,所以这时候食堂大妈就成为了“中介者”
原型模式
// 通过实现Cloneable接口并重写clone方法的方式,让Bar对象变得可克隆。 public class Bar implements Cloneable { String value; public String getValue () { return value; } public void setValue (String value) { this.value = value; } public Bar clone() { Bar clone = null; try { clone = (Bar)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } } // 调用clone方法可以克隆对象 public class mian { public static void main(String args []) { Bar bar = new Bar(); Bar bar2 = bar.clone(); bar.setValue("1"); bar2.setValue("2"); System.out.println(bar.getValue()); System.out.println(bar2.getValue()); } }
- 原型模式的优点: 底层的二进制实现拷贝,相比起new操作可以节约性能
- 原型模式的缺点: 构造函数没有调用,牺牲了灵活性