1. 程式人生 > >Java設計模式(四):工廠設計模式

Java設計模式(四):工廠設計模式

1. 工廠設計模式

1.1 應用場景

由於需求的變化,一個類的子類經常面臨著劇烈的變化,但他卻擁有比較穩定的介面。使用一種封裝機制來“隔離這種易變物件的變化”,工廠方法定義一個用於建立物件的介面,讓子類來確定建立哪一個具體類的物件,將物件的例項化延遲。

1.2 概念

定義了一個建立物件的介面,但由子類決定要例項化哪個類。工廠方法把例項化操作推遲到子類。

1.3 Class Diagram

在簡單工廠中,建立物件的是另一個類,而在工廠方法中,是由子類來建立物件。

下圖中,Factory 有一個 doSomething() 方法,這個方法需要用到一個產品物件,這個產品物件由 factoryMethod() 方法建立,也稱為“工廠方法”。該方法是抽象的,需要由子類去實現。在抽象的Factory中,任何其他實現的方法,都可能使用到這個工廠方法所製造出來的產品,但只有子類真正實現了這個工廠方法並建立產品。

在這裡插入圖片描述

1.4 Implementation

public abstract class Pizza {
	String name;
	String dough;
	String sauce;
	ArrayList<String> toppings = new ArrayList<String>();
 
	void prepare() {
		System.out.println("Prepare " + name);
		System.out.println("Tossing dough...");
		System.out.println("Adding sauce..."
); System.out.println("Adding toppings: "); for (String topping : toppings) { System.out.println(" " + topping); } } void bake() { System.out.println("Bake for 25 minutes at 350"); } void cut() { System.out.println("Cut the pizza into diagonal slices"); } void box() { System.
out.println("Place pizza in official PizzaStore box"); } public String getName() { return name; } public String toString() { StringBuffer display = new StringBuffer(); display.append("---- " + name + " ----\n"); display.append(dough + "\n"); display.append(sauce + "\n"); for (String topping : toppings) { display.append(topping + "\n"); } return display.toString(); } } public abstract class PizzaStore { public Pizza orderPizza(String type){ Pizza pizza; pizza=createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } public abstract Pizza createPizza(String type); } public class NYStyleCheesePizza extends Pizza { public NYStyleCheesePizza() { name = "NY Style Sauce and Cheese Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce"; toppings.add("Grated Reggiano Cheese"); } } public class ChicagoStyleCheesePizza extends Pizza { public ChicagoStyleCheesePizza() { name = "Chicago Style Deep Dish Cheese Pizza"; dough = "Extra Thick Crust Dough"; sauce = "Plum Tomato Sauce"; toppings.add("Shredded Mozzarella Cheese"); } void cut() { System.out.println("Cutting the pizza into square slices"); } } public class ChicagoStylePizzaStore extends PizzaStore{ @Override public Pizza createPizza(String type) { if(type.equals("cheese")) return new ChicagoStyleCheesePizza(); return null; } } public class NYStylePizzaStore extends PizzaStore{ @Override public Pizza createPizza(String type) { if(type.equals("cheese")) return new NYStyleCheesePizza(); return null; } } public class PizzaTestDrive { public static void main(String[] args) { PizzaStore nyStylePizzaStore=new NYStylePizzaStore(); PizzaStore chicagoStylePizzaStore=new ChicagoStylePizzaStore(); Pizza nyStylePizza = nyStylePizzaStore.orderPizza("cheese"); System.out.println("Ethan ordered a " + nyStylePizza.getName() + "\n"); Pizza chicagoPizza = chicagoStylePizzaStore.orderPizza("cheese"); System.out.println("Ethan ordered a " + chicagoPizza.getName() + "\n"); } }

1.5 JDK

2. 抽象工廠方法

2.1 應用場景

一系列相互依賴的物件有不同的具體實現。提供一種“封裝機制”來避免客戶程式和這種“多系列具體物件建立工作”的緊耦合。

2.2 概念

