zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

    一.装饰者模式特点:
    1.装饰者和被装饰者对象有相同的超类
    2.可以用一个或多个装饰者包装一个对象
    3.由于装饰者和被装饰者具有相同超类,所以任何需要被包装对象的场合,可以用装饰过的对象代替
    4.装饰者可以再所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的(重点)
    5.对象可以在任何时候被装饰,所以可以在运行时动态的不限量的用你喜欢的装饰者来装饰对象
    二.装饰者模式定义:

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

    三.代码部分

    1.咖啡超类

     1 package com.pattern.decorate;
     2 /*
     3  * 咖啡超类
     4  */
     5 public abstract class Coffee {
     6     
     7     String des;//对咖啡的描述
     8 
     9     public String getDes() {
    10         return des;
    11     }
    12 
    13     public void setDes(String des) {
    14         this.des = des;
    15     }
    16     
    17     public abstract double cost();//不同的咖啡花费不同
    18     
    19 }

    2.咖啡实体类一意大利咖啡,被修饰者

     1 package com.pattern.decorate;
     2 /**
     3  * 意大利咖啡,被装饰者
     4  * @author Administrator
     5  *
     6  */
     7 public class ItalianCoffee extends Coffee {
     8 
     9     public ItalianCoffee() {
    10         des = "意大利咖啡";
    11     }
    12     
    13     @Override
    14     public double cost() {
    15         return 10.99;
    16 
    17     }
    18 
    19 }

    3.咖啡实体类2被装饰者

     1 package com.pattern.decorate;
     2 /**
     3  * 美式咖啡,被装饰者
     4  * @author Administrator
     5  *
     6  */
     7 public class CafeAmericano extends Coffee {
     8 
     9     public CafeAmericano() {
    10         des = "美式咖啡";
    11     }
    12     
    13     @Override
    14     public double cost() {
    15         // TODO Auto-generated method stub
    16         return 8.10;
    17     }
    18 
    19 }

    4.装饰者超类,调料

     1 package com.pattern.decorate;
     2 /**
     3  * 装饰者的超类,咖啡调料,也是咖啡一部分,所以继承Coffee
     4  * @author Administrator
     5  *
     6  */
     7 public abstract class CoffeeCondiment extends Coffee {
     8 
     9     
    10     
    11     @Override
    12     public abstract String getDes();//要知道调料加到什么咖啡中
    13     @Override
    14     public abstract double cost();//不同的调料价格不一样
    15 }

    5.装饰者实现类1巧克力

     1 package com.pattern.decorate;
     2 /**
     3  * 装饰者实现类,用来修饰Coffee对象
     4  * @author Administrator
     5  *
     6  */
     7 public class Chocolate extends CoffeeCondiment {
     8 
     9     Coffee coffee;//肯定会有这个引用表示调料要加到咖啡中
    10 
    11     public Chocolate(Coffee coffee) {
    12         this.coffee = coffee;
    13         this.des = "巧克力";
    14     }
    15 
    16     @Override
    17     public String getDes() {
    18         // TODO Auto-generated method stub
    19         return this.des+coffee.getDes();
    20     }
    21 
    22     @Override
    23     public double cost() {
    24         // TODO Auto-generated method stub
    25         return coffee.cost()+5.1;//加一种调料价钱加一点
    26     }
    27 
    28 }

    6.装饰者实现类2冰块

     1 package com.pattern.decorate;
     2 /**
     3  * 装饰者实现类,用来修饰Coffee对象,
     4  * @author Administrator
     5  *
     6  */
     7 public class Ice extends CoffeeCondiment {
     8 
     9     Coffee coffee;//肯定会有这个引用表示调料要加到咖啡中
    10 
    11     public Ice(Coffee coffee) {
    12         this.coffee = coffee;
    13         this.des = "冰块";
    14     }
    15 
    16     @Override
    17     public String getDes() {
    18         // TODO Auto-generated method stub
    19         return this.des+coffee.getDes();
    20     }
    21 
    22     @Override
    23     public double cost() {
    24         // TODO Auto-generated method stub
    25         return coffee.cost()+1.5;//加一种调料价钱加一点
    26     }
    27 
    28 }

    7.装饰者实现类3摩卡

     1 package com.pattern.decorate;
     2 /**
     3  * 装饰者实现类,用来修饰Coffee对象,
     4  * @author Administrator
     5  *
     6  */
     7 public class Mocha extends CoffeeCondiment {
     8 
     9     Coffee coffee;//肯定会有这个引用表示调料要加到咖啡中
    10 
    11     public Mocha(Coffee coffee) {
    12         this.coffee = coffee;
    13         this.des = "摩卡";
    14     }
    15 
    16     @Override
    17     public String getDes() {
    18         // TODO Auto-generated method stub
    19         return this.des+coffee.getDes();
    20     }
    21 
    22     @Override
    23     public double cost() {
    24         // TODO Auto-generated method stub
    25         return coffee.cost()+8.2;//加一种调料价钱加一点
    26     }
    27 
    28 }

    8.测试类

     1 package com.pattern.decorate;
     2 /**
     3  * 装饰者模式测试代码
     4  * @author Administrator
     5  *
     6  */
     7 public class Client {
     8 
     9     public static void main(String[] args) {
    10         //创建原始对象,意大利咖啡
    11         Coffee coffee1 = new ItalianCoffee();
    12         System.out.println("给我来一杯"+coffee1.getDes()+",价格:"+coffee1.cost());
    13         System.out.println("---------------------------------------------");
    14         Coffee coffee2 = new CafeAmericano();
    15         System.out.println("给我来一杯"+coffee2.getDes()+",价格:"+coffee2.cost());
    16         System.out.println("---------------------------------------------");
    17         //创建装饰者
    18         Coffee co = new  Chocolate(coffee1);//加入巧克力
    19         co = new Ice(co);//在加入冰块
    20         co = new Mocha(co);//再加入摩卡
    21         System.out.println("给我来一杯"+co.getDes()+",价格:"+co.cost());
    22         System.out.println("------------------------------------------------");
    23         Coffee cof = new Ice(coffee2);
    24         cof = new Mocha(cof);
    25         System.out.println("给我来一杯"+cof.getDes()+",价格:"+cof.cost());
    26         
    27         
    28         
    29     }
    30 
    31 }

    9.运行结果

    10.装饰者模式要点:

    @1继承属于扩展形式之一,但不是达到弹性设计的最佳方案

    @2在我们的设计中,应该允许行为可以被扩展,而无需修改现有的代码

    @3组合和委托可用于在运行时动态添加新的行为

    @4除了继承装饰者模式也可以让我们扩展行为

    @5装饰者模式意味着一群装饰者类,这些类用来包装具体的组件

    @6装饰这类反映出被装饰者的组件类型,事实上他们都具有相同的类型,都经过接口或者继承实现

    @7装饰者可以在被装饰者的行为前面与后面加上自己的行为,甚至被装饰者的整个行为替换掉而达到特定目的

    @8可以用许许多多装饰者包装一个组件

    @9装饰者一般对组件的客户是透明的,除非客户程序依赖于组建的具体类型

    @10装饰者会导致设计中出现许许多多的小对象,如果过度使用,会让程序变得很复杂

    需要程序源码的可以加我微信x241602私聊。
  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/huipengbo/p/6881077.html
Copyright © 2011-2022 走看看