裝飾者模式

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

clip_image002

圖片引用至博文「裝飾者模式java

要點:less

1.ConcreteComponent具體組件(基礎組件)和Decorator裝飾着組件都是Component子類或子接口,它們擁有相同的超類ide

2.裝飾着擁有具體組件的應用,能夠在調用具體組件的行爲以前或以後加上本身的行爲。測試

3.具體組件能夠被1到N個裝飾着對象裝飾this

4.對象能夠在任什麼時候候被裝飾,因此能夠在運行時動態地、不限量地用你喜歡的裝飾着來裝飾具體組件code

 

實現:htm

定義抽象類或者接口,由於場景須要有一個公共的屬性(食物的份數),因此把經常使用的接口改爲了抽象類,或者頂層保持接口,再新增一個抽象類對象

package com.jv.designpatterns.decorator;

public abstract class Food {

	int count = 1;
	
	public abstract Float cost();
	
	public abstract String desc();


	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}
	
	
	
}

定義重慶小面類blog

package com.jv.designpatterns.decorator;


//重慶小面
public class Noodle extends Food {

	private final static Float price_1 = 6F;
	private final static Float price_2 = 8F;
	private final static Float price_3 = 10F;
	
	Sizer s ;
	
	public Noodle() {}
	public Noodle(Sizer s) {
		this.s = s;
	}
	
	@Override
	public Float cost() {
		switch(s.getSize()) {
		case 1:
			return price_1*getCount();
		case 2:
			return price_2*getCount();
		case 3:
			return price_3*getCount();
		default:
			return price_2*getCount();
			
		}
	}	


	@Override
	public String desc() {
		
		return getCount()+"份"+s.getSize()+"兩重慶小面";
		
	}

}

定義小面的裝飾者抽象類 

package com.jv.designpatterns.decorator;

public abstract class FoodDecorator extends Food {
	
	Food f ;

	//子類必須實現cost方法
	public abstract Float cost();
	
	public abstract String desc();
	
}

定義牛肉臊子裝飾者 

package com.jv.designpatterns.decorator;

//牛肉
public class Beef extends FoodDecorator {
	
	private final static Float price = 4F;
	private final static String desc = "牛肉";
	
	public Beef() {}
	
	public Beef(Food f) {
		this.f=f;
	}

	@Override
	public Float cost() {
		return f.cost() + price*count;
	}

	@Override
	public String desc() {
		return f.desc()+"加"+count+"份"+desc;
	}

	
}

定義泡菜臊子裝飾者

package com.jv.designpatterns.decorator;

//泡菜
public class Pickle extends FoodDecorator {

	private final static Float price = 1F;
	private final static String desc = "泡菜";
	
	public Pickle() {}
	
	public Pickle(Food f) {
		this.f = f;
	}
	
	@Override
	public Float cost() {
		return f.cost() + price*count;
	}

	@Override
	public String desc() {
		return f.desc()+"加"+count+"份"+desc;
	}

}

定義小面特有尺寸類,使用組合的方式讓小面具有改變單分量的能力,而不須要使用繼承

package com.jv.designpatterns.decorator;

public class Sizer {
	private int size = 2;
	
	public Sizer() {}
	
	public Sizer(int size) {
		this.size = size;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}
	
}

測試類

package com.jv.designpatterns.decorator;

public class DecoratorTest {

	public static void main(String[] args) {
		Sizer s = new Sizer(3);
		Food f = new Noodle(s);
		
		f = new Beef(f);
		f.setCount(2);
		f = new Pickle(f);
		System.out.println(f.desc()+",總計:"+f.cost()+"元");
	}
}

輸出結果:

1份3兩重慶小面加2份牛肉加1份泡菜,總計:19.0元
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息