提供一個介面,用於建立 相關的物件家族,而不需要明確的指定具體類。抽象工廠允許客戶使用抽象的介面來建立一組相關的產品,而不需要知道或者關心實際產出的產品是什麼。這樣一來客戶就從具體的產品中被解耦。

2.3 Class Diagram

抽象工廠模式建立的是物件家族,也就是很多物件而不是一個物件,並且這些物件是相關的,也就是說必須一起創建出來。而工廠方法模式只是用於建立一個物件,這和抽象工廠模式有很大不同。

抽象工廠模式用到了工廠方法模式來建立單一物件,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是讓子類來實現,這兩個方法單獨來看就是在建立一個物件,這符合工廠方法模式的定義。

至於建立物件的家族這一概念是在 Client 體現,Client 要通過 AbstractFactory 同時呼叫兩個方法來創建出兩個物件,在這裡這兩個物件就有很大的相關性,Client 需要同時創建出這兩個物件。

從高層次來看,抽象工廠使用了組合,即 Cilent 組合了 AbstractFactory,而工廠方法模式使用了繼承。

在這裡插入圖片描述

2.4 Implementation

public interface Cheese {
	public String toString();
}

public interface Clams {
	public String toString();
}

public interface Dough {
	public String toString();
}

public class FreshClams implements Clams {

	public String toString() {
		return "Fresh Clams from Long Island Sound";
	}
}

public class Garlic implements Veggies {

	public String toString() {
		return "Garlic";
	}
}

public class MarinaraSauce implements Sauce {
	public String toString() {
		return "Marinara Sauce";
	}
}

public class Mushroom implements Veggies {

	public String toString() {
		return "Mushrooms";
	}
}

public class Onion implements Veggies {

	public String toString() {
		return "Onion";
	}
}

public interface Pepperoni {
	public String toString();
}

public class RedPepper implements Veggies {

	public String toString() {
		return "Red Pepper";
	}
}

public class ReggianoCheese implements Cheese {

	public String toString() {
		return "Reggiano Cheese";
	}
}

public interface Sauce {
	public String toString();
}

public class SlicedPepperoni implements Pepperoni {

	public String toString() {
		return "Sliced Pepperoni";
	}
}

public class ThinCrustDough implements Dough {
	public String toString() {
		return "Thin Crust Dough";
	}
}

public interface Veggies {
	public String toString();
}

public interface PizzaIngredientFactory {
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clams createClams();
}

public abstract class Pizza {
	public String name;

	public Dough dough;
	public Sauce sauce;
	public Veggies veggies[];
	public Cheese cheese;
	public Pepperoni pepperoni;
	public Clams clam;

	public abstract void prepare();

	public void bake() {
		System.out.println("Bake for 25 minutes at 350");
	}

	public void cut() {
		System.out.println("Cutting the pizza into diagonal slices");
	}

	public void box() {
		System.out.println("Place pizza in official PizzaStore box");
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("---- " + name + " ----\n");
		if (dough != null) {
			result.append(dough);
			result.append("\n");
		}
		if (sauce != null) {
			result.append(sauce);
			result.append("\n");
		}
		if (cheese != null) {
			result.append(cheese);
			result.append("\n");
		}
		if (veggies != null) {
			for (int i = 0; i < veggies.length; i++) {
				result.append(veggies[i]);
				if (i < veggies.length-1) {
					result.append(", ");
				}
			}
			result.append("\n");
		}
		if (clam != null) {
			result.append(clam);
			result.append("\n");
		}
		if (pepperoni != null) {
			result.append(pepperoni);
			result.append("\n");
		}
		return result.toString();
	}
}

public class CheesePizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
 
	public CheesePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
 
	public void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
	}
}

public class ClamPizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
 
	public ClamPizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
 
	public void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
		clam = ingredientFactory.createClams();
	}
}

public class PepperoniPizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
 
	public PepperoniPizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
 
	public void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
		veggies = ingredientFactory.createVeggies();
		pepperoni = ingredientFactory.createPepperoni();
	}
}

