给爱用继承的人一个全新的设计眼界-----装饰者模式(java I/O的源码思想就是基于这个来的)

导读:如果感觉有点困难,请看后面的例子和最后一句话

开始的思维:

这是一个父类,假设是某种产品的总称,比如:饮料(beverage):

public class Beverage {
   private String description;//产品的描述
   public String getDescription(){//返回产品的描述
       return this.description;
   }
   public String cost(){ //由子类继承来返回当前产品的价格
       return "no chird";
   }
   
}

如果有很多产品,那么就需要建立很多的子类,导致维护的时候就会变得非常麻烦。(子类继承cost() 只重写方法,返回对应的价格。 )

 

设计原则:类应该对扩展开发,对修改关闭。

我们的目标是允许类容易扩展,在不修改现有的代码的情况下,就可以搭配新的行为,如能实现这样的目标,有什么好处呢?这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的 需求。

 

正文开始:

要做到:

1.拿一个对象,比如DarkRoast(**咖啡)

2.以摩卡(Mocha)对象装饰它

3.对奶泡(Whip)对象装饰它

4.调用cost()方法,并依赖委托(delegate) 将调料的价格加上去

 

所谓装饰者就是分为两类,一类是装饰的对象,另一类是被装饰的对象。就像红豆牛奶,红豆是修饰者,牛奶是被修饰者,

在饮品店里,你可以单买牛奶,但是不可以单买红豆(配料)[不要钻牛角尖,认真你就输了.....] 所以我们在写程序的时候就需要实现两个类型的类。

那么现在是被装饰对象的主类,他是一个抽象对象(接口也可以,随你开心)

public abstract class Beverage {

    String description = "Unknown Beverage";

    public String getDescription() {
        return this.description;
    }

    public abstract Double cost();

}

它是所有的超类,主要的作用是把后面的子类的形态定住。

 

接下来是装饰者的抽象类

//首先,必须让Condiment Decorator 能够取代Beverage,所以将CondimentDecorator扩展自Beverage类
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();//所有的被装饰者都必须重新实现getDescription()方法。
}

让其作为上面超类的子类,也是为了把形态固定住,重命名肯定是必须的。

 

接下来是实现多个装饰对象

//摩卡(配料)
public class Mocha extends CondimentDecorator {
    Beverage beverage;

    //把饮料(主体传入)
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    @Override
    public Double cost() {
        return .20 + beverage.cost(); //组合价格
    }
}
public class Whip extends CondimentDecorator{

    Beverage beverage;

    //把饮料(主体传入)
    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }

    @Override
    public Double cost() {
        return .30 + beverage.cost(); //组合价格
    }
}

接下来是被装饰者

//浓缩咖啡
public class Espresso extends Beverage{
    public Espresso(){
        description = "Espresso";
    }
    @Override
    public Double cost() {
        return 1.99;
    }
}
//另一种
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "House Blend";
    }

    @Override
    public Double cost() {
        return .89;
    }
}

接下来是测试类:

public class StarbuzzCoffee {
    public static void main(String args[]) {
        Beverage beverage = new Espresso();
        //订一杯Espresso 不加调理 打印价格
        System.out.println(beverage.getDescription()
                + " $" + beverage.cost());

        Beverage beverage1 = new HouseBlend();
        beverage1 = new Mocha(beverage1);
        beverage1 = new Mocha(beverage1);//加入第二份
        beverage1 = new Whip(beverage1);
        System.out.println(beverage1.getDescription()
                + " $" + beverage1.cost());
    }
}

很显然,被装饰者类并不需要做太多的事,而装饰者类则需要在被装饰者的基础上增加加上自己后对应的变化操作,所有装饰者模式就是利用多重组合来实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值