装饰者模式

装饰者模式

定义:动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的代替方案。
装饰者模式遵循了OO设计原则:类应该对扩展开放,对修改关闭。

设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性。同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。如果扩展的功能有什么变动,我们就得修改源码。
这样也违反了 OO设计原则: 01.运行时扩展,远比编译时期的继承威力大。02.多用组合,少用继承。

下面这个例子帮助理解 装饰者模式的流程和作用:

现在我们需要出售一个汉堡并计算它的价格,它的价格主要是根据汉堡的价格+配料的价格。

注:代码未验证,如有bug自行修复,此处只是为了帮助理解装饰者模式。

汉堡基类 — 被装饰者

public abstract class Humburger {
    protected  String description;
    pubic String getDescription(){
        return description;
    }
    public abstract double cost();
}   

鸡腿堡 – 被装饰者的初始化状态,有些自己的特征(汉堡是基类,而顾客点餐会点具体种类的汉堡)

public class ChickenHuburger extends Humburger{
    public ChickenHuburger (){
        description= "鸡腿堡";
    }
    @override
    public double cost() {
        return 8;
    }
}

巨无霸堡

public class BigHumburger extends Humburger {
    public BigHumburger(){
        description = "巨无霸堡";
    }
    @override
    public double cost(){
        return 12;
    }
}

配料基类

public abstract class Condiment extends Humburger{
    public abstract String getDescription();
}

生菜(装饰者,用来对汉堡进行装饰) – 蔬菜可以对不同的多个种类的汉堡进行装饰

public class Lettuce extends Condiment{
    Humburger humburger;
    public Lettuce(Humburger humburger){    
        this.humburger = humburger;    
    }    
    @Override    
    public String getDescription() {    
        return humburger.getDescription()+" 加生菜";    
    }    

    @Override    
    public double cost() {    
        return humburger.cost()+1.5;    
    }    
}

酱料(装饰者)

public class Sauce  extends Condiment {
    Humburger humburger;
    public Sauce(Humburger humburger){    
        this.humburger = humburger;    
    }    
    @override
    public String getDescription(){
        return humburger.getDescription + " 加酱料";
    }
    @Override    
    public double cost() {    
        return humburger.cost()+2.0;    
    }  
}

测试类

public class Test {    

    public static void main(String[] args) {   
        //鸡腿堡 
        Humburger humburger = new ChickenBurger();    
        System.out.println(humburger.getDescription()+"  价钱:"+humburger.cost());  
        //巨无霸堡
        Humburger bigHumburger = new BigHumburger();
        System.out.println(bigHumburger .getDescription()+"  价钱:"+bigHumburger .cost());
        //鸡腿堡 + 生菜
        Lettuce lettuce = new Lettuce(humburger);    
        System.out.println(lettuce.getDescription()+"  价钱:"+lettuce.cost());   
        //鸡腿堡 + 酱料
        Sauce  sauce  = new Sauce  (humburger);    
        System.out.println(sauce.getDescription()+"  价钱:"+sauce.cost());   
        //鸡腿堡 + 生菜 + 酱料
        Sauce  sauce2 = new Sauce  (lettuce);    
        System.out.println(sauce2.getDescription()+"  价钱:"+sauce2.cost());  
        //巨无霸堡 + 生菜 + 酱料
        Sauce  sauce3 = new Sauce(new Lettuce(bigHumburger));
        System.out.println(sauce3.getDescription()+"  价钱:"+sauce3.cost());  
    }    
}    

输出:

鸡腿堡  价钱:8.0    
巨无霸堡 价格:12.0
鸡腿堡 加生菜  价钱:9.5    
鸡腿堡 加酱料  价钱:10.0    
鸡腿堡 加生菜 加酱料  价钱:11.5
巨无霸堡 加生菜 加酱料 价钱:15.5

重点总结

  1. 装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为。
  2. 你可以用一个或者多个装饰者包装一个对象。
  3. 因为装饰者和被装饰者对象有着相同的超类型,所以在任何需要原始对象(被包装)的场合,可以用装饰过的对象代替它。
  4. 对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用喜欢的装饰者来装饰对象。

缺点:使用装饰者模式。常常会造成设计中有大量的小类,会造成使用API程序员的困扰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值