装饰者模式:动态地将责任附加到对象上,若要扩展,装饰者提供了比继承更有弹性的替代方案(貌似等于没说。。。定义一般都挺费解的)。
先说说一个重要的OO设计原则——开放-封闭原则:类应该对扩展开放,对修改关闭。该原则的设计目标:允许类容易扩展,在不修改现有代码的情况下,就可以搭配新的行为。这样的设计具有弹性,可以应付改变,可以接受新的功能来应对改变的需求。
遵循开放-封闭原则,通常会引入新的抽象层次,增加代码的复杂度,所以得用在确实需要的地方。我们需要将注意力集中在设计中最有可能改变的地方,然后应用开放-封闭原则。(在选择需要被扩展的代码部分时要小心。每个部分都采用开放-封闭原则是一种浪费,也没必要,且通常也难以做到,还会导致代码变得复杂且难以理解)。
装饰者模式的部分要点:
a. 装饰者和被装饰对象有相同的超类型(继承的祖先一样,也可以理解为装饰者和被装饰对象的类型一致),因此在任何需要原始对象(被包装的)场合,可以用装饰过的对象代替它;
b. 可以用一个或多个装饰者包装一个对象;
c. 装饰者可以在 所委托被装饰者 的行为 之前或之后,加上自己的行为,以达到特定的目的。(有点不好理解,待会儿有具体例子来说明)
d. 对象可以在任何时候被装饰,所以可以在运行时动态地,不限量地用你喜欢的装饰者来装饰对象。
下面来看看代码吧。。。
先写一个超类:
public abstract class Drink { string sDesc = "drink"; public string getDesc() { return sDesc; } public abstract double cost() {} }
接下来写 被装饰者 和 装饰者 的具体类
// 被装饰者
public class Coco extend Drink { public Coco() { sDesc = "Coco"; } public double cost() { return 2.5; } }
// 装饰者
public class Mocha extend Drink { Drink drink; public Mocha(Drink drink) { this.drink = drink; } public string getDesc() { return drink.getDesc() + ", Mocha"; // 装饰者模式的部分要点的 c 项:drink.getDesc() 即 所委托被装饰者 的行为(主料描述) // + ", Mocha" 即 加上自己的行为,以达到特定的目的(描述饮料总名称) } public double cost() { return drink.cost() + 0.5; // 装饰者模式的部分要点的 c 项:drink.cost() 即 所委托被装饰者 的行为(主料价格) // + 0.5 即 加上自己的行为,以达到特定的目的(描述饮料总价格) } }
最后看看是怎么调用的:
public class Test { public static void main(string args[]) { Drink drink = new Coco(); drink = new Mocha(drink); // 因为装饰者和被装饰者继承同一个超类 system.out.println(drink.getDesc() + drink.cost()); } }