Java設計模式(三)-修飾模式

咱們都知道。可以使用兩種方式給一個類或者對象加入行爲。java

        一是使用繼承。繼承是給一個類加入行爲的比較有效的途徑。經過使用繼承,可以使得子類在擁有自身方法的同一時候,還可以擁有父類的方法。但是使用繼承是靜態的,在編譯的時候就已經決定了子類的行爲,咱們不便於控制添加行爲的方式和時機。ide

        二是使用關聯。組合即將一個對象嵌入到還有一個對象中,由還有一個對象來決定是否引用該對象來擴展本身的行爲。this

這是一種動態的方式,咱們可以在應用程序中動態的控制。spa

        與繼承相比,關聯關係的優點就在於不會破壞類的封裝性,且具備較好的鬆耦合性,可以使系統更加easy維護。但是它的缺點就在於要建立比繼承不少其它的對象設計

1、裝飾者的定義:code

    裝飾着模式動態的將責任附加到對象上,若想要擴展功能,裝飾着提供比繼承更有彈性的替代方案。對象

2、裝飾着模式的UML圖:繼承

     Compoent類:抽象類,每個組件可以單獨使用它。或者包裝起來使用接口

     ConcreteCompoent類:動態載入新行爲的對象。繼承於Compoentip

     Decorator類:裝飾着共同實現的接口,可以使抽象類

     ConcreteDecorator一、ConcreteDecorator2類:裝飾實例,裝飾者包着Compent


3、應用場景:

   Startbuzz是以擴張速度最快的的咖啡連鎖店。因爲擴張太快。他們準備更新訂單系統。以供應需求。他們原先的設計是這種。  

     購買咖啡時,可以要求在當中增長各類調料。好比:牛奶(Milk)、豆漿(Soy)、摩卡(Mocha)。Startbuzz會依據不一樣的調料收取不一樣的費用,因此訂單必須考慮到調料部分。。

這是他們的第一次嘗試。。。


解決方式:


4、編寫代碼

Compotemt:Beverage類

	//@file:beverage.java
	public abstract class Beverage {	
		String description = "Unknown Beverage";
		public String getDescription(){
			return description;
		}	
		public abstract double cost();
	}

ConcreteCompotemt:Espresso類

	//濃縮咖啡
	//@file:Espresso.java
	public class Espresso extends Beverage {
	<span style="white-space:pre">	</span>public Espresso(){
			description = "Espresso";
		}
		@Override
		public double cost() {
			return 1;
		}
	}
CondimentDecorator HouseBlend

	//@file:HouseBlend.java  、
	//深烤烘焙
	public class HouseBlend extends Beverage {
		public HouseBlend(){
			description = "HouseBlend";
		}
		@Override
		public double cost() {
			return 0.5;
		}
	}
DecoratorCondimentDecorator
        //@file:CondimentDecorator.java
	public abstract class CondimentDecorator extends Beverage{
		abstract public String getDescription();
	}

ConcreteDecoratorMilk

	//file:Milk.java  牛奶味道的調料
	public class Milk extends CondimentDecorator {
	
		Beverage beverage;
		public Milk(Beverage beverage){
			this.beverage = beverage;
		}
		@Override
		public String getDescription() {
			return beverage.getDescription()+"-Milk";
		}
		@Override
		public double cost() {
			return beverage.cost()+2.0;
		}
	}

ConcreteDecorator:Mocha

//摩卡味道的調料
	public class Mocha extends CondimentDecorator {
		Beverage beverage;
		public Mocha(Beverage beverage){
			this.beverage = beverage;
		}
		@Override
		public String getDescription() {
			return beverage.getDescription()+"-Mocha";
		}
		@Override
		public double cost() {
			return beverage.cost()+3.0;
		}
	}

ConcreteCDecoratorSoy

	//豆漿味道的調料
	public class Soy extends CondimentDecorator {
		Beverage beverage;
		public Soy(Beverage beverage){
			this.beverage = beverage;
		}
		@Override
		public String getDescription() {
			return beverage.getDescription()+"-Soy";
		}
		@Override
		public double cost() {
			return beverage.cost()+4.0;
		}
	}

開始下單啦!!!

public class OrderApp {
	public static void main(String[] args) {
		Beverage  beverage1 = new HouseBlend();
		beverage1 = new Milk(beverage1);
		beverage1 = new Mocha(beverage1);
		beverage1 = new Soy(beverage1);
		System.out.println("beverage1 description:"+beverage1.getDescription()+"\ncost:"+beverage1.cost());
		
		Beverage  beverage2 = new Espresso();
		beverage2= new Milk(beverage2);
		beverage2 = new Mocha(beverage2);
		System.out.println("beverage2 description:"+beverage2.getDescription()+"\ncost:"+beverage2.cost());
	}
}

output:

beverage1 description:HouseBlend-Milk-Mocha-Soy cost:9.5 beverage2 description:Espresso-Milk-Mocha cost:6.0

相關文章
相關標籤/搜索