读书笔记-----------------------
装饰者模式:动态地将责任加到对象身上。如果要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。
利用组合和委托可以在运行时实现继承行为的效果,动态地给对象加上新的行为。
利用继承扩展子类的行为,是在编译时静态决定的;利用组合的做法,可以在运行时动态地扩展对象的行为。
软件设计原则:类应该对扩展开放,对修改关闭。这就是我们常说的开放-关闭原则。
开放-关闭原则使类容易扩展,在不修改代码的情况下,通过搭配实现新的行为。这样的设计可以应对改变,比如增加新功能或需求发生变更。
遵循开放-关闭原则设计系统,努力使关闭的部分(不变)和开放的部分(变化)隔离开来。
装饰者模式的几个缺点:
1有时在设计中加入大量的小类,变得不容易理解。
2有的客户端代码依赖于特定的类型(这是个比较糟糕的习惯,违反了“针对接口编程,而不是针对实现编程”的设计原则),当服务器端引入装饰者模式时,客户端就会出现状况。
3装饰者模式使得实例化组件的复杂度提升。
PS:工厂(Factory)模式和生成器(Builder)模式对于装饰者(Decorator)模式的这些缺点会有所帮助。
我的理解-------------------------
1 动态添加功能的顺序不影响最终的结果。
2 装饰者与被装饰者对象有相同的超类型。
3 在任何需要原始对象(被包装的)的场合,可以使用装饰过的对象来代替它。
2 这些装饰者也是从基类继承而来的,他们的构造方法都传递了一个基类对象。
3 对上转型的支持是其可以实现的本质。
代码实例-----------------------
public abstract class Car { String name = "Unknow Car"; public String getName() { return this.name; } public abstract float cost(); } // 标准型Benz汽车 public class BenzCar extends Car { public BenzCar() { this.name = "Benz"; } @Override public float cost() { return 100 * 10000.00f; } } // 标准型BMW汽车 public class BmwCar extends Car { public BmwCar() { this.name = "BMW"; } @Override public float cost() { return 50 * 10000.00f; } } // 标准QQ汽车 public class QQCar extends Car { public QQCar() { this.name = "QQ"; } @Override public float cost() { return 3 * 10000.00f; } } // 配件装饰者 public abstract class AccesoryDecorator extends Car { public abstract String getName(); } // 安全气囊配件 public class AirbagAccesory extends AccesoryDecorator { private Car car; public AirbagAccesory(Car car) { this.car = car; } @Override public String getName() { return car.getName() + ",Airbag"; } @Override public float cost() { return car.cost() + 1500; } } // 摄像头配件 public class CameraAccesory extends AccesoryDecorator { private Car car; public CameraAccesory(Car car) { this.car = car; } @Override public String getName() { return car.getName() + ",Camera"; } @Override public float cost() { return car.cost() + 800; } } // 收音机配件 public class RadioAccesory extends AccesoryDecorator { private Car car; public RadioAccesory(Car car) { this.car = car; } @Override public String getName() { return car.getName() + ",Radio"; } @Override public float cost() { return car.cost() + 600; } } // 测试程序 public class Test { public static void main(String[] args) { Car car1 = new RadioAccesory(new AirbagAccesory(new CameraAccesory(new BenzCar()))); printCarInfo(car1); Car car2 = new AirbagAccesory(new CameraAccesory(new BmwCar())); printCarInfo(car2); Car car3 = new RadioAccesory(new QQCar()); printCarInfo(car3); } public static void printCarInfo(Car car) { System.out.println("Car Name:" + car.getName() + ",Cost:" + car.cost()); } }