目录java
装饰模式能够在不改变一个对象自己功能的基础上给对象增长额外的新行为。git
装饰模式是一种用于替代继承的技术,它经过一种无须定义子类的方式来给对象动态增长职责,使用对象之间的关联关系取代类之间的继承关系。在装饰模式中引入了装饰类,在装饰类中既能够调用待装饰的原有类的方法,还能够增长新的方法,以扩充原有类的功能。编程
装饰模式(Decorator Pattern):动态地给一个对象增长一些额外的职责,就增长对象功能来讲,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。设计模式
在装饰模式中,为了让系统具备更好的灵活性和可扩展性,咱们一般会定义一个抽象装饰类,而将具体的装饰类做为它的子类,装饰模式结构如图所示:ide
原本Car只有驾驶功能,为了动态地给Car加一些其余的功能,好比加上一个电视,或者放几瓶水,使用装饰模式实现以下:性能
抽象构件类Icarthis
public interface ICar { void drive(); }
具体构建类1加密
public class Jeep implements ICar { @Override public void drive() { System.out.println("驾驶吉普车啦"); } }
具体构建类2设计
public class Lorry implements ICar { @Override public void drive() { System.out.println("开货车啦"); } }
抽象装饰类调试
public abstract class CarDecorator implements ICar { private ICar car; public CarDecorator(ICar car) { this.car = car; } @Override public void drive() { car.drive(); } }
具体装饰类1
public class TvCarDecorator extends CarDecorator { public TvCarDecorator(ICar car) { super(car); } @Override public void drive() { addTv(); super.drive(); } public void addTv(){ System.out.println("为这部车安装了电视咯"); } }
具体装饰类2
public class WaterCarDecorator extends CarDecorator { public WaterCarDecorator(ICar car) { super(car); } @Override public void drive() { addWater(); super.drive(); } public void addWater(){ System.out.println("为车子放了几瓶水"); } }
客户端
public class Client { public static void main(String[] args) { ICar jeepCar,lorryCar,tvCar,waterCar1,waterCar2; jeepCar=new Jeep(); lorryCar=new Lorry(); tvCar=new TvCarDecorator(jeepCar); waterCar1=new WaterCarDecorator(tvCar); waterCar1.drive(); System.out.println("------------"); waterCar2=new WaterCarDecorator(lorryCar); waterCar2.drive(); } } //为车子放了几瓶水 //为这部车安装了电视咯 //驾驶吉普车啦 //------------ //为车子放了几瓶水 //开货车啦
能够将装饰了一次以后的tvCar对象注入另外一个装饰类WaterCarDecorator中实现第二次装饰,获得一个通过两次装饰的对象waterCar1,再调用waterCar1的drive()方法便可获得一个既有电视机又有放了水的吉普车。
在透明装饰模式中,要求客户端彻底针对抽象编程,装饰模式的透明性要求客户端程序不该该将对象声明为具体构件类型或具体装饰类型,而应该所有声明为抽象构件类型。对于客户端而言,具体构件对象和具体装饰对象没有任何区别。
没法单独调用新增的行为,好比
tvCar.addTv();
透明装饰模式可让客户端透明地使用装饰以前的对象和装饰以后的对象,无须关心它们的区别,此外,还能够对一个已装饰过的对象进行屡次装饰,获得更为复杂、功能更为强大的对象。在实现透明装饰模式时,要求具体装饰类的operation()方法覆盖抽象装饰类的operation()方法,除了调用原有对象的operation()外还须要调用新增的addedBehavior()方法来增长新行为。
为了可以调用到新增方法,咱们不得不用具体装饰类型来定义装饰以后的对象,而具体构件类型仍是可使用抽象构件类型来定义,这种装饰模式即为半透明装饰模式,也就是说,对于客户端而言,具体构件类型无须关心,是透明的;可是具体装饰类型必须指定,这是不透明的。
ICar jeepCar=new Jeep(); TvCarDecorator tvCar=new TvCarDecorator(jeepCar); tvCar.addTv();
半透明装饰模式能够给系统带来更多的灵活性,设计相对简单,使用起来也很是方便;可是其最大的缺点在于不能实现对同一个对象的屡次装饰(由于该对象新增的方法后面加入装饰类的时候仍是没法调用,因此是不完全的装饰),并且客户端须要有区别地对待装饰以前的对象和装饰以后的对象。
装饰模式下降了系统的耦合度,能够动态增长或删除对象的职责,并使得须要装饰的具体构件类和具体装饰类能够独立变化,以便增长新的具体构件类和具体装饰类。在JavaIO中的输入流和输出流的设计、javax.swing包中一些图形界面构件功能的加强,多重加密的设计能够运用装饰模式。