1. 程式人生 > >設計模式學習——工廠模式

設計模式學習——工廠模式

工廠模式有幾種不同方式:簡單工廠模式、工廠方法模式、抽象工廠模式。用來統一管理不同產品的建立。

簡單工廠模式

  1. 定義:屬於類的創新型模式,又稱靜態工廠方法模式,通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。
  2. 包含的角色及其職責:
  • 工廠角色:這是簡單工廠模式的核心,由它負責建立所有類的核心邏輯。能夠被外界呼叫,建立所需的產品物件。
  • 抽象產品角色:簡單工廠模式所建立的所有物件的父類(可以是介面也可以是抽象類),負責描述所有例項所共有的公共介面。
    、* 具體產品角色:簡單工廠所建立的具體例項物件。
  1. 核心思想:有一個專門的類來負責建立例項的過程。 實質是選擇實現的過程。
  2. 優缺點
    優點:使用者無需瞭解物件是如何建立及如何組織的,有利於整個軟體體系結構的優化。
    缺點:違背單一職責原則和開放封閉原則。
  3. android中簡單工廠模式之一就是獲取服務的系統方法“getSystemService”
  4. 簡單示例:
  • 工廠角色
/**
 * 工廠類,用來建立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("正在使用簡單工廠");
	}
}

工廠方法模式

  1. 定義:同樣屬於類的建立型模式,又稱多型工廠模式。意義是定義一個建立產品物件的工廠介面,讓子類決定例項化哪個類。(當只有一個工廠類時,可簡化相當與簡單工廠)
  2. 包含的角色及其職責:
    A、抽象工廠角色:這是工廠方法模式的核心,任何工廠類都必須實現這個介面。
    B、具體工廠角色:具體工廠類是抽象工廠的一個實現,負責例項化產品物件。
    C、抽象產品角色:工廠方法模式所建立的所有產品的父類(可以是介面也可以是抽象類)。
    D、具體產品角色:工廠方法所建立的具體例項物件。
  3. 工廠方法模式解決的是同一系列產品的建立問題。
  4. 優缺點
    優點:當系統拓展需要新增新的產品物件時,僅需新增一個具體物件以及一個具體工廠物件,原有工廠物件不需修改。很好符合開放封閉原則。
    缺點:把簡單工廠模式的內部判斷邏輯轉移到了客戶端,客戶端需要決定例項化哪一個具體的工廠。
  5. android的activity和service等核心元件中都定義了onCreate()方法。和List和Set都用到此模式。
  6. 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();
    }
}

抽象工廠模式

  1. 抽象工廠模式:是所有形態 的工廠模式中最為抽象和最具一般性的。抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品型別的情況下,能夠建立多個產品族的產品物件。
  2. 包含的角色及其職責:
  • 抽象工廠角色:這是工廠方法模式的核心,包含對多個產品結構的宣告,任何工廠類都必須實現這個介面。
  • 具體工廠角色:具體工廠類是抽象工廠的一個實現,負責例項化某個產品族中的產品物件。
  • 抽象產品角色:抽象模式所建立的所有物件的父類(可以是介面也可以是抽象類),負責描述所有例項所共有的公共介面。
  • 具體產品角色:抽象模式所建立的具體例項物件。
  1. 工廠方法模式針對的是一個產品等級結構;而抽象工廠模式針對的是多個產品等級結構。

  2. 優缺點
    優點:客戶端不再負責物件的具體建立,而是把這個任務交給了具體工廠類,客戶端只負責對物件的呼叫。
    缺點:新產品加入時,需要修改抽象工廠類的設計,導致要修改所有具體工廠類。

  3. android應用開發中涉及到的IPC通訊就是抽象工廠模式很好的說明。

  4. UML圖
    在這裡插入圖片描述

  5. 實現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()");  
    }  
}