工廠模式是創建型模式之一。簡單的說,工廠模式就是爲了減少代碼的工作量,方便測試和擴展。在工廠模式中,創建對象時不會對客戶端暴露創建邏輯,並且是通過使用一個共同的接口來指向新創建的對象。創建工廠類,接收不同的參數生成不同的對象的過程。由於簡單工廠模式,抽象工廠模式,工廠方法模式依次遞進且很相似,所以放在一起總結。
一、定義
工廠模式定義一個用於創建對象的接口,這個接口由子類決定實例話哪一個類。該模式是一個類的實例話延遲到了子類。而子類可以重寫接口方法便於創建不同類型的對像
二、分類
簡單工廠模式
簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。在簡單 工廠模式中,可以根據參數的不同返回不同類的實例。簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。
優點:
1、簡單工廠模式實現了責任分離
2、工廠類中包含了對象生成的必要邏輯判斷,根據客戶端的選擇條件實例化不同的對象,所以客戶端沒有創建對象所需要的條件
3、客戶端不直接創建產品類的對象,客戶端只作爲消費者,具體邏輯代碼交由工廠類處理
缺點:
1、工廠類必須知道怎麼樣創建每一個對象,當增加一個對象時必須改動工廠類的邏輯代碼,所以簡單工廠模式不符合開閉原則。
2、因爲工廠類中的工廠方法是靜態的,所以工廠類中的方法不能被重寫,工廠類只是一個單獨的類,它不能成爲一個層次的類
抽象工廠模式
抽象工廠模式(Abstract Factory Pattern):提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象創建型模式。
優點:
1、更符合開閉原則,增加創建對象時只需要修改相應的產品類和工廠子類
2、符合單一職責原則,每個產品都有相應的工廠負責
3、不使用靜態工廠方法,可以形成基於繼承的等級結構。
缺點:
1、沒有完全符合開閉原則,這是因爲在抽象工廠角色中規定了所有可能被創建的產品集合,要支持新種類的產品就意味着要對該接口進行擴 展,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。
工廠方法模式(工廠模式)
優點:
缺點:
三、基本結構
簡單工廠模式
簡單工廠模式定義三個角色:
· 工廠角色(Factory): 負責創建實例的具體邏輯。
· 抽象產品角色(Product):是所有創建對象的的父類,擁有所有創建對象的公共接口。
· 具體產品角色(CreateProduct):具體產品角色是創建目標,所有創建的對象都充當這個角色的某個具體類的實例。
抽象工廠模式
AbstractFactory:抽象工廠
ConcreteFactory:具體工廠
AbstractProduct:抽象產品
Product:具體產品
工廠方法模式
Product:抽象產品
ConcreteProduct:具體產品
Factory:抽象工廠
ConcreteProduct:具體工廠
四、時序圖
簡單工廠模式
抽象工廠模式
五、代碼實現
簡單工廠模式
1.工廠角色
public class FruitFactory {
public static Fruit newInstance(String name) throws BadFruitException {
if ("apple".equalsIgnoreCase(name)) {
return new Apple();
} else if ("grape".equalsIgnoreCase(name)) {
return new Grape();
} else if ("strawberry".equalsIgnoreCase(name)) {
return new Strawberry();
// 其它情況,則拋出異常。
} else {
throw new BadFruitException("Bad fruit request!");
}
}
}
2.抽象產品角色
public abstract class Fruit {
//公共屬性
abstract void grow(); // 生長
abstract void harvest(); // 收穫
abstract void plant(); // 種植
}
3.具體產品角色
由三個角色 apple、grape、strawberry都繼承抽象產品角色,重寫其中的方法表現出每個產品不一樣的行爲
4.客戶端代碼
public class Client {
public static void main(String[] args) {
try {
Fruit apple = FruitFactory.newInstance("Apple");
apple.plant();
apple.grow();
apple.harvest();
Fruit grape = FruitFactory.newInstance("Grape");
grape.plant();
grape.grow();
grape.harvest();
Fruit strawberry = FruitFactory.newInstance("strawberry");
strawberry.plant();
strawberry.grow();
strawberry.harvest();
Fruit error = FruitFactory.newInstance("error");
error.plant();
error.grow();
error.harvest();
} catch (BadFruitException e) {
e.printStackTrace();
}
}
}
抽象工廠模式
1、抽象工廠
abstract class Factory{
public abstract Product ManufactureContainer();
public abstract Product ManufactureMould();
}
2、具體工廠
//A廠 - 生產模具+容器產品
class FactoryA extends Factory{
@Override
public Product ManufactureContainer() {
return new ContainerProductA();
}
@Override
public Product ManufactureMould() {
return new MouldProductA();
}
}
//B廠 - 生產模具+容器產品
class FactoryB extends Factory{
@Override
public Product ManufactureContainer() {
return new ContainerProductB();
}
@Override
public Product ManufactureMould() {
return new MouldProductB();
}
}
3、抽象產品族
abstract class AbstractProduct{
public abstract void Show();
}
4、抽象產品
//容器產品抽象類
abstract class ContainerProduct extends AbstractProduct{
@Override
public abstract void Show();
}
//模具產品抽象類
abstract class MouldProduct extends AbstractProduct{
@Override
public abstract void Show();
}
5、具體產品
//容器產品A類
class ContainerProductA extends ContainerProduct{
@Override
public void Show() {
System.out.println("生產出了容器產品A");
}
}
//容器產品B類
class ContainerProductB extends ContainerProduct{
@Override
public void Show() {
System.out.println("生產出了容器產品B");
}
}
//模具產品A類
class MouldProductA extends MouldProduct{
@Override
public void Show() {
System.out.println("生產出了模具產品A");
}
}
//模具產品B類
class MouldProductB extends MouldProduct{
@Override
public void Show() {
System.out.println("生產出了模具產品B");
}
}
6、客戶端
//生產工作流程
public class AbstractFactoryPattern {
public static void main(String[] args){
FactoryA mFactoryA = new FactoryA();
FactoryB mFactoryB = new FactoryB();
//A廠當地客戶需要容器產品A
mFactoryA.ManufactureContainer().Show();
//A廠當地客戶需要模具產品A
mFactoryA.ManufactureMould().Show();
//B廠當地客戶需要容器產品B
mFactoryB.ManufactureContainer().Show();
//B廠當地客戶需要模具產品B
mFactoryB.ManufactureMould().Show();
}
}
六、應用
簡單工廠模式
1、工廠類負責創建的對象比較少:由於創建的對象較少,不會造成工廠方法中的業務邏輯太過複雜。
2、客戶端只知道傳入工廠類的參數,對於如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,只需要知道類型所對應的參數。
抽象工廠模式
1、一個系統不要求依賴產品類實例如何被創建、組合和表達的表達,這點也是所有工廠模式應用的前提。
2、這個系統有多個系列產品,而系統中只消費其中某一系列產品