设计模式之装饰者模式
?情景: 你是一个咖啡店老板,你会做很多种咖啡。 首先有一个超类,饮料类。 咖啡可以加很多种调料,就假设是A,B,C…… 那么你会有AB型的,AC型,BC型,A型的,B型,C型,ABC型的咖啡,那么你需要有六种具体子类。 如果有n种调料,你就要有(2^n-1)种具体子类有木有啊!!! 同时,如果,你添加了一种调料或者改变一种调料!!!会死人呐有木有!!! 怎么办???可以考虑使用组合(compisition)和委托(delegation)。 装饰者模式 以饮料为主体,然后在运行时,以调料来装饰(decorate)饮料。 设饮料价格是X,加了调料A,可以用A把X包装起来A(X),又加了调料B,再用B把A(x)包装起来,B(A(X))。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。 类图: 解决最开始的咖啡问题~~ 首先饮料类: = "Unknown Beverage"
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getDescription() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> description;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">abstract</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> cost();
} 然后是两种具体的饮料 Espresso = "Espresso" 1.99
<div class="cnblogs_code"> HouseBlend = "House Blend Coffee" 0.89
调料抽象类: CondimentDecorator
具体调料类(包装类): 摩卡 Mocha
Beverage beverage; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 被装饰者</span>
<span style="color: #0000ff;">public</span><span style="color: #000000;"> Mocha(Beverage beverage) {
</span><span style="color: #0000ff;">this</span>.beverage =<span style="color: #000000;"> beverage;
}
@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getDescription() {
</span><span style="color: #0000ff;">return</span> beverage.getDescription() + ",Mocha"<span style="color: #000000;">;
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> cost() {
</span><span style="color: #0000ff;">return</span> .20 +<span style="color: #000000;"> beverage.cost();
}
} 豆浆 Soy
Beverage beverage; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 被装饰者</span>
<span style="color: #0000ff;">public</span><span style="color: #000000;"> Soy(Beverage beverage) {
</span><span style="color: #0000ff;">this</span>.beverage =<span style="color: #000000;"> beverage;
}
@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getDescription() {
</span><span style="color: #0000ff;">return</span> beverage.getDescription() + ",Soy"<span style="color: #000000;">;
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> cost() {
</span><span style="color: #0000ff;">return</span> .15 +<span style="color: #000000;"> beverage.cost();
}
} 好了,测试一下: = Espresso();
System.out.println(beverage.getDescription() + " $" +
Beverage beverage2 </span>= <span style="color: #0000ff;">new</span> HouseBlend(); <span style="color: #008000;">//</span><span style="color: #008000;"> 一杯HouseBlend 加摩卡 加豆浆</span>
beverage2 = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Mocha(beverage2);
beverage2 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Soy(beverage2);
System.out.println(beverage2.getDescription() </span>+ " $" +<span style="color: #000000;"> beverage2.cost());
}
} 输出: Espresso $1.991.24
Java的io包中使用了装饰者模式。 ? ?编写自己的Java IO装饰者 <span style="color: #0000ff;">public <span style="color: #0000ff;">class LowerCaseInputStream <span style="color: #0000ff;">extends<span style="color: #000000;"> FilterInputStream {
<span style="color: #0000ff;">public<span style="color: #000000;"> LowerCaseInputStream(InputStream in) { <span style="color: #0000ff;">super<span style="color: #000000;">(in); }
} 测试一下:(使用了try-with-resources) = FileInputStream("test.txt" ((c = in.read()) > 0
test.txt内容:?? 输出:?? 装饰者模式的缺点: 会产生大量的类。实例化的时候会很复杂。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |