Java复习之装饰者设计模式

这篇博客主要是总结一下Java中的装饰者设计模式。

1.继承带来的问题

举一个生活中常见的例子来说明继承带来的问题。豆浆,大家一定不陌生。有纯豆浆,加糖豆浆,黑豆豆浆,红枣豆浆,绿豆豆浆等等,如果我们要写一个程序来计算每种豆浆的价格以及说明这种豆浆的配料,如果按照之前的学习的,我们将会继承一个豆浆类,然后在其之上,重写自己的方法,但是对于豆浆来说,种类实在太多了,我们就要写很多很多的子类,这样的话便会引起类爆炸,于是,便产生的装饰者这种设计模式。

2.装饰者模式概述
涉及角色:
抽象构件角色:定义一个抽象接口,来规范准备附加功能的类
具体构件角色:将要被附加功能的类,实现抽象构件角色接口
抽象装饰者角色:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
具体装饰角色:实现抽象装饰者角色,负责为具体构件添加额外功能

3.装饰者模式实现
我们就以豆浆的例子为例,来实现一下装饰者模式

抽象构件角色,来规范准备附加功能的类

/**
 * 被装饰者对象的接口
 */
public interface Drink {
    //饮料的描述信息
    public String description();
    //计算价格
    public float cost();
}

具体的构建角色,将要被附加功能的类

**
 * 具体的被装饰者的对象
 */
public class SoyaBeanMilk implements Drink{

    @Override
    public String description() {
        return "纯豆浆";
    }

    @Override
    public float cost() {
        return 5f;
    }
}

抽象装饰者角色:持有对具体构件角色的引用并定义与抽象构件角色一致的接口

/**
 * 装饰者基类
 */
public abstract class Decorator implements Drink{
    //要装饰的对象
    private Drink drink;//关联Drink

    //使用构造方法初始化关联的类对象,很经典
    public Decorator(Drink drink)
    {
        this.drink=drink;
    }

    @Override
    public String description() {
        return drink.description();
    }
    @Override
    public float cost() {
        return drink.cost();
    }
}
**
 *具体的装饰者对象:糖
 */
public class SugarDecorator extends Decorator{
    public SugarDecorator(Drink drink)
    {
        super(drink);
    }

    @Override
    public String description() {
        return super.description()+"+糖";
    }

    @Override
    public float cost() {
        return super.cost()+0.5f;
    }
}
/**
 * 具体的装饰者对象--黑豆
 */
public class BlackBeanDecorator extends Decorator {
    public BlackBeanDecorator(Drink drink)
    {
        super(drink);
    }

    @Override
    public String description() {
        return super.description()+"+黑豆";
    }

    @Override
    public float cost() {
        return super.cost()+3.0f;
    }
}
/**
 * 具体的装饰者对象:鸡蛋
 */
public class EggDecorator extends Decorator {
public EggDecorator(Drink drink)
{
    super(drink);
}

    @Override
    public String description() {
        return super.description()+"+鸡蛋";
    }

    @Override
    public float cost() {
        return super.cost()+2.0f;
    }
}
/**
*测试类
*/
public class Test {
    public static void main(String args[])
    {
        //生产一杯豆浆
        Drink soya = new SoyaBeanMilk();
        //在豆浆中加鸡蛋
        EggDecorator eggsoya=new EggDecorator(soya);
        //在鸡蛋豆浆中加糖
        SugarDecorator sugarEggSoya=new SugarDecorator(eggsoya);
        //在加了糖的豆浆中加黑豆
        BlackBeanDecorator blackBeanSugarEggSoya=new BlackBeanDecorator(sugarEggSoya);
        //结账
        System.out.println("同志,您点的是:"+blackBeanSugarEggSoya.description());
        System.out.println("您一共消费了"+blackBeanSugarEggSoya.cost());
    }
}

4.装饰者模式小结
OO原则:动态地将责任附加对象上。
想要拓展功能,装饰者提供有别于继承的另一种选择

要点:
(1)继承属于拓展形式之一,但不见得是达到弹性设计的最佳方法
(2)在我们的设计中,应该允许行为可以被拓展,而不须修改现有的代码
(3)组合和委托可用于在运行时动态地加上新行为
(4)除了继承,装饰者模式也可以让我们拓展行为
(5)装饰者模式意味着一群装饰者类,这些类用来包装具体组件
(6)装饰者类反应出被装饰的组件的类型(实际上,他们具有相同的类型,都经过接口或者继承实现)
(7)装饰者可以在被装饰者的行为前面或者后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而得到特定的目的
(8)你可以有无数个装饰者包装的一个组件
(9)装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值