装饰者模式是一种结构型模式 可以动态地给一个对象添加功能 这些功能也可以动态地被撤销
装饰者模式用到的设计原则:
1)多用组合 少用继承
2)开闭原则(对拓展开放 对修改关闭)
优点:
装饰者模式相比于继承更灵活 可以动态的为对象添加功能
缺点:
多层装饰时比较复杂 出错之后调试起来比较麻烦
装饰者模式实现步骤:
1)先定义一个顶级抽象类/接口 为了给对象动态地添加功能/职责
其中被装饰类也就是实际被动态添加功能的类 要继承/实现这个抽象类或接口
2)再定义一个抽象类 也去继承/实现上述抽象类或接口 是为了扩展顶级抽象类或接口的功能的
3)最后就是定义具体的装饰类了 这个类就是给被装饰类动态添加功能的
在类中将顶级接口作为属性 通过构造方法传入为其赋值
然后在这个类下就可以使用到被装饰类的方法 也可以定义新的功能
如下案例:
有一个男人 什么都没有 经过装饰 可以有车 有房
顶级接口:
package decorator;
/**
* 顶级的接口 目的是为了让被装饰对象的方法 和 Decorator 的方法名字统一
* 统一了以后 用户就分不清了 用起来方便些
*/
public interface Top {
String getAssets();
}
Man类(原始对象):
package decorator;
/**
* 原始对象
*/
public class Man implements Top{
private String name;
public Man(String name){
this.name = name;
}
public Man(){}
public String getAssets(){
return "我的名字是"+name+",我是一个男人,但我现在什么都没有!";
}
}
抽象的装饰者:
package decorator;
/**
* 定义装饰者规则
* 这个类的目的是为了装饰时可以随意的进行装配
* 而不是需要按照某种顺序一层一层的装饰
*/
public abstract class Decorator implements Top{
//因为具体装饰类都会用到top对象中的方法
//所以可以将其从具体类中抽离出来 放到这个类中 减少代码的冗余
protected Top top;
public Decorator(Top top){
this.top = top;
}
public abstract String getAssets();
}
具体装饰者1:
package decorator;
public class BuyCar extends Decorator{
public BuyCar(Top top){
super(top);
}
public String getAssets(){
//先获取被装饰类的结果
String msg = top.getAssets();
return msg+"经过努力,我有车了!";
}
}
具体装饰者2:
package decorator;
public class BuyHouse extends Decorator{
public BuyHouse(Top top){
//传递的参数是顶级接口
//所以此时参数就可以随便传 随意装饰
//而不是必须要按照某种顺序来进行装饰
super(top);
}
public String getAssets(){
//先获取被装饰类的结果
String msg = top.getAssets();
return msg+"经过努力,我有房了!";
}
}