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私聊。
  • 相关阅读:
    CentOS7最小化安装后要做的事
    Django 2.0 新特性
    Django2.+ path配置
    Django 安装
    Django基础
    http协议
    Centos7 下mysql大小写敏感问题
    CentOS 设置mysql的远程访问
    Linux下彻底卸载mysql详解
    静态库和动态库
  • 原文地址:https://www.cnblogs.com/huipengbo/p/6881077.html
Copyright © 2011-2022 走看看