1.什么是装饰者模式
装饰者模式就是是动态地将责任附加到对象上,要扩展功能,装饰者提供有别于继承的另一种选择。
2.装饰者模式的优点
有效地把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
3.装饰者模式的特点
1.装饰者与被装饰对象有相同的超类型。
2.可以用一个或多个装饰者包装一个对象。
3.既然装饰者与被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。
4.装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定目的。
5.对象可以在任何时候被装饰,所以可以在运行时动态地,不限量地用你喜欢的装饰者来装饰对象。
4.装饰者模式结构图
5.案例展示
01.FineryComponent.java
/**
* 抽象组件又叫被装饰对象的基类
* @author shixiangcheng
* 2019-12-05
*/
public interface FineryComponent {
/**
* 穿着服饰方法
*/
public void show();
}
02.PersonConcreteComponent.java
/**
* 具体组件又叫具体被装饰对象
* @author shixiangcheng
* 2019-12-05
*/
public class PersonConcreteComponent implements FineryComponent{
private String name;
public PersonConcreteComponent(String name) {
this.name = name;
}
public void show(){
System.out.println("装扮的:"+name);
}
}
03.FineryDecorator.java
/**
* 装饰者抽象类
* @author shixiangcheng
* 2019-12-05
*/
public abstract class FineryDecorator implements FineryComponent{
private FineryComponent fineryComponent;
public void setFineryComponent(FineryComponent fineryComponent) {
this.fineryComponent = fineryComponent;
}
@Override
public void show() {
this.fineryComponent.show();
}
}
04.BigTrouser.java
/**
* 具体装饰者
* @author shixiangcheng
* 2019-12-05
*/
public class BigTrouser extends FineryDecorator {
@Override
public void show() {
super.show();
System.out.println("穿大裤衩");
}
}
05.TShirts.java
/**
* 具体装饰者
* @author shixiangcheng
* 2019-12-05
*/
public class TShirts extends FineryDecorator {
@Override
public void show() {
super.show();
System.out.println("穿T恤");
}
}
06.Test.java
/**
* 测试类
* @author shixiangcheng
* 2019-12-05
*/
public class Test {
public static void main(String[] args) {
PersonConcreteComponent p=new PersonConcreteComponent("张三");
BigTrouser b=new BigTrouser();
TShirts t=new TShirts();
b.setFineryComponent(p);
t.setFineryComponent(b);
t.show();
}
}
执行结果
装扮的:张三
穿大裤衩
穿T恤
6.总结
当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,但这种做法的问题就在于,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。而装饰者模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地,按顺序地使用装饰功能包装对象了。