设计模式——装饰者模式

Posted studentytj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——装饰者模式相关的知识,希望对你有一定的参考价值。

装饰者模式

1. 定义

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

2. 类图

技术图片

3. Example

假如有这样一个需求:有一天,奶茶店的老板喊你给他们做一个简单版的计算价格程序。新店开张,供应的饮料有奶茶(8元)、红茶(7元)、绿茶(5元)三种,提供的配料有波霸1元,布丁5元,红豆3元。

则可如下设计:

Component及其实现如下:

package com.gitlearning.hanldegit.patterns.decorator;

/**
 * 相当于Component
 */
public abstract class Beverage 
    String description = "Unkown beverage";

    public String getDescription() 
        return description;
    

    public abstract double cost();



class MilkTea extends Beverage 
    @Override
    public String getDescription() 
        return "奶茶";
    

    @Override
    public double cost() 
        return 8.00;
    


class RedTea extends Beverage 
    @Override
    public String getDescription() 
        return "红茶";
    

    @Override
    public double cost() 
        return 7.00;
    


class GreenTea extends Beverage 
    @Override
    public String getDescription() 
        return "绿茶";
    

    @Override
    public double cost() 
        return 5.00;
    

Decorator及其实现如下:

package com.gitlearning.hanldegit.patterns.decorator;

public abstract class CondimentDecorator extends Beverage 
    @Override
    public abstract String getDescription();




class RedBean extends CondimentDecorator 

    Beverage beverage;

    public RedBean(Beverage beverage) 
        this.beverage = beverage;
    

    @Override
    public String getDescription() 
        return beverage.getDescription() + "添加红豆";
    

    @Override
    public double cost() 
        return beverage.cost() + 3.00;
    


class Pudding extends CondimentDecorator 
    Beverage beverage;

    public Pudding(Beverage beverage) 
        this.beverage = beverage;
    

    @Override
    public String getDescription() 
        return beverage.getDescription() + "添加布丁";
    

    @Override
    public double cost() 
        return beverage.cost() + 5.00;
    


class Boba extends CondimentDecorator 
    Beverage beverage;

    public Boba(Beverage beverage) 
        this.beverage = beverage;
    

    @Override
    public String getDescription() 
        return beverage.getDescription() + "添加波霸";
    

    @Override
    public double cost() 
        return beverage.cost() + 1.00;
    

测试代码如下:

package com.gitlearning.hanldegit.patterns.decorator;

import org.junit.jupiter.api.Test;

public class DecoratorTest 
    @Test
    void test() 
        // 来一杯加波霸和布丁的奶茶
        Beverage milkTea = new MilkTea();
        milkTea = new Pudding(milkTea);
        milkTea = new Boba(milkTea);
        System.err.println(milkTea.getDescription() + "¥"+ milkTea.cost());

        // 来一杯加红豆的绿茶
        Beverage greenTea = new GreenTea();
        greenTea = new RedBean(greenTea);
        System.err.println(greenTea.getDescription() + "¥"+ greenTea.cost());

        // 来一杯加红豆、布丁、波霸的红茶
        Beverage redTea = new RedTea();
        redTea = new Pudding(redTea);
        redTea = new Boba(redTea);
        redTea = new RedBean(redTea);
        System.err.println(redTea.getDescription() + "¥"+ redTea.cost());
    

发现输出为:

奶茶添加布丁添加波霸¥14.0
绿茶添加红豆¥8.0
红茶添加布丁添加波霸添加红豆¥16.0

4. 使用

1. Java I/O

InputStream作为抽象Component,
技术图片

Component,像BufferedInputStream装饰了FileInputStream,增加了readLine()和缓冲输入,LineNumberInputStream()则增加了计算行数的能力。

2. Mybatis

技术图片

5.其他

  1. 装饰者会导致类中出现许多的小对象,如果过度使用,会让程序变得复杂。
  2. 装饰者可以在被装饰者的行为前面或者后面加上自己的行为。
  3. 可以用无数个装饰者包装一个组件。

以上是关于设计模式——装饰者模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式装饰者模式

装饰者模式

设计模式学习_装饰者模式

设计模式 - 装饰者模式详解

设计模式整理_装饰者模式

设计模式---装饰者模式