• 装饰者模式


    定义与特定

    装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

    装饰器模式主要包含以下角色。

    1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
    2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
    3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
    4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

    装饰者模式的主要优点有:

    • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
    • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
    • 装饰器模式完全遵守开闭原则

    其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

    UML图与代码

     

    public abstract class Drink {
    /**描述*/
      private String des;
      private float price = 0.0f;
    
      /**
       * 计算总价格
       * @return
       */
      public abstract float cost();
    public String getDes() { return des; } public void setDes(String des) { this.des = des; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } } public class Coffee extends Drink{ @Override public float cost() { return super.getPrice(); } }
    public class Espresso extends Coffee{
        public Espresso() {
            setDes("意大利咖啡");
            setPrice(6.0f);
        }
    
        @Override
        public String getDes() {
            return super.getDes()+" "+this.getPrice();
        }
    }
    public class Decorator extends Drink{

    private Drink drink;

    public Decorator(Drink drink) {
    this.drink = drink;
    }

    @Override
    public float cost() {
    //super.getPrice():修饰者价格,drink.cost()被修饰者价格
    return super.getPrice()+drink.cost();
    }

    @Override
    public String getDes() {
    return super.getDes()+" "+super.getPrice()+" "+drink.getDes();
    }
    }
    public class MilkDecorator extends Decorator{ 

    public MilkDecorator(Drink drink) {
      super(drink);
      setDes(
    "牛奶");
      setPrice(
    2.0f);
      }
    }

    public class ChocolateDecorator extends Decorator{

      public ChocolateDecorator(Drink drink) {

        super(drink);
        setDes(
    "巧克力");
      
        //巧克力价格
        setPrice(3.0f);
         }
      }

    public class Client {

      public static void main(String[] args) {

      //不加调味品
      
    Espresso espresso = new Espresso();
      System.out.println(espresso.getDes());

      //加牛奶的意大利咖啡
      MilkDecorator milkEspresso = new MilkDecorator(new Espresso());
      System.out.println(milkEspresso.getDes());

      //加牛奶,巧克力的意大利咖啡
      MilkDecorator milkChocolateEspresso = new MilkDecorator(new ChocolateDecorator(new Espresso()));
      System.out.println(milkChocolateEspresso.getDes());
      }
    }

    输出:

    意大利咖啡 6.0
    牛奶 2.0 意大利咖啡 6.0
    牛奶 2.0 巧克力 3.0 意大利咖啡 6.0

  • 相关阅读:
    Verilog语言
    OrCAD --从SNAPEDA导入封装库
    RAM/ROM IP一次性总结
    USB之Main item, Local item和Global item 的作用范围与归类
    发光LED压降与工作电流总结
    C之输入输出函数(3) -- 请使用sscanf()
    C之输入输出函数(2) -- gets()
    C之输入输出函数(1) -- fgets()
    C中的lvalue和rvalue
    关于字符串的一点补充
  • 原文地址:https://www.cnblogs.com/isalo/p/15420509.html
Copyright © 2020-2023  润新知