1. 程式人生 > >3.抽象工廠模式(Abstract Factory)

3.抽象工廠模式(Abstract Factory)

一、簡介

定義:

為建立一組相關或相互依賴的物件提供一個介面,而且無需指定他們的具體類。

為了方便引進抽象工廠模式,引進一個新概念:產品族(Product Family) 。所謂產品族,是指位於不同產品等級結構,功能相關聯的產品組成的家族。如圖:

圖中一共有四個產品族,分佈於三個不同的產品等級結構中。只要指明一個產品所處的產品族以及它所屬的等級結構,就可以唯一的確定這個產品。

引進抽象工廠模式

所謂的抽象工廠是指一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有物件。如果用圖來描述的話,如下圖:

二、Abstract Factory模式的結構:

上圖用產品族的概念來解釋如下圖:

其中分為以下四個角色:

  1. 抽象工廠(Abstract Factory)角色: 擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。
  2. 具體工廠(Concrete Factory)角色: 這個角色直接在客戶端的呼叫下建立產品的例項。這個角色含有選擇合適的產品物件的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。
  3. 抽象產品(Abstract Product)角色: 擔任這個角色的類是工廠方法模式所建立的物件的父類,或它們共同擁有的介面。
  4. 具體產品(Concrete Product)角色: 抽象工廠模式所建立的任何產品物件都是某一個具體產品類的例項。這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。

三、示範程式

該程式演示了抽象工廠的結構,本身不具有任何實際價值。

先看類圖:

抽象產品(按鈕):

package _3AbstractFactoryPattern;

public interface IButton {
	public void click();
}

抽象產品(輸入框):

package _3AbstractFactoryPattern;

public interface ITextInput {
	public void input();
}

按鈕產品實現(windows):

package _3AbstractFactoryPattern;

public class WindowsButton implements IButton {

	@Override
	public void click() {
		System.out.println("windows 按鈕點選");
	}

}

按鈕產品實現(linux):

package _3AbstractFactoryPattern;

public class LinuxButton implements IButton {

	@Override
	public void click() {
		System.out.println("Linux 按鈕點選");
	}

}

輸入框產品實現(windows):

package _3AbstractFactoryPattern;

public class WindowsTextInput implements ITextInput {

	@Override
	public void input() {
		System.out.println("Windows 輸入框輸入");
	}

}

輸入框產品實現(linux):

package _3AbstractFactoryPattern;

public class LinuxTextInput implements ITextInput {

	@Override
	public void input() {
		System.out.println("Linux 輸入框輸入");
	}

}

抽象工廠:

package _3AbstractFactoryPattern;

public interface IUICreator {

	public IButton createButton();
	public ITextInput createTextInput();
}

工廠實現(windows):

package _3AbstractFactoryPattern;

public class WindowsUICreator implements IUICreator {

	@Override
	public IButton createButton() {
		return new WindowsButton();
	}

	@Override
	public ITextInput createTextInput() {
		return new WindowsTextInput();
	}

}

 工廠實現(linux)

package _3AbstractFactoryPattern;

public class LinuxUICreator implements IUICreator {

	@Override
	public IButton createButton() {
		return new LinuxButton();
	}

	@Override
	public ITextInput createTextInput() {
		return new LinuxTextInput();
	}

}

這其中:button和textinput就是產品等級,而windows和linux兩個系列的產品就是產品族。

抽象工廠模式的優點:

  1. 封裝性
  2. 產品族內的約束為非公開狀態
  3. 擴充套件產品族非常方便

抽象工廠模式的缺點:

  1. 擴充套件產品等級困難,需要修改工廠類的介面.上例中如果需要新增一個panel產品,則需要修改的UICreator介面。

抽象工廠模式的使用場景:

一個物件族(或是一組沒有任何關係的物件)都有相同的約束,則可以使用抽象工廠模式。上例中的button和TextInput沒有任何關係,但是它們同時被作業系統約束。