装饰者模式包含两种对象:装饰者和组件【被装饰者】
装饰者模式的核心思想:
1.替代继承,动态的将责任附加到对象上
2.有效的扩展行为同时不违反开闭原则
3.有效的复用修饰者
装饰者模式的设计原则:开闭原则,多用组合少用继承,低耦合
装饰者模式的用途:
1.需要生产大量的类
2.这些类又可以原子化成数量不多的小类
3.这些小类的组合可以构成(1)的类
装饰者模式的缺点:
1.组件不宜被过多的类装饰,代码会冗长(使用工厂模式可以有效解决)
2.如果一个装饰类同时装饰多种组件,维护仍是麻烦的(如咖啡加糖要收钱,但是甜品加糖就不需要收钱)
3.同一个组件被装饰者装饰多次【加10个鸡蛋】,只能重复调用装饰方法,特别是,这个装饰方法还是个构造函数的时候,你还需要不停的new
4.不可以用非同一类别的【不是继承自同一个父类/接口】修饰者修饰同一个组件。(如水、佐料都是食物,板蓝根是药品,来一份重口味的板蓝根泡面就很难实现,好像也不难,重写一下装饰方法就可以了...)
5.可以修饰组件,但是取消就非常麻烦,毕竟传递进去的对象是被处理过的,没有进行保存
简单示例
文本编辑中,句子和字的修饰关系【好像有点牵强,修饰者模式也算是组合吧】
package decratorpattern;
public interface Decrator {
/**
* 展示信息
* @return
*/
String display();
}
package decratorpattern;
public class Sentence implements Decrator{
Word words = new Word("");
@Override
public String display() {
return words.display();
}
/**
* 装饰
*
* @param d
*/
public void decrate(Word d) {
if(d != null)
{
words.connect(d);
}
}
}
package decratorpattern;
public class Word implements Decrator{
private String word = null;
public Word(String word)
{
this.word = word;
}
/**
* 展示内容
*/
@Override
public String display() {
String displayString = "";
if(word!=null)
{
displayString += word;
}
return displayString;
}
/**
* 装饰
*/
public void connect(Decrator d) {
if(d != null)
{
word += d.display();
}
}
}
package decratorpattern;
public class Test {
public static void main(String[] args) {
Word w1 = new Word("今天");
Word w2 = new Word("天气");
Word w3 = new Word("很好");
Word w4 = new Word("!");
Sentence s = new Sentence();
s.decrate(w1);
s.decrate(w2);
s.decrate(w3);
s.decrate(w4);
System.out.println(s.display());
}
}
测试结果
今天天气很好!