鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > .net技术 > 控件开发 > >

每天一个设计模式 -9 装饰者模式

来源:互联网 作者:佚名 时间:2017-09-09 08:42
每天一个设计模式 -9 装饰者模式 一、现实 使用继承不总能够实现最有弹性和最好维护的设计。 利用组合和委托可以在运行时具有继承行为的效果。 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。 利用组合的做法扩展对象

每天一个设计模式 -9 装饰者模式

一、现实

  • 使用继承不总能够实现最有弹性和最好维护的设计。
  • 利用组合和委托可以在运行时具有继承行为的效果。

利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。

利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

二、认识装饰者模式

角色:

  • 装饰者
  • 组件

举例:

给咖啡添加调料(咖啡(组件或被装饰对象),调料(装饰者)种类很多。咖啡,调料需要付费)并能算出需要付款的总费用,用图形表示:

  1. 装饰者和被装饰对象有相同的超类型。
  2. 可以用一个或多个装饰者包装一个对象。
  3. 装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。
  4. 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,已达到特定的目的。
  5. 对象可以在任何时候被装饰,所以可以在运行是动态地,不限量的用你喜欢的装饰者来装饰对象。

三、定义装饰者模式

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

通用的类图:

对这个类图进行改造,完成上面的例子:

四、源代码

抽象类 Coffee:一个description字段,一个抽象方法cost,一个有默认实现的getDescription()方法

public abstract class Coffee {

     String description = "未知的咖啡";

    public Coffee(){

    }

    public void finalize() throws Throwable {

    }

    public abstract double cost();

    public String getDescription(){
        return description;
    }

}
Coffee

四个具体的Coffee类Coffee1,Coffee2...,继承自Coffee,实现抽象方法cost()

public class Coffee1 extends Coffee {

    public Coffee1(){
        description = "咖啡1";
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        return 10;
    }
}
public class Coffee2 extends Coffee {

    public Coffee2(){
        description = "咖啡2";
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        return 20;
    }
}
public class Coffee3 extends Coffee {

    public Coffee3(){
        description = "咖啡3";
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        return 30;
    }
}
public class Coffee4 extends Coffee {

    public Coffee4(){
        description = "咖啡4";
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        return 20;
    }
}
Coffee的具体类

抽象类 CondimentDectorator:继承自Coffee 一个抽象方法getDescription(),强制子类重写

public abstract class CondimentDecorator extends Coffee {

    public Coffee m_Coffee;

    public CondimentDecorator(){

    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public abstract String getDescription();
}
CondimentDectorator

三个具体的CondimentDectorator,Condiment1...,继承自CondimentDectorator,实现抽象方法getDescription()

public class Condiment1 extends CondimentDecorator {

    public Condiment1(Coffee coffee){
        m_Coffee = coffee;
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        //计算自己和被装饰的对象的价格
        return m_Coffee.cost()+0.9;
    }

    public String getDescription(){
        return m_Coffee.getDescription()+",Condiment1";
    }
}
//----------------------------------------------------------------------------
public class Condiment2 extends CondimentDecorator {

    public Condiment2(Coffee coffee){
        m_Coffee = coffee;
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        return m_Coffee.cost()+0.7;
    }

    public String getDescription(){
        return m_Coffee.getDescription()+",Condiment2";
    }
}
//---------------------------------------------------------------------------
public class Condiment3 extends CondimentDecorator {

    public Condiment3(Coffee coffee){
        m_Coffee = coffee;
    }

    public void finalize() throws Throwable {
        super.finalize();
    }

    public double cost(){
        return m_Coffee.cost()+0.5;
    }

    public String getDescription(){
        return m_Coffee.getDescription()+",Condiment3";
    }
}
CondimentDectorator具体类

五、总结

从这次学习中能看出一些OO原则:

  • 封装变化(Coffee封装了变化)
  • 多用组合,少用继承(继承可能会变得死板,组合达到扩展则很灵活)
  • 针对借口编程,不针对实现编程(抽象类)
  • 对扩展开放,对修改关闭
  • 依赖抽象

转载注明出处:http://www.cnblogs.com/xiemubg/p/6753811.html

网友评论
<