Java设计模式(3)-装饰者模式

一. 学习项目:咖啡馆订单系统

  咖啡馆订单:
  1)咖啡种类:Espresso,ShortBlack,LongBlack,Decaf
  2)调料:Milk,Soy,Chocolate
  3)扩展性好,改动方便,维护方便

1.一个差的解决方案:

       饮品超类:
      (1)<abstract>Drink
           description
           getDescription()
           cost()
           
       咖啡单品:
       (1) Decaf
           cost()
           
       (2) ShortBlack
           cost()              
      (3) LongBlack
            cost()
       (4) Espresso
            cost()
        
       添加调料咖啡:
       (1)Espresso && Milk
            cost()
            
       (3)Espresso  && Soy
            cost()
                 
       (3)Espresso && Milk && Soy
            cost()       
            
         ...   
         ...
   拓展性很差,到时可能遇见类爆炸。。。

2. 一个较好的设计方案

饮品超类:
    <abstract>Drink
        desciprtion
        milk
        soy
        chocolate
        
     getDescription()
     cost()
     hasMilk()
     setMilk()
     hasSoy()
     setSoy()
     hasChocolate()
     setChocolate()
 
  咖啡单品:
       (1) Decaf
           cost()
           
       (2) ShortBlack
           cost()              
      (3) LongBlack
            cost()
       (4) Espresso
            cost()
  
 存在一些问题:
   (1)增删调料种类
   (2)添加多份问题 

3.使用装饰者模式

 了解装饰者模式
 (1)装饰者模式就像打包的一个快递
      1)主体:陶瓷 ,衣服
      2)包装:报纸填充,塑料泡沫,纸盒,木盒
 (2)Component:
  
  (3)ConcreteComponent 和 Decorator        
  
  (4)装饰者模式:动态的将新的功能附加到对象上。在对象的扩展方面,它比继承更有弹性。

设计方案:

1.
<abstract>Drink
    description
    getDescription()
    cost()
  
2.
Decorator
   Drink obj
   getDescription()
   cost()
   ...

3.
    
     咖啡单品:
     (1) Decaf
         cost()
         
     (2) ShortBlack
         cost()              
    (3) LongBlack
          cost()
     (4) Espresso
          cost()
          
     调料单品:
     (1)Chocolate
           getDescription()
           cost()
     (2)Milk
           getDescription()
           cost()
     (3)Soy
           getDescription()
           cost()               
    

代码实现:

(1) Drink

package com.java.keen.coffeebar;
//饮品类:描述,价格
public abstract class Drink {
    public String description = "";
    private float price = 0f;
    
    public String getDescription() {
        return description+"  "+this.getPrice();
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    
    //花费是一个抽象方法,因为不知道顾客具体选喝啥
    public abstract float cost();
}

(2)Decorator

package com.java.keen.coffeebar.decorator;

import com.java.keen.coffeebar.Drink;

public class Decorator extends Drink{
   private Drink obj;
   public Decorator(Drink obj) {
       this.obj = obj;
   }
    @Override
    public float cost() {
        
        return super.getPrice() +obj.cost();
    }
   public String getDescription() {
       return super.description+"+"+super.getPrice()+"&&"+obj.getDescription();
   }
}

(3)Coffee

package com.java.keen.coffeebar.coffee;

import com.java.keen.coffeebar.Drink;

public class Coffee extends Drink {

    @Override
    public float cost() {
        
        return super.getPrice();
    }
    

}

(4)各种咖啡单品

//1.Decaf
package com.java.keen.coffeebar.coffee;

public class Decaf  extends Coffee{
    public Decaf() {
        super.setDescription("Decaf");
        super.setPrice(3.0f);
    }

}


//2.Espresso
package com.java.keen.coffeebar.coffee;

public class Espresso extends Coffee{
    public Espresso() {
        super.setDescription("Espresso");
        super.setPrice(4.0f);
    }

}

//3.LongBlack
package com.java.keen.coffeebar.coffee;

public class LongBlack  extends Coffee{
    public LongBlack() {
        super.setDescription("LongBlack");
        super.setPrice(5.0f);
    }

}

//4.ShortBlack 
package com.java.keen.coffeebar.coffee;

public class ShortBlack extends Coffee{
    public ShortBlack () {
        super.setDescription("ShortBlack ");
        super.setPrice(6.0f);
    }

}

(5)各种调料单品:

//1.Chocolate
package com.java.keen.coffeebar.decorator;

import com.java.keen.coffeebar.Drink;

public class Chocolate extends Decorator{

    public Chocolate(Drink obj) {
        super(obj);
        // TODO Auto-generated constructor stub
        super.setDescription("Chocolate");
        super.setPrice(3.0f);
    }

}


//2.Milk
package com.java.keen.coffeebar.decorator;

import com.java.keen.coffeebar.Drink;

public class Milk extends Decorator{

    public Milk(Drink obj) {
        super(obj);
        // TODO Auto-generated constructor stub
        super.setDescription("milk");
        super.setPrice(2.5f);
    }

}



//3.Soy
package com.java.keen.coffeebar.decorator;

import com.java.keen.coffeebar.Drink;

public class Soy extends Decorator{

    public Soy(Drink obj) {
        super(obj);
        // TODO Auto-generated constructor stub
        super.setDescription("soy");
        super.setPrice(1.5f);
    }

}

(6)测试类

package com.java.keen.coffeebar;

import com.java.keen.coffeebar.coffee.*;
import com.java.keen.coffeebar.decorator.*;

public class CoffeeBar {
    public static void main(String[] args) {
         Drink order;
         order = new Decaf();
         System.out.println("order1 price:  " +order.cost());
         System.out.println("order1 desc :  "+order.getDescription());
    
         System.out.println("***************");
         order = new LongBlack();
         order = new Milk(order);
         order =new Chocolate(order);
         order =new Chocolate(order);
         System.out.println("order2 price:  " +order.cost());
         System.out.println("order2 desc :  "+order.getDescription());
    
    
    }
}

output:

order1 price:  3.0
order1 desc :  Decaf  3.0
***************
order2 price:  13.5
order2 desc :  Chocolate+3.0&&Chocolate+3.0&&milk+2.5&&LongBlack  5.0

个人在极客学院的学习的笔记

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容