簡單工廠和工廠方法模式

一.前言java

 1.準備好開始烘烤某些鬆耦合OO設計編程

 2.製造對象的方法除了new,還有不少其餘的方法;設計模式

 3.初始化使用new常常會帶來一些耦合的問題,工廠模式能夠解決這個問題;框架

   那麼「new」有什麼不對勁呢?
ide

  其實,new沒有問題,有問題的是「改變」。則能夠用設計原則「找出會變化的部分,把他們從不變的部分分離出來」測試

 (即:將實例化具體類的方法抽離,或者封裝起來,使他們不會干擾其餘部分。)ui

 4.重要原則--「針對接口編程」。spa

 5.全部工廠模式都是用來封裝對象的建立。設計

二.披薩店實例--簡單工廠對象

 1.pizza店有許多pizza類型,每種pizza從order開始的流程都要通過準備prepare、烘烤bake、切片cut和裝箱box,因此一般對於OO設計者們,初步能夠考慮到這樣的設計:

wKioL1cPBd3TvXEFAABS7rX5jZ4174.png

public class MainTest {
	public static void main(String[] args) {
		IPizza pizza = orderPizza(null);
		if(pizza != null){
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
		}
	}
	
	private static IPizza orderPizza(String type){
		if(type == null){
			System.out.println("What kind of pizza do you want?");
			return null;
		}
		IPizza pizza = null;
		if(type.equals("cheese")){
			pizza = new PizzaCheese();
		}else if(type.equals("fruit")){
			pizza = new PizzaFruit();
		}else if(type.equals("banana")){
			pizza = new PizzaBanana();
		}
		return pizza;
	}
}
public interface IPizza {

	/**準備*/
	public void prepare();
	/**烘烤*/
	public void bake();
	/**切片*/
	public void cut();
	/**裝盒*/
	public void box();
}
public class PizzaCheese implements IPizza{

	public void prepare() {
		System.out.println("PizzaCheese prepare");
	}

	public void bake() {
		System.out.println("PizzaCheese bake");
	}

	public void cut() {
		System.out.println("PizzaCheese cut");
	}

	public void box() {
		System.out.println("PizzaCheese box");
	}

}

 2.上述中存在一個問題:增長新類型pizza或去除一種賣的很差的pizza,上述建立pizza對象的部分就要一改再改,這裏就是變化的部分,咱們要作的,就是分離變化的部分----該使用封裝了。

   封裝建立對象的代碼

  (1)將建立對象的代碼移到另外一個對象中,這個對象的專職就是建立pizza對象;

  (2)稱這個專職對象爲「工廠」SimplePizzaFactory;

  (3)此時,orderPizza()就再也不須要知道什麼類型的pizza,只管獲得一個pizza。

wKiom1cPD2OiD3e0AABaICBLPbA835.png

    

//測試類
public class MainTest {
	public static void main(String[] args) {

		//利用工廠建立pizza
		IPizza pizza = new PizzaShop().orderPizza("banana");

		if(pizza != null){
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
		}
	}
}
//客戶預訂披薩
class PizzaShop{
	public IPizza orderPizza(String type){
		//利用工廠建立pizza
		IPizza pizza = SimplePizzaFactory.createPizza(type);
		return pizza;
	}

}
public class SimplePizzaFactory {
	/**
	 * 把原來的建立代碼直接移動過來
	 * @param type
	 * @return
	 */
	public static IPizza createPizza(String type){
		if(type == null){
			System.out.println("What kind of pizza do you want?");
			return null;
		}
		IPizza pizza = null;
		if(type.equals("cheese")){
			pizza = new PizzaCheese();
		}else if(type.equals("fruit")){
			pizza = new PizzaFruit();
		}else if(type.equals("banana")){
			pizza = new PizzaBanana();
		}
		return pizza;
	}
}

 其餘部分不變,此後:

  當有不少不少「客戶」時,他們都利用該「工廠」建立指定類型的pizza,若是pizza自己種類等發生任何改變,每一個「客戶」都不用修改代碼,只需「工   廠」修改便可


 3.以上就是「簡單工廠」:

   簡單工廠其實並非一個設計模式,而是一種編程習慣;

   簡單工廠經常使用爲static,但有時也有缺點,不能利用繼承待改變建立方法的行爲。


三.披薩店實例--工廠方法

 1.現有不一樣區域的披薩店想要作不一樣口味的披薩。就不能用簡單工廠了。能夠考慮將建立對象的功能移到pizzashop的一個抽象方法中,由pizzashop的子類作決定建立具體的對象

wKiom1cPJTKyh4eTAABNiaBEQAY422.png

public abstract class PizzaShop {
	// final的修飾不是必要的,不過這樣能夠防止子類覆蓋
	public final IPizza orderPizza(String type){
		
		// createPizza()移回PizzaShop中
		IPizza pizza = createPizza(type);
		
		if(pizza != null){
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
		}
		return pizza;
	}
	// 抽象的「工廠方法」
	protected abstract IPizza createPizza(String type);
}
// 每一個子類都要繼承PizzaShop
public class BeijingPizzaShop extends PizzaShop{
	// 實現抽象的「工廠方法」
	protected IPizza createPizza(String type) {
		if(type == null){
			System.out.println("BeijingPizzaShop:What kind of pizza do you want?");
			return null;
		}
		IPizza pizza = null;
		if(type.equals("cheese")){
			pizza = new BeijingPizzaCheese();
		}else if(type.equals("fruit")){
			pizza = new BeijingPizzaFruit();
		}else if(type.equals("banana")){
			pizza = new BeijingPizzaBanana();
		}
		return pizza;
	}

}
public class ShenZhenPizzaShop extends PizzaShop{

	protected IPizza createPizza(String type) {
		if(type == null){
			System.out.println("ShenZhenPizzaShop kind of pizza do you want?");
			return null;
		}
		IPizza pizza = null;
		if(type.equals("cheese")){
			pizza = new ShenZhenPizzaCheese();
		}else if(type.equals("fruit")){
			pizza = new ShenZhenPizzaFruit();
		}else if(type.equals("banana")){
			pizza = new ShenZhenPizzaBanana();
		}
		return pizza;
	}

}

  2.進一步說明:

  (1)作到了解耦--orderPizza()是在PizzaShop中定義的,可是他在使用createPizza()建立的pizza對象類執行prepare、bake、cut、box方法時並不知道具體的pizza對象是哪一種類型。

  (2)pizza對象的具體類型僅由具體的pizza店(顧客)決定。

  3.有關工廠方法

  (1)簡單工廠是有一個專職對象負責全部具體類的實例化,而工廠方法則是由一羣子類來負責實例化;

  (2)將一個orderpizza方法和一個工廠方法聯合起來,能夠成爲一個框架;

  (3)工廠方法將生產知識封裝進各個建立者,這種作法也可視爲一個框架;

  4.定義工廠方法模式

  (1)工廠方法模式定義了一個建立對象的接口,但由子類決定要實例化的類是哪個。工廠方法讓類把實例化推遲到子類。

相關文章
相關標籤/搜索