設計模式學習——工廠模式
阿新 • • 發佈:2018-12-22
工廠模式有幾種不同方式:簡單工廠模式、工廠方法模式、抽象工廠模式。用來統一管理不同產品的建立。
簡單工廠模式
- 定義:屬於類的創新型模式,又稱靜態工廠方法模式,通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。
- 包含的角色及其職責:
- 工廠角色:這是簡單工廠模式的核心,由它負責建立所有類的核心邏輯。能夠被外界呼叫,建立所需的產品物件。
- 抽象產品角色:簡單工廠模式所建立的所有物件的父類(可以是介面也可以是抽象類),負責描述所有例項所共有的公共介面。
、* 具體產品角色:簡單工廠所建立的具體例項物件。
- 核心思想:有一個專門的類來負責建立例項的過程。 實質是選擇實現的過程。
- 優缺點
優點:使用者無需瞭解物件是如何建立及如何組織的,有利於整個軟體體系結構的優化。
缺點:違背單一職責原則和開放封閉原則。 - android中簡單工廠模式之一就是獲取服務的系統方法“getSystemService”
- 簡單示例:
- 工廠角色
/** * 工廠類,用來建立Api物件 * @author dream * */ public class Factory { /** * 具體建立Api物件的方法 * @param condition 從外部傳入的選擇條件 * @return 建立好的Api物件 */ public static Api createApi(int condition){ //應該根據某些條件去選擇建立哪一個具體的實現物件 //這些條件可以從外部傳入,也可以從其他途徑來獲取 //如果只有一個實現,可以省略條件,因為你沒有選擇的必要 Api api = null; if(condition == 1){ api = new ImplA(); }else if(condition == 2){ api = new ImplB(); } return api; } }
- 抽象產品
/**
* 介面的定義,該介面可以通過簡單工廠來建立
*/
public interface Api {
/**
* 示意,具體功能方法的定義
*/
public void operation(String s);
}
- 具體產品
public class ImplA implements Api{ @Override public void operation(String s) { //實現功能的程式碼 System.out.println("ImplA s==" + s); } } public class ImplB implements Api{ @Override public void operation(String s) { //實現功能的程式碼 System.out.println("ImplB s==" + s); } }
- 客戶端測試用例
public class Client {
public static void main(String[] args) {
//通過簡單工廠來獲取介面物件
Api api = Factory.createApi(1);
api.operation("正在使用簡單工廠");
}
}
工廠方法模式
- 定義:同樣屬於類的建立型模式,又稱多型工廠模式。意義是定義一個建立產品物件的工廠介面,讓子類決定例項化哪個類。(當只有一個工廠類時,可簡化相當與簡單工廠)
- 包含的角色及其職責:
A、抽象工廠角色:這是工廠方法模式的核心,任何工廠類都必須實現這個介面。
B、具體工廠角色:具體工廠類是抽象工廠的一個實現,負責例項化產品物件。
C、抽象產品角色:工廠方法模式所建立的所有產品的父類(可以是介面也可以是抽象類)。
D、具體產品角色:工廠方法所建立的具體例項物件。 - 工廠方法模式解決的是同一系列產品的建立問題。
- 優缺點
優點:當系統拓展需要新增新的產品物件時,僅需新增一個具體物件以及一個具體工廠物件,原有工廠物件不需修改。很好符合開放封閉原則。
缺點:把簡單工廠模式的內部判斷邏輯轉移到了客戶端,客戶端需要決定例項化哪一個具體的工廠。 - android的activity和service等核心元件中都定義了onCreate()方法。和List和Set都用到此模式。
- UML圖
7.簡單實現
- 抽象的工廠類
public abstract class AGrower {
//抽象的果農類,生產水果的方法
public abstract <T extends Fruits> T getFruits(Class<T> clz);
}
- 具體的工廠類
這是一種簡潔的實現,其實也可以分別為每一個產品都定義一個具體的工廠。
public class Grower extends AGrower{
public <T extends Fruits> T getFruits(Class<T> clz) {
try {
Fruits fruits = (Fruits) Class.forName(clz.getName()).newInstance(); //反射獲得產品類的例項
return (T) fruits;
} catch (Exception e) {
return null;
}
}
}
- 抽象產品類
public abstract class Fruits {
/**
* 水果的名稱(產品屬性)
*/
public abstract void name();
}
- 具體產品類
public class Banana extends Fruits {
@Override
public void name() {
System.out.println("my name is banana");
}
}
public class Apple extends Fruits {
@Override
public void name() {
System.out.println("my name is apple");
}
}
- 客戶測試類
public class Client {
public static void main(String[] args) {
//構建一個生產水果的果農物件 (工廠)
Grower grower = new Grower();
//獲得具體的水果(產品)
Fruits banana = grower.getFruits(Banana.class);
banana.name();
Fruits apple = grower.getFruits(Apple .class);
apple.name();
}
}
抽象工廠模式
- 抽象工廠模式:是所有形態 的工廠模式中最為抽象和最具一般性的。抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品型別的情況下,能夠建立多個產品族的產品物件。
- 包含的角色及其職責:
- 抽象工廠角色:這是工廠方法模式的核心,包含對多個產品結構的宣告,任何工廠類都必須實現這個介面。
- 具體工廠角色:具體工廠類是抽象工廠的一個實現,負責例項化某個產品族中的產品物件。
- 抽象產品角色:抽象模式所建立的所有物件的父類(可以是介面也可以是抽象類),負責描述所有例項所共有的公共介面。
- 具體產品角色:抽象模式所建立的具體例項物件。
-
工廠方法模式針對的是一個產品等級結構;而抽象工廠模式針對的是多個產品等級結構。
-
優缺點
優點:客戶端不再負責物件的具體建立,而是把這個任務交給了具體工廠類,客戶端只負責對物件的呼叫。
缺點:新產品加入時,需要修改抽象工廠類的設計,導致要修改所有具體工廠類。 -
android應用開發中涉及到的IPC通訊就是抽象工廠模式很好的說明。
-
UML圖
-
實現demo
- 抽象工廠:AbstractFactory介面
//抽象工廠,定義了生產族產品的方法;
public interface AbstractFactory {
public ProductA factoryA();
public ProductB factoryB();
}
- 抽象產品:ProductA介面
//抽象產品A定義了產品的公共方法,產品A和B屬於一個產品族
public interface ProductA {
public void method1();
public void method2();
}
- 抽象產品:ProductB介面
//抽象產品B定義了產品的公共方法,產品A和B屬於一個產品族
public interface ProductB {
public void method1();
public void method2();
}
- 具體工廠(生產等級為1的族產品):ConcreteFactory1類
[html] view plain copy
//ConcreateFactory1是用來生產等級為1的產品A,B;
public class ConcreateFactory1 implements AbstractFactory {
//生產等級為1的產品A
@Override
public ProductA factoryA() {
// TODO Auto-generated method stub
return new ConcreateProductA1();
}
//生產等級為1的產品B
@Override
public ProductB factoryB() {
// TODO Auto-generated method stub
return new ConcreateProductB1();
}
}
- 具體工廠(生產等級為2的族產品):ConcreteFactory2類
[html] view plain copy
public class ConcreateFactory2 implements AbstractFactory {
//生產等級為2的產品A
@Override
public ProductA factoryA() {
// TODO Auto-generated method stub
return new ConcreateProductA2();
}
//生產等級為2的產品B
@Override
public ProductB factoryB() {
// TODO Auto-generated method stub
return new ConcreateProductB2();
}
}
- 具體產品(等級為1的A產品):ConcreteProductA1類
[html] view plain copy
//等級為1的具體產品A
public class ConcreateProductA1 implements ProductA {
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等級為1的產品A的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等級為1的產品A的method2()");
}
}
- 具體產品(等級為2的A產品):ConcreteProductA2類
[html] view plain copy
//等級為2的具體產品A
public class ConcreateProductA2 implements ProductA {
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等級為2的產品A的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等級為2的產品A的method2()");
}
}
- 具體產品(等級為1的B產品):ConcreteProductB1類
[html] view plain copy
//等級為1的產品B
public class ConcreateProductB1 implements ProductB{
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等級為1的產品B的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等級為1的產品B的method2()");
}
}
- 具體產品(等級為2的B產品):ConcreteProductB2類
[html] view plain copy
//等級為2的產品B
public class ConcreateProductB2 implements ProductB {
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("等級為2的產品B的method1()");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("等級為2的產品B的method2()");
}
}