public class VeggiePizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
 
	public VeggiePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
 
	public void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
		veggies = ingredientFactory.createVeggies();
	}
}

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
 
	public Dough createDough() {
		return new ThinCrustDough();
	}
 
	public Sauce createSauce() {
		return new MarinaraSauce();
	}
 
	public Cheese createCheese() {
		return new ReggianoCheese();
	}
 
	public Veggies[] createVeggies() {
		Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
		return veggies;
	}
 
	public Pepperoni createPepperoni() {
		return new SlicedPepperoni();
	}

	@Override
	public Clams createClams() {
		return new FreshClams();
	}
}

public abstract class PizzaStore {
 
	protected abstract Pizza createPizza(String item);
 
	public Pizza orderPizza(String type) {
		Pizza pizza = createPizza(type);
		System.out.println("--- Making a " + pizza.getName() + " ---");
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
}

public class NYPizzaStore extends PizzaStore {
 
	protected Pizza createPizza(String item) {
		Pizza pizza = null;
		PizzaIngredientFactory ingredientFactory = 
			new NYPizzaIngredientFactory();
 
		if (item.equals("cheese")) {
  
			pizza = new CheesePizza(ingredientFactory);
			pizza.setName("New York Style Cheese Pizza");
  
		} else if (item.equals("veggie")) {
 
			pizza = new VeggiePizza(ingredientFactory);
			pizza.setName("New York Style Veggie Pizza");
 
		} else if (item.equals("clam")) {
 
			pizza = new ClamPizza(ingredientFactory)
            
           

相關推薦

Java設計模式()工廠設計模式

1. 工廠設計模式 1.1 應用場景 由於需求的變化,一個類的子類經常面臨著劇烈的變化,但他卻擁有比較穩定的介面。使用一種封裝機制來“隔離這種易變物件的變化”,工廠方法定義一個用於建立物件的介面,讓子類來確定建立哪一個具體類的物件,將物件的例項化延遲。 1.2 概念 定義了一

java常用設計模式建造者模式

規則 擴展 cto 抽象 具體類 代碼量 特定 clas class 1、定義 是一種對象構建的設計模式,它可以將復雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象。 產品類:一般是一個較為復雜的對象,也就是說創建對象的過

C#設計模式工廠方法模式

工廠方法模式(Factory Method): 定義一個用於建立物件的介面,讓子類決定例項化哪一個類。工廠方法使一個類的例項化延遲到其子類 回顧之前簡單工廠 簡單工廠的核心程式碼 class OperationFactory { public

Java設計模式(創建型工廠方法模式)

out nbsp 操作 短信發送 ora print temp ati ural (該文內容為原創,有不足之處望多多指教!) 設計模式根據目的準則可以分為三類: 創建型:creational 創建型的設計模式與對象的創建有關。 結構型:Structural 處理類和

Java 設計模式(二)工廠方法模式

參考連結:工廠方法模式-Factory Method Pattern 在介紹簡單工廠模式時提到簡單工廠模式存在一個很嚴重的問題,就是當系統中需要引入新產品時,如果靜態工廠方法是通過傳入引數的不同來建立不同的產品,這必定要修改工廠類的原始碼,將違背“開閉原則”,如何實現增加新產品而不影

JAVA設計模式(1)工廠設計模式

工廠模式是Java中最常用的設計模式之一。 這種型別的設計模式屬於建立模式,因為此模式提供了建立物件的最佳方法之一。 在工廠模式中,我們沒有建立邏輯暴露給客戶端建立物件,並使用一個通用的介面引用新建立的物件。 實現方法 我們將建立一個Shape介面和實現Shape介面的具體類。 一個工廠類S

設計模式()從“兵工廠”中探索簡單工廠工廠方法和抽象工廠模式

前面陸陸續續的更新了三篇關於設計模式的部落格,是關於“策略模式”、“觀察者模式”、“裝飾者模式”的,今天這篇部落格就從“兵工廠”中來探索一下“工廠模式”(Factory Pattern)。“工廠模式”又可以分為“簡單工廠模式”(Simple Factory Pattern)、“工廠方法模式”(Factory

java常用設計模式工廠模式

1、簡單工廠模式(靜態工廠方法模式) 抽象例項: public interface People { void talk(); } 具體例項: public class Doctor implements People { public void talk() {

Java設計模式(十)MVC設計模式

1. 應用場景 MVC設計模式廣泛應用於桌面應用程式開發和網頁頁面開發這些與使用者互動的應用場景中。 2.概念 眾所周知MVC不是設計模式,是一個比設計模式更大一點的模式,稱作設計模式不合理,應該說MVC它是一種軟體開發架構模式,它包含了很多的設計模式,最為密切是以下三種:Obs

PHP設計模式系列(工廠方法模式

工廠方法模式 工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多型工廠(Polymorphic Factory)模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責

Java設計模式補充回調模式、事件監聽器模式、觀察者模式(轉)

應該 hand 關閉 lan china 關註 update 使用 event 一、回調函數 為什麽首先會講回調函數呢?因為這個是理解監聽器、觀察者模式的關鍵。 什麽是回調函數 所謂的回調,用於回調的函數。 回調函數只是一個功能片段,由用戶按照回調函數調用約定來實現的

設計模式之六工廠方法模式(Factory method Pattern)

image bsp turn stat ole ati ace 方法 系統擴展 工廠方法(Factory Method)模式就是定義一個創建對象的工廠接口,將實際創建工作推遲到子類當中。 核心工廠類不再負責具體產品的創建,僅提供了具體工廠子類必須實現的接口,這樣核

設計模式實戰應用之五工廠方法模式

fontsize -c iterator name 工廠方法 iss sat cep exce 工廠方法模式的定義 工廠方法模式的應用相當廣泛。工廠方法模式在 Java API 中的應用比比皆是:java.util.Collection 接

Java設計模式百例 - 工廠方法模式

java設計模式本文源碼見:https://github.com/get-set/get-designpatterns/tree/master/factory-method工廠方法模式同簡單工廠模式一樣,也是創建類模式,又叫做虛擬構造(Virtual Constructor)模式或多態工廠(Polymorph

設計模式(2)工廠方法模式

sys 實例化 不同 err reat inter 設計 end 泛型 工廠方法模式: ? 定義: ? 定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工廠方

設計模式工廠方法模式

left 實例 設計模式 設計 通過 耦合度 creat margin 增加 一、簡單工廠模式 1、內容 不直接向客戶端暴露對象創建的實現細節,而是通過一個工廠類來負責創建產品類的實例 2、角色 1、工廠角色(Factory) 2、抽象產品角色(Product) 3、具體產

js設計模式工廠方法模式 讀書筆記

對於建立多類物件,簡單工廠就不太實用了。  通過工廠方法模式可以輕鬆的建立多個類的例項物件,而且建立物件的方式避免了使用者與物件類之間的耦合,使用者不必關心建立該物件的具體類,只需呼叫工廠方法即可。 安全的工廠方法模式 var Factory=function(type,con

Java設計模式11觀察者模式

一、什麼是觀察者模式 在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述觀察者(Observer)模式的:   觀察者模式是物件的行為模式,又叫釋出-訂閱(Publish/Subscribe)模式、模型-檢視(Model/View)模式、源-監聽器(Source/Listener)模式

Java設計模式9橋接模式

一、橋接模式: 橋接模式是用於把抽象化與實現化解耦,使得二者可以獨立變化。這種型別的設計模式屬於結構型模式,它通過提供抽象化和實現化之間的橋接結構,來實現二者的解耦。 二、示例程式碼: 先來考慮下如下場景: 傳送訊息功能。基本上所有帶業務流程處理的系統都會有這樣的功能,比如OA上

Java設計模式1單例模式

咳咳,想系統的整理一下知識想了好久了,畢竟工作了快半年了,業務程式碼感覺已經寫得差不多了,明顯感覺到又到了再夯實一遍基礎的時候了,畢竟基礎打得好後面才能得心應手,事半功倍。所以就從設計模式這裡開始看吧。   設計模式感覺在寫程式碼的時候也是挺重要的,確實有些時候就是不知道該如何設計