1.装饰模式的概念
定义:表示动态的给一个对象添加一些新的功能,但是比生成子类方式更灵活。(当然利用子类继承父类也可以实现,但是不推荐)
核心:动态地扩展一个实现类的功能。(装饰模式是继承关系的一个替换方案,不管装饰多少层,返回的对象构件角色)
角色:
抽象构件(Component)角色:定义一个对象接口,可以给这些对象动态添加职责。
具体构件(ConcreteComponent)角色:是定义了一个具体的对象(例如:车),也可以给这个对象添加一些其他职责。
装饰(Decorator)角色:装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对Component来说,是无需知道Decorator存在的。
具体装饰(ConcreteDecorator)角色:就是具体的装饰对象了(飞车,水车..),它起到了给Component添加职责的功能。这里通过一个实例来写吧,未来汽车,听上去好像很高大上的样子,未来超级汽车可以飞,可以在水上航行,可以。。。大家大开脑洞去想吧。。哈哈!
2.UML图
3.具体代码
1.抽象构件:
public interface FutureCar {
public void move();
}
2.具体构件:
public class Car implements FutureCar{
@Override
public void move() {
System.out.println("汽车可以路上跑");
}
}
3.装饰角色:
public abstract class SuperCar implements FutureCar {
private FutureCar futureCar;
public SuperCar(FutureCar futureCar) {
super();
this.futureCar = futureCar;
}
@Override
public void move() {
futureCar.move();
}
}
4.具体装饰角色:
超级飞车:
public class FlyCar extends SuperCar {
public FlyCar(FutureCar futureCar) {
super(futureCar);
}
//新增加的功能,就是车可以在天上飞
public void fly(){
System.out.println("汽车可以天上飞");
}
public void move(){
super.move();
fly();//天上飞
}
}
超级水车:
public class SeaWayCar extends SuperCar {
public SeaWayCar(FutureCar futureCar) {
super(futureCar);
}
//新增加的功能,就是车可以在水里航行了
public void seaWay(){
System.out.println("汽车可以水里航行");
}
public void move(){
super.move();
seaWay();//海水航行
}
}
5.测试类:
public class Client {
public static void main(String[] args) {
//现在的车在路上跑
Car car=new Car();
car.move();
//超级汽车,可以在天上飞
System.out.println("------------------超级飞车,可以在天上飞-------------");
FlyCar flyCar=new FlyCar(car);
flyCar.move();
//超级汽车,可以在水里航行
System.out.println("------------------超级水车,可以在水里航行-------------");
SeaWayCar seaWayCar=new SeaWayCar(car);
seaWayCar.move();
//超级汽车,可以在路上跑,天上飞,水里航行
System.out.println("------------------超级汽车,可以在路上跑,天上飞,水里航行-------------");
SuperCar superCar=new SeaWayCar(new FlyCar(car));
superCar.move();
}
}
结果:
汽车可以路上跑
------------------超级飞车,可以在天上飞-------------
汽车可以路上跑
汽车可以天上飞
------------------超级水车,可以在水里航行-------------
汽车可以路上跑
汽车可以水里航行
------------------超级汽车,可以在路上跑,天上飞,水里航行-------------
汽车可以路上跑
汽车可以天上飞
汽车可以水里航行
4.小结
装饰模式是对继承的有力补充,单纯的使用继承时,在一些情况下就会增加很多子类,而灵活性差,不容易维护。这就是不推荐使用的原因,装饰模式是可以替换继承的,它解决类膨胀的问题,java中的输出输入流相关的类大量使用了装饰模式。最大的缺点就是,多层装饰是比较是复杂的。
以上都是个人一些学习总结,可能有些比较含糊,或者可能有错误,希望大家可以指出,欢迎吐槽。