大牧絮叨設計模式:抽象工廠模式

1、 抽象工廠模式概述

抽象工廠模式(Abstract Factory)[GOF95]是一種對象的創建模式,是在工廠方法模式上的又一次改進,主要應用於多等級產品結構的項目架構中,將產品對象的創建過程產品對象的使用過程解耦合,使用抽象工廠模式的架構中業務模型從工廠對象中獲取到產品對象,只需要關注產品對象的使用即可,而可能添加了較爲複雜業務邏輯的創建過程封裝在工廠內部,讓系統中各個模塊的責任更加明確。

1.1、 核心組件

抽象工廠模式中的核心組件,主要是對多等級類型架構的一種解決方案,核心包含了高度抽象的工廠接口,產品接口以及具體的實現過程,其架構如圖所示:
在這裏插入圖片描述

  • 抽象工廠角色【Abstract Factory】:上圖中的Factory,抽象工程概念方法模式的核心,與應用系統的商業邏輯無關,主要是工廠方法標準化的定義和構建。
  • 具體工廠角色【Concrete Factory】:上圖中的MobileFactory以及ComputerFactory,該角色包含具體產品對象的創建業務邏輯,在使用時可以直接調用創建對應的產品對象。
  • 抽象產品角色【Abstract Product】:上圖中的Xiaomi或者Dell,抽象產品體系可以是1到n套相同體系的產品結構,抽象產品體系的公共數據抽象就是抽象產品角色。
  • 具體產品角色【Concrete Product】:具體業務邏輯的實現類型,由具體工廠角色負責創建的實例對象,包含了具體業務處理邏輯的實例。

1.2、 優點缺點

抽象工廠模式最早是在操作系統構建過程中落地的一個設計概念,不同的操作系統在處理窗口以及窗口中的按鈕、文字時涉及到類似的構建過程,在該架構模式下工廠架構和對應的產品架構之間會產生對應的耦合關係,在業務邏輯中必須使用具體的某個產品系列,可以支持相似架構的其他產品系列,如果是類似的模式可以通過抽象工廠設計模式進行架構,作爲創建模式中一種非常經典的設計模式,是很多設計模式的最原始的實現架構,在該模式的基礎上可以變通實現多種設計實現。

優點:

  • 產品的創建、組合和表現形式解耦合,在系統中形成兩套不同的體系,將構建與業務分離。
  • 多個產品系統可以無縫切換,並且不會影響整體系統的穩定性。
  • 客戶端依賴系統的抽象層,所有產品體系結構相似,客戶端不依賴產品實現。
  • 系統整體擴展性提高,滿足OCP原則。

缺點:

  • 多個產品體系必須相似【固定架構模式,設計約束性較高】
  • 業務無關代碼的冗餘較多。

2、 Java實現

2.1、 工廠及產品結構的定義

package com.damu.inter;

/**
 * <p>項目文檔: 抽象工廠聲明</p>
 *
 * @author 大牧
 * @version V1.0
 */
public interface IFactory<T> {
    /**
     * 產品創建方法
     * @param objects 參數列表
     * @return 創建好的產品對象
     */
    T product(Object ... objects);
}
---------------------------------------------
package com.damu.inter;

/**
 * <p>項目文檔: 抽象產品聲明</p>
 *
 * @author 大牧
 * @version V1.0
 */
public interface IProduct {
    String getInformation();
}

2.2、 具體工廠類的實現

遊戲本工廠類

package com.damu.factory;

import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.product.XiaomiGameComputer;

/**
 * <p>項目文檔: 遊戲計算機制造工廠類</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class GameComputerFactory implements IFactory<IProduct> {

    @Override
    public IProduct product(Object... objects) {
        return null;
    }

    /**
     * 小米遊戲本製造方法
     * @return 小米遊戲本
     */
    public IProduct productXiaomi() {
        return new XiaomiGameComputer();
    }

    /**
     * Dell遊戲本製造方法
     * @return Dell遊戲本
     */
    public IProduct productDell() {
        return null;
    }
}

商務本工廠處理類

package com.damu.factory;

import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.product.XiaomiBusinessComputer;

/**
 * <p>項目文檔: 商務計算機制造工廠類</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class BusinessComputerFactory implements IFactory<IProduct> {

    @Override
    public IProduct product(Object... objects) {
        return null;
    }

    /**
     * 小米商務本製造方法
     * @return 小米商務本對象
     */
    public IProduct productXiaomi() {
        return new XiaomiBusinessComputer();
    }

    /**
     * 戴爾商務本製造方法
     * @return 戴爾商務本
     */
    public IProduct productDell() {
        return null;
    }
}

學生本工廠處理類

package com.damu.factory;

import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.product.XiaomiEduComputer;

/**
 * <p>項目文檔: 學生計算機制造工廠類</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class EduComputerFactory implements IFactory<IProduct> {
    @Override
    public IProduct product(Object... objects) {
        return null;
    }

    /**
     * 小米學生本製造方法
     * @return 小米學生本
     */
    public IProduct productXiaomi() {
        return new XiaomiEduComputer();
    }

    /**
     * Dell學生本製造方法
     * @return Dell學生本
     */
    public IProduct productDell() {
        return null;
    }
}

具體產品體系的父類構建

package com.damu.inter.extend;

import com.damu.inter.IProduct;

/**
 * <p>項目文檔: Dell產品父類</p>
 *
 * @author 大牧
 * @version V1.0
 */
public interface IDell extends IProduct {
}
----------------------------------------------
package com.damu.inter.extend;

import com.damu.inter.IProduct;

/**
 * <p>項目文檔: 小米產品父類</p>
 *
 * @author 大牧
 * @version V1.0
 */
public interface IXiaomi extends IProduct {
}

具體產品構建

package com.damu.product;

import com.damu.inter.extend.IXiaomi;

/**
 * <p>項目文檔: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class XiaomiGameComputer implements IXiaomi {
    @Override
    public String getInformation() {
        return "小米遊戲本,最佳性價比";
    }
}
--------------------------------------------
package com.damu.product;

import com.damu.inter.extend.IXiaomi;

/**
 * <p>項目文檔: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class XiaomiBusinessComputer implements IXiaomi {
    @Override
    public String getInformation() {
        return "小米商務本,最佳選擇";
    }
}
--------------------------------------------
package com.damu.product;

import com.damu.inter.extend.IDell;

/**
 * <p>項目文檔: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class DellGameComputer implements IDell {
    @Override
    public String getInformation() {
        return "Dell遊戲,Alienware,王者歸來";
    }
}

package com.damu.product;

import com.damu.inter.extend.IXiaomi;

/**
 * <p>項目文檔: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class XiaomiEduComputer implements IXiaomi {
    @Override
    public String getInformation() {
        return "小米學生本,學生黨的福利";
    }
}
--------------------------------------------
package com.damu.product;

import com.damu.inter.extend.IDell;

/**
 * <p>項目文檔: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class DellGameComputer implements IDell {
    @Override
    public String getInformation() {
        return "Dell遊戲,Alienware,王者歸來";
    }
}
--------------------------------------------more.....

測試代碼,使用工廠構建產品過程

package com.damu.main;

import com.damu.factory.GameComputerFactory;
import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.product.XiaomiGameComputer;

/**
 * <p>項目文檔: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class Main {

    public static void main(String[] args) {
        // 創建工廠對象
        GameComputerFactory factory = new GameComputerFactory();

        // 創建小米遊戲本
        IProduct productXiaomi = factory.productXiaomi();
        System.out.println(productXiaomi.getInformation());
        // 創建Dell遊戲本
        IProduct productDell = factory.productDell();
        System.out.println(productDell.getInformation());

        // more....
    }
}

3、 Python實現

"""
抽象工廠模式
"""
import abc


# ------------------------------------------ 接口層
class IFactory(metaclass=abc.ABCMeta):
    """工廠接口"""

    @abc.abstractmethod
    def product(self):
        raise NotImplementedError("該方法必須在子類中實現")


class IProduct(metaclass=abc.ABCMeta):
    """產品抽象接口"""

    def get_information(self):
        raise NotImplementedError("該方法必須在產品子類中實現")


# ------------------------------------------ 抽象層
class DellComputer(IProduct):
    """Dell電腦產品抽象類"""
    pass


class XiaomiComputer(IProduct):
    """小米產品抽象類"""
    pass


# ------------------------------------------ 實現層
class XiaomiGameComputer(IProduct):
    """產品具體:小米遊戲本"""

    def get_information(self):
        print("小米遊戲,品質佳軒")


class DellGameComputer(IProduct):
    """產品具體:Dell遊戲本"""

    def get_information(self):
        print("Dell遊戲,Alienware出擊")


class GameComputerFactory(IFactory):
    """遊戲本工廠處理類"""

    def product(self):
        print("小米遊戲本:product_xiaomi(); Dell遊戲本:product_dell()")

    def product_xiaomi(self):
        return XiaomiGameComputer()

    def product_dell(self):
        return DellGameComputer()

# 其他 具體產品 對應 具體工廠 產品體系和工廠體系保持一致即可


if __name__ == "__main__":
    # 創建工廠對象
    game_factory = GameComputerFactory()

    # 創建具體產品
    xiao_mi = game_factory.product_xiaomi()

    dell = game_factory.product_dell()

    # 打印
    xiao_mi.get_information()
    dell.get_information()

4、 Go實現

package main

import "fmt"

/*************** 接口層 ****************/
type IProduct interface {
	// 抽象產品接口
	GetInformation() string
}

type IFactory interface {
	// 抽象工廠接口
	product() IProduct
}

/*************** 抽象產品層 ****************/
type XiaomiComputer interface {
	IProduct
}

type DellComputer interface {
	IProduct
}

/*************** 具體產品層 ****************/
type XiaomiGameComputer struct {
	XiaomiComputer
}

func (computer XiaomiGameComputer) GetInformation() string {
	return "小米遊戲,品質佳選"
}

type DellGameComputer struct {
	DellComputer
}

func (computer DellGameComputer) GetInformation() string {
	return "Alienware,筆記本中的王者"
}

/*************** 具體工廠層 ****************/
type GameComputerFactory struct {}

func (gameComputerFactory GameComputerFactory) product_xiaomi() IProduct {
	return new(XiaomiGameComputer)
}

func (gameComputerFactory GameComputerFactory) product_dell() IProduct {
	return new(DellGameComputer)
}

/*************** 具體測試 ****************/
func main()  {
	// 創建工廠對象
	gameComputerFactory := new(GameComputerFactory)

	// 創建具體產品
	dellComputer := gameComputerFactory.product_dell()
	fmt.Println(dellComputer.GetInformation())

	xiaomiComputer := gameComputerFactory.product_xiaomi()
	fmt.Println(xiaomiComputer.GetInformation())
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章