[Java设计模式]装饰者模式入门Ⅰ

装饰者模式


为什么要使用装饰者模式

举个栗子:

老王是一个豆浆店的老板,因为豆浆品种多,生意火爆,我看着老王赚钱比较眼馋,晚上和他套近乎喝了点啤酒,老王就把配方分享给我了,具体配方如下:

[Java设计模式]装饰者模式入门Ⅰ_第1张图片

如果此时由于生意火爆,老王又加了一种辅料:西瓜

[Java设计模式]装饰者模式入门Ⅰ_第2张图片

类似于在开发中子类与父类的关系,子类功能比父类强大,但是由于子类数量增加,会形成类爆炸现象

如果实现子类继承父类,那么我们要写很多子类,这样做无疑增加了程序的臃肿性,并不是很灵活,这时,装饰者模式就可以帮助我们使得程序变得更简洁


装饰者的概念

装饰者模式又名包装模式,动态的给一个对象添加一些额外的职责,就扩展功能而言,它比生成子类的方式更加灵活

适用场景:

  • 以动态的方式给对象添加职责
  • 处理那些可以撤销的职责
  • 当采用生成子类的方法来进行扩充时,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数量呈现爆炸性增长

装饰者模式的结构

抽象组件(Component):给出一个抽象接口,以规范准备接受附加责任的对象

被装饰者(ConcreteComponent):Component的具体实现,也就是我们要装饰的具体的对象

装饰者组件(Decorator):持有组件(Component)对象的实例引用,该类的职责就是为了 装饰具体组件的对象,定义的基类

具体装饰(ConcreteDecorator):负责给构件对象装饰附加的功能

[Java设计模式]装饰者模式入门Ⅰ_第3张图片

迁移到豆浆案例则具体职责如下:

[Java设计模式]装饰者模式入门Ⅰ_第4张图片


一个小Demo

饮品接口(Component):

package cn.homyit.designpattern.decorator;

/**
 * Component
 * 抽象组件
 * 饮品接口
 */
public interface Drink {
     
    //价格
    double price();
    //品种描述
    String description();
}

饮品实现类豆浆(ConcreteComponent)

package cn.homyit.designpattern.decorator;

/**
 * ConcreteComponent
 * 被装饰者
 * 豆浆
 */
public class Soya implements Drink{
     

    @Override
    public double price() {
     
        return 5;
    }

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

装饰者(Decorator)

package cn.homyit.designpattern.decorator;

/**
 * Decorator
 * 装饰器组件
 * 1.抽象类
 * 2.实现抽象组件接口
 * 3.持有抽象接口的引用
 */
public abstract class Decorator implements Drink{
     

    //定义私有饮品引用
    private Drink drink;
    //通过构造来创建抽象接口的引用
    public Decorator(Drink drink){
     
        this.drink = drink;
    }

    @Override
    public double price() {
     
        return drink.price();
    }

    @Override
    public String description() {
     
        return drink.description();
    }
}

具体装饰即各种豆浆(ConcreteDecorator)

package cn.homyit.designpattern.decorator;

/**
 * ConcreteDecorator
 * 具体装饰
 * 红豆豆浆
 */
public class RedBeanSoya extends Decorator{
     

    public RedBeanSoya(Drink drink) {
     
        super(drink);
    }
    //重写价格

    @Override
    public double price() {
     
        return super.price()+3.2;
    }

    //重写描述
    @Override

    public String description() {
     
        return super.description()+"+红豆";
    }
}
package cn.homyit.designpattern.decorator;

/**
 * ConcreteDecorator
 * 具体装饰
 * 鸡蛋豆浆
 */
public class EggSoya extends Decorator{
     
    public EggSoya(Drink drink) {
     
        super(drink);
    }
    //重写价格

    @Override
    public double price() {
     
        return super.price()+3.9;
    }
    //重写描述

    @Override
    public String description() {
     
        return super.description()+"+鸡蛋";
    }
}
package cn.homyit.designpattern.decorator;

/**
 * ConcreteDecorator
 * 具体装饰
 * 糖豆浆
 */
public class SugarSoya extends Decorator{
     

    public SugarSoya(Drink drink) {
     
        super(drink);
    }
    //重写价格

    @Override
    public double price() {
     
        return super.price()+2.1;
    }

    //重写描述

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

测试类:

package cn.homyit.designpattern.decorator;

/**
 * 测试类
 */
public class Test {
     
    public static void main(String[] args) {
     
        //创建豆浆对象
        Drink soya = new Soya();
        System.out.println(soya.price());
        System.out.println(soya.description());
        System.out.println("----------------------");
        //创建红豆豆浆
        Drink redBean = new RedBeanSoya(soya);
        System.out.println(redBean.price());
        System.out.println(redBean.description());
        System.out.println("----------------------");
        //创建鸡蛋豆浆
        Drink egg = new EggSoya(soya);
        System.out.println(egg.price());
        System.out.println(egg.description());
        System.out.println("----------------------");
        //创建糖豆浆
        Drink sugar = new SugarSoya(soya);
        System.out.println(sugar.price());
        System.out.println(sugar.description());
        System.out.println("----------------------");
        //创建红豆鸡蛋豆浆
        Drink eggRedBean = new EggSoya(redBean);
        System.out.println(eggRedBean.price());
        System.out.println(eggRedBean.description());
        System.out.println("----------------------");
    }
}

打印结果如下:

5.0
纯豆浆
----------------------
8.2
纯豆浆+红豆
----------------------
8.9
纯豆浆+鸡蛋
----------------------
7.1
纯豆浆加糖
----------------------
12.1
纯豆浆+红豆+鸡蛋
----------------------

你可能感兴趣的:(设计模式,设计模式,接口,java,抽象类,多态)