Java[Android]設計模式之工廠模式(簡單工廠模式+工廠方法模式+抽象工廠模式)
1. 寫在前面
網上關於設計模式的文章已經非常詳盡了,寫這篇文章旨在給自己的學習做一個筆記和總結方便以後翻閱查詢,若對你有用可細學之若覺得膚淺可略之。
工廠模式屬於建立型設計模式,分為簡單工廠模式,工廠方法模式,抽象工廠模式三種,話不多說,請看下面一一道來。
2. 簡單工廠模式
簡單工廠模式屬於建立型設計模式,又叫靜態工廠(Static Factory Method)模式,簡單工廠模式(靜態工廠模式)是工廠內部根據傳入的條件(或者工廠內部決定)創建出適合的產品,簡單工廠模式相對來說是工廠模式中最簡單的一種設計模式(相對於工廠方法模式和抽象工廠模式)。
2.1 UML類圖
從UML類圖中可以看出簡單工廠存在幾種不同的角色,一是產品的父類即產品模版IProduct,二是繼承IProduct的不同產品ProductA,ProductB...,三是最重要的負責生產產品的Factory工廠類,當然還包括一個模擬的Client。Client端只需要通過Factory就可以根據不同的需求創建出不同的Product,而不需要直接通過new來建立,這樣就遮蔽了物件的建立過程。
2.2 程式碼示例
抽象產品介面類:
public interface IProduct {
public void create(String s);
}
具體產品實現類:
public class ProductA implements IProduct{
public ProductA() {
}
@Override
public void create(String s) {
// TODO Auto-generated method stub
System.out.println("ProductA create");
}
}
public class ProductB implements IProduct{ public ProductB() { } @Override public void create(String s) { // TODO Auto-generated method stub System.out.println("ProductB create"); } }
工廠類:
public class Factory { public static <T extends IProduct> T createProduct(int flag) { T product = null; switch (flag) { case 1: product = (T)new ProductA(); break; case 2: product = (T)new ProductB(); break; default: product = (T)new ProductA(); break; } return product; } }
簡單客戶端測試類:
public class Client {
public static void main(String[] args) {
Factory.createProduct(1).create("test");
}
}
2.3 在原始碼中的實際應用
BitmapFactory->res.openRawResource->mResourcesImpl.openRawResource->getValue->mAssets.getResourceValue
3. 工廠方法模式
工廠方法模式(Factory Method)又叫多型工廠模式和虛擬構造器模式,通過定義工廠父類負責定義建立物件的公共介面,而子類則負責生成具體的物件。
3.1 UML類圖
從UML圖中可以看出工廠方法模式和簡單工廠模式比較類似或者說工廠方法模式是對簡單工廠模式的擴充套件,仍然是利用工廠根據不同的需求建立不同的產品,建立過程在UML圖中沒有體現(和簡單工廠類似),工廠方法模式中重點在方法兩個字上,這裡附上自己對其的理解-所謂方法即在父類或介面(產品共性)中定義abstract方法或者介面方法,在具體的產品中實現方法,這樣我們可以通過父類或者介面的定義但在記憶體中指向的是具體的實現來呼叫具體產品的實現。(呵呵,不知道說得清楚不清楚,反正我是這樣理解的)
3.2 程式碼示例
抽象產品類:
public interface IProduct {
public void show();
}
具體產品A:
public class ProductA implements IProduct {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("ProductA show()");
}
}
具體產品B:
public class ProductB implements IProduct {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("ProductB show()");
}
}
抽象構造器(定義抽象方法或介面方法的父類,主要體現工廠方法中方法二字的父類):public abstract class Creator {
public abstract IProduct factoryMethod();
public void operate() {
IProduct product = factoryMethod();
product.show();
}
}
具體構造器A:
public class ConcreteCreatorA extends Creator {
public IProduct factoryMethod(){
return new ProductA();
}
}
具體構造器B:
public class ConcreteCreatorB extends Creator {
public IProduct factoryMethod(){
return new ProductB();
}
}
public class ConcreteCreatorB extends Creator {
public IProduct factoryMethod(){
return new ProductB();
}
}
最後工廠類及測試類:public class Factory {
public static Creator generateCreator(int flag) {
Creator creator = null;
switch (flag) {
case 1:
creator = new ConcreteCreatorA();
break;
case 2:
creator = new ConcreteCreatorB();
break;
default:
creator = new ConcreteCreatorA();
break;
}
return creator;
}
}
public class Client {
public static void main(String[] args) {
Factory.generateCreator(2).operate();
}
}
3.3 在原始碼中的應用體現
工 廠方法模式在Android中應用如:
List(抽象工廠方法)->AbstractList->ArrayList(具體工廠方法實現,實際會呼叫裡面的實現)
Activity(工廠,工廠方法)->ListActivity(具體工廠方法實現和具體產品)
LayoutInflater.FactoryManager->LayoutInflater.Factory(Factory2)(工廠方法)->Activity(或者具體的Activity)(具體工廠方法實現和具體產品)
4. 抽象工廠模式
引用百度百科的抽象工廠模式的定義-為建立一組相關或相互依賴的物件提供一個介面,而且無需指定他們的具體類;抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品的具體的情況下,建立多個產品族中的產品物件,這裡有引入了一個產品族的概念-所謂產品族就是具有相同功能(實現同一介面或abstract class)的不同物件。
4.1 UML類圖
從UML圖中可以看出抽象工廠模式有以下幾種角色存在:
抽象工廠(Abstract Factory)角色:擔任這個角色的是工廠方法模式的核心, 定義生產不同產品族的方法,通常為interface或者abstract class;對應UML圖中的AbstractFactory類。
具體工廠(Concrete Factory)角色:這個角色直接在客戶端的呼叫下建立產品的例項,即建立不同產品族中合適的產品,其implements或者extends AbstractFactory;對應UML圖中的ConcreteFactory1和ConcreteFactory2。
抽象產品(Abstract Product)角色:擔任這個角色的類是工廠方法模式所建立的物件的父類,或它們共同擁有的介面;對應UML圖中的AbstractProductA和AbstractProductB。
具體產品(Concrete Product)角色:抽象工廠模式所建立的任何產品物件都是某一個具體產品類的例項。是最終需要的東西;對應UML圖中的ProductA1,ProcuctB1,ProductA2,ProductB2。
4.2 程式碼示例
AbstractFactory:
public abstract class AbstractFactory {
public abstract AbstractProductA createProductA();
public abstract AbstractProductB createProductB();
}
ConcreteFactory1:
public class ConcreteFactory1 extends AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}
ConcreteFactory2:
public class ConcreteFactory2 extends AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
AbstractProductA:
public interface AbstractProductA {
public void show();
}
AbstractProductB:
public interface AbstractProductB {
public void show();
}
ProductA1:
public class ProductA1 implements AbstractProductA {
@Override
public void show() {
System.out.println("ProductA1");
}
}
ProductA2:public class ProductA2 implements AbstractProductA {
@Override
public void show() {
System.out.println("ProductA2");
}
}
ProductB1:
public class ProductB1 implements AbstractProductB {
@Override
public void show() {
System.out.println("ProductB1");
}
}
ProductB2:
public class ProductB2 implements AbstractProductB {
@Override
public void show() {
System.out.println("ProductB2");
}
}
Client:
public class Client {
public static void main(String[] args) {
new ConcreteFactory1().createProductA().show();
new ConcreteFactory1().createProductB().show();
new ConcreteFactory2().createProductA().show();
new ConcreteFactory2().createProductB().show();
}
}
4.3 在原始碼中的應用體現
寫過JDBC連線資料庫的應該知道,JDBC中Connection是通過Driver及對應的URL過建立的,其實在這個建立過程中就用到了抽象工廠模式。
5. 為什麼要使用工廠模式
其實設計模式就是為了解決某一特定的問題或者說更方便的解決問題而出現的,那使用它到底有什麼好處呢:
簡單工廠:這個比較好理解,封裝解耦,客戶端不用關心具體的實現類,只需要知道其父類就可以了;當然也有一些弊端,不利於擴充套件,當需要增加產品的時候就需要額外增加工廠類來實現。
工廠方法:同樣,隔離了物件的建立過程,降低耦合,感覺是對簡單工廠的進一步擴充。
抽象工廠:同簡單工廠和工廠方法一樣,隔離了物件的建立過程,降低耦合;並可以保證同一個工廠中創建出來的是同一個產品族中的產品;便於擴充,擴充時不需要修改原來的程式碼結構;但其程式碼結構比較複雜不好理解,在新增產品時需要修改AbstractFactory進行擴充套件。
好了,關於工廠模式(簡單工廠,工廠方法,抽象工廠)就說到了這裡,純屬個人理解和學習筆記。