設計模式之抽象工廠模式
這個類圖比較簡單,也很直觀。一個接口,多個抽象類,然後多個實現類。每個人種都是抽象類,性別是在各個實現類中實現的。HumanFactory定義了三個方法,分別創建三個不同膚色的人類。
人種有三個抽象類,負責人種的抽象屬性定義:膚色和語言,
人種接口
public interface Human {
void getTalk();
void getColor();
void getSex();
}
人種有三個抽象類,負責人種的抽象屬性定義
黑色人種
public abstract class AbstractBlackHuman implements Human{
@Override
public void getTalk() {
System.out.println("黑人說話聽不懂");
}
@Override
public void getColor() {
System.out.println("我的皮膚是黑色的");
}
}
白色人種
public abstract class AbstractWhiteHuman implements Human{
@Override
public void getTalk() {
System.out.println("我是一個白人");
}
@Override
public void getColor() {
System.out.println("我的皮膚是白色的");
}
}
黃色人種
public abstract class AbstractYellowHuman implements Human{
@Override
public void getTalk() {
System.out.println("黃種人說話最好聽");
}
@Override
public void getColor() {
System.out.println("我的皮膚是黃色的");
}
}
每個抽象類都有兩個實現,分別實現公共的細節最具體的事物。
定義一個黑人女性
public class FamaleBlackHuman extends AbstractYellowHuman {
@Override
public void getSex() {
System.out.println("黑人女性");
}
}
黑人男性人種
public class MaleBlackHuman extends AbstractYellowHuman {
@Override
public void getSex() {
System.out.println("黑色人種男性");
}
}
八卦爐的定義,分別創建三個不同膚色的人
public interface HummanFactory {
public Human createBlackHuman();
public Human createYellowHuman();
public Human createWhiteHuman();
}
八卦爐的細分,生產女性的八卦爐
public class FamaleFactory implements HummanFactory {
@Override
public Human createBlackHuman() {
return new FamaleBlackHuman();
}
@Override
public Human createYellowHuman() {
return new FamaleYellowHuman();
}
@Override
public Human createWhiteHuman() {
return null;
}
}
生產男性的八卦爐
public class MaleFactory implements HummanFactory {
@Override
public Human createBlackHuman() { return new MaleBlackHuman(); }
@Override
public Human createYellowHuman() {
return new MaleBlackHuman();
}
@Override
public Human createWhiteHuman() {
return null;
}
}
女媧重造人類
public class NvWa {
public static void main(String[] args){
//第一條生產線,男性生產線
HummanFactory balckMale = new MaleFactory();
//創建人類
Human human = balckMale.createBlackHuman();
human.getSex();
}
}
總結
- 每個工廠有很多車間,每個車間又分多條生產線,分別生成不同的產品,我們可以吧八卦爐比喻爲車間,把八卦爐的工藝叫做生產線。如此看來就是女性生產車間生產不同膚色的女性,男性生產車間生產不同膚色的男性。
抽象工廠的定義
-
爲創建一組相關或相互依賴的對象提供一個接口,而且無須指定他們的具體類。
-
抽象工廠是工廠模式的升級版本,在有多個業務品種,業務分類時,通過抽象工廠模式產生需要的對象是一種非常號的解決方式。
-
兩個抽象類產品類可以有關係,例如共同繼承和實現一個抽象類接口。
定義抽象產品類
public abstract class AbstractProductA {
/**
* 共享方法
*/
public void shareMethod(){}
/**
* 每個產品相同的方法, 不同的實現
*/
public abstract void doSomeThimg();
}
產品類A1的實現類
public class ProductA1 extends AbstractProductA{
@Override
public void doSomeThimg() {
System.out.println("產品A1的實現");
}
}
產品類A2的實現
public class ProductA2 extends AbstractProductA{
@Override
public void doSomeThimg() {
System.out.println("產品A2的實現");
}
}
抽象工廠類AbstractCreator的職責是定義每個工廠要實現的功能。
public abstract class AbstractCreator {
//創建A產品類
public abstract AbstractProductA createProductA();
//創建B產品類
public abstract AbstractProductB createProductB();
//todo 有N個產品類,在抽象工廠類中就應該有N個創建方法
}
創建一個產品是由實現類來完成的,Creator1和Creator2
產品等級1的實現
public class Creator1 extends AbstractCreator {
//創建產品等級爲1 的A類產品
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
//創建產品等級爲1 的B類產品
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
//todo 有M個產品等級就應該有M個實現工廠類,在每個實現工廠中,實現不同產品類的生成任務。
}
產品等級2的實現
public class Creator2 extends AbstractCreator {
//創建產品等級爲2的A類產品
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
//創建產品等級爲2的B類產品
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}
場景類
public class Client {
//場景類
public static void mian(String[] args){
AbstractCreator abstractCreator = new Creator1();
AbstractCreator abstractCreator12 = new Creator2();
//產生A1對象
abstractCreator.createProductA();
//產生A2對象
abstractCreator12.createProductA();
//產生B1對象
abstractCreator.createProductB();
//產生B2對象
abstractCreator12.createProductB();
}
}
在產品類上,沒有一個方法與實現類有關係,對於一個產品來說,我們只要知道它的工廠方法就可以直接產生一個產品對象,無須關心它的實現類。
抽象工廠的優點:
- 封裝性,每個產品的實現類不是高層模塊需要關心的, 它要關心的是接口,抽象類,它不關心對象是如何創建出來的,由誰負責的,工廠類,只要知道工廠類是誰,就能創建出一個需要的對象。
- 產品族內的約束爲非公開狀態,舉個例子,加入女媧有自己的想法,她不想女盛男衰,它想每生產一個女性,就生產1.2倍的男生,但是對於實現高層是不需要的,也不關心,它只需要知道我調用的類,接口,我要創建一個人。
抽象工廠的缺點:
- 抽象工廠最大的缺點就是擴展困難,加入我們要加入一個產品C,也就是說原先的產品家族由2個變成3個,AbstractCreator要增加一個createProductC(),然後兩個實現類都要改變。打個比方,抽象類和接口是一個契約,改變契約,所有與契約有關係的代碼都要改掉。
抽象工廠的使用場景:
- 一個對象族或是一組沒有任何關係的對象都有相同的約束,則可以使用工廠模式。
- 舉例說明:一個文本編輯器和一個圖片編輯器,在不同操作系統下面他們的代碼都不同,但是他們的界面和功能是相同的,於實我們可以用抽象工廠模式,產生不同操作系統下面的文本編輯器和圖片編輯器。
抽象工廠的注意事項;
最佳實踐:
- 一個應用,需要應用在不同操作系統下面(Windows,Linux,Andorid)上運行,他們都有相同的約束,但是他們要實現 的效果都是一樣的(軟件功能,應用邏輯,Ui),所以這個時候我們可以用抽象工廠模式創建不同操作系統下面的應用,由不同的產品類去處理與操作系統交互的信息。