码迷,mamicode.com
首页 > 其他好文 > 详细

装饰者模式

时间:2018-05-31 22:00:11      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:pen   inf   方法   img   修改   策略   装饰者   需要   off   

装饰者模式:动态将责任附加到对象上。若要扩展功能,装饰者提供了比集成更有弹性的替代方案。

原则:封装变化;多用组合,少用继承;针对接口编程,不针对实现编程;为交互对象之间的松耦合设计而努力;对扩展开放,对修改关闭。

技术分享图片

技术分享图片

Beverage是抽象基类,是被装饰者,getDescription()有基本实现,子类可重写,cost()是抽象方法,子类必须重写。HouseBlend,DarkRoast,Espresso,Decaf是具体的被装饰者,只需要扩展实现基类中的cost()方法。CondimentDecorator是装饰者抽象基类,继承自Beverage,下面的四个是具体的装饰者子类。扩展实现cost()和getDescription()方法,cost()需要将自己的花费加上。

Beverage抽象基类被装饰者:

技术分享图片
1 public abstract class Beverage {
2 
3     String description = "Unknown Beverage";
4     
5     public String getDescription() {
6         return description;
7     }
8     public abstract double cost();
9 }
View Code

CondimentDecorator抽象基类装饰者:

技术分享图片
1 public abstract class CondimentDecorator extends Beverage{
2     public abstract String getDescription();
3 }
View Code

DarkRoast具体被装饰者子类:

技术分享图片
 1 public class DarkRoast extends Beverage {
 2 
 3     public DarkRoast() {
 4         description = "DarkRoast";
 5     }
 6     public double cost() {
 7         return 0.99;
 8     }
 9 
10 }
View Code

Mocha具体装饰者子类:

技术分享图片
 1 public class Mocha extends CondimentDecorator{
 2     Beverage beverage;
 3     
 4     public Mocha(Beverage beverage) {
 5         this.beverage = beverage;
 6     }
 7     public String getDescription() {
 8         System.out.println("mochaDescription");
 9         return beverage.getDescription() + ",Mocha";
10     }
11     public double cost() {
12         System.out.println("mochaCost");
13         return 0.20 + beverage.cost();
14     }
15 }
View Code

Whip具体装饰者子类:

技术分享图片
 1 public class Whip extends CondimentDecorator{
 2     Beverage beverage;
 3     
 4     public Whip(Beverage beverage) {
 5         this.beverage = beverage;
 6     }
 7     public String getDescription() {
 8         System.out.println("whipDescription");
 9         return beverage.getDescription() + ",Whip";
10     }
11     public double cost() {
12         System.out.println("whipCost");
13         return 0.10 + beverage.cost();
14     }
15 }
View Code

测试类:

技术分享图片
 1 public class StarbuzzCoffee {
 2 
 3     public static void main(String[] args) {
 4         Beverage beverage = new Espresso();
 5         System.out.println(beverage.getDescription() + "$" + beverage.cost());
 6         Beverage beverage2 = new DarkRoast();
 7         beverage2 = new Mocha(beverage2);
 8         beverage2 = new Mocha(beverage2);
 9         beverage2 = new Whip(beverage2);
10         System.out.println(beverage2.getDescription() + "$" + beverage2.cost());
11     }
12 
13 }
View Code

技术分享图片

 

 

1.装饰者和被装饰者对象具有相同的超类型,所以在任何使用被装饰者对象的场合,可以用装饰过的对象来代替它。(所以装饰者类反映出被装饰的组件的类型)

2.装饰者不仅可以装饰具体构件,还可以装饰装饰者

3.装饰者和被装饰者都继承(或实现)自相同的超类型(Component),我们是利用继承达到“类型匹配”,而不是利用继承获得“行为”。当我们将装饰者与组件(或装饰者)组合时,加入的新的行为并不是继承自超类,而是由组合对象(ConcreteComponent或ConcreteDecorator)得来的。

4.虽然装饰者模式可以为设计注入弹性,但装饰者也常常造成设计中有大量的小对象,如果过度使用会让程序变得很复杂。

5.装饰模式VS继承:装饰模式是使用组合和委托用来扩展特定对象的功能,不需要子类,动态地在运行时给对象加上新的行为,防止了由于子类而导致的复杂和混乱,具有更多的灵活性。而继承是用来扩展一类对象的功能,需要子类,静态地在编译时分派职责,导致了很多子类的产生,缺乏灵活性。

6.装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型

7.Decorator装饰者角色并不是必须的,当你仅需要添加一个职责时,没有必要定义抽象Decorator类。你常常需要处理现存的类层次结构而不是设计一个新系统,这时你可以把Decorator向Component转发请求的职责合并到Concrete Decorator中。

8.改变对象外壳与改变对象内核:我们可以将Decorator看作一个对象的外壳,它可以改变这个对象的行为。另外一种方法是改变对象的内核。例如, Strategy(策略)模式就是一个用于改变内核的很好的模式。

 

I/O应用:

技术分享图片

技术分享图片

 

装饰者模式

标签:pen   inf   方法   img   修改   策略   装饰者   需要   off   

原文地址:https://www.cnblogs.com/cing/p/9119032.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!