设计模式-装饰者模式(结构型)
2019-08-08 本文已影响0人
NealLemon
定义
在不改变原有对象的基础之上,将功能附加到对象上。提供了比继承更有弹性的替代方案(扩展原有对象功能)。
适用场景
- 扩展一个类的功能或给一个类添加附加职责
- 动态的给一个对象添加功能,这些功能也可以动态撤销
优点
- 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能。
- 通过使用不同的装饰类以及这些装饰类的排列组合,可以实现不同的效果。
- 符合开闭原则。
缺点
- 会出现更多的代码和类,增加程序的复杂性。
- 动态装饰时,多层装饰时会更复杂,不易于调试。
代码以及UML类图
对于我们程序员来说,选老婆的标准一定不能低了。我们就来用装饰者模式,来一步一步装饰我们心中的女神。
首先得是一个女生(当然你要是口味不同,另说)
其次必须 貌美 肤白 大长腿
好了,说的都流口水了。来 让我们来码出来吧。
代码
抽象一个女生类
/**
* 抽象girl
*/
public abstract class AbstractGirl {
/**
* 特点
* @return
*/
protected abstract String feature();
/**
* 描述
* @return
*/
protected abstract String getDesc();
}
具体实现我们心中模糊的标准的女生
/**
* 你眼中的女神
*/
public class YourGirl extends AbstractGirl {
@Override
protected String feature() {
return "是一个女生";
}
@Override
protected String getDesc() {
return "漂亮";
}
}
抽象一个具体装饰女生的标准类
/**
* 女神的装饰抽象方法
*/
public abstract class AbstractGirlDecorate extends AbstractGirl {
//将装饰类和装饰者关联
private AbstractGirl abstractGirl;
//通过构造函数关联
public AbstractGirlDecorate(AbstractGirl abstractGirl) {
this.abstractGirl = abstractGirl;
}
@Override
protected String feature() {
return this.abstractGirl.feature();
}
/**
* 其他描述,对自己的标准
*/
protected abstract void otherThings();
@Override
protected String getDesc() {
return this.abstractGirl.getDesc();
}
}
我们通过构造方法来关联被装饰的对象,在这里我们增加了一个otherThings()
抽象方法,用来补充,比如 我们如果想要一个漂亮又腿长的女生,那么我们需要做到什么样子的标准。
具体实现装饰标准 ---腿长装饰类
public class LongLegsGirlDecorate extends AbstractGirlDecorate {
public LongLegsGirlDecorate(AbstractGirl abstractGirl) {
super(abstractGirl);
}
@Override
protected String feature() {
return super.feature() + " 大长腿 ";
}
@Override
protected void otherThings() {
System.out.println("努力赚钱");
}
@Override
protected String getDesc() {
return super.getDesc() + "身高1米7";
}
}
具体实现装饰标准--肤白装饰类
public class WhiteSkinGirlDecorate extends AbstractGirlDecorate {
public WhiteSkinGirlDecorate(AbstractGirl abstractGirl) {
super(abstractGirl);
}
@Override
protected String feature() {
return super.feature() + " 皮肤白 ";
}
@Override
protected void otherThings() {
System.out.println("温柔体贴");
}
@Override
protected String getDesc() {
return super.getDesc() + " 面如凝脂 ";
}
}
做梦的开始类
public class DecoratorBootStrap {
public static void main(String[] args) {
//你心里的第一要求的女孩
AbstractGirl abstractGirl = new YourGirl();
//进一步细化一下,要求腿长
abstractGirl = new LongLegsGirlDecorate(abstractGirl);
System.out.println("想要一个腿长的女神,我们要");
((LongLegsGirlDecorate) abstractGirl).otherThings();
//既然腿长怎么可能少了肤白
abstractGirl = new WhiteSkinGirlDecorate(abstractGirl);
System.out.println("再想要腿长和肤白,我们要");
((WhiteSkinGirlDecorate) abstractGirl).otherThings();
System.out.println("你心里要求的女孩标准是" + abstractGirl.feature());
System.out.println("必须满足:" + abstractGirl.getDesc());
}
}
在这里 由于我们的抽象装饰类AbstractGirlDecorate
也继承AbstractGirl
,因此我们可以做相互转换。
UML 类图
decorator.jpg我们可以看到 一个抽象装饰类(AbstractGirlDecorate
),只装饰一个被装饰者对象(YourGirl
)。
做梦的结果展示
fighting.jpg小结
虽然代码的例子很屌丝,但是希望从众能看到装饰者这种设计模式的巧妙支持,以及他的缺点,合适的运用。