設計模式學習筆記-抽象工廠模式


1. 概述
  抽象工廠模式為一個產品家族提供了統一的創建接口。當需要這個產品家族的某一系列的時候,可以從抽象工廠中選出相對應的系列來創建一個具體的工廠類別。

2. 抽象工廠模式中的角色

   2.1 抽象工廠(AbstractFactory):擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。

   2.2 具體工廠(ConcreteFactory):這個角色直接在客戶端的調用下創建產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。

   2.3 抽象產品(AbstractProduct):擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的接口。

   2.4 具體產品(ConcreteProduct):抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。

3. 實例:更換數據庫。現有系統使用的是SqlServer數據庫,它的Licence是付費的,有的客戶想使用免費的數據庫服務,如Access。有的客戶擁有其它數據庫服務商的Licence,他們也不想使用還要另付費的SqlServer。

   3.1 解決這個問題的根本是將應用程序與數據庫解耦,使得應用程序不再依賴某一個具體的數據庫。抽象工廠給我們提供了解決方案。

   3.2 實現類圖

    

  3.3 實現代碼

    3.3.1 抽象工廠類,提供了創建一組相關或相互依賴的對象的接口。

    /// <summary>
    /// 抽象工廠類
    /// </summary>
    public interface IDatabaseFactory
    {

        IEmployee CreateEmployee();

        IUser CreateUser();
    }

    3.3.2 具體工廠類,提供了創建SqlServer,或Access具體產品的實現

    /// <summary>
    /// 與SqlServer相關產品的實現
    /// </summary>
    public class SqlServerDatabaseFactory : IDatabaseFactory
    {

        public IEmployee CreateEmployee()
        {

            return new SqlEmployee();
        }

        public IUser CreateUser()
        {

            return new SqlUser();
        }

    }


    /// <summary>
    /// 與Access相關產品的實現
    /// </summary>
    public class AccessDatabaseFactory : IDatabaseFactory
    {

        public IEmployee CreateEmployee()
        {

            return new AccessEmployee();
        }

        public IUser CreateUser()
        {

            return new AccessUser();
        }

    }

    3.3.3 兩個抽象產品,分別是IUser和IEmployee

    /// <summary>
    /// 抽象產品
    /// </summary>
    public interface IUser 
    {
        User GetUser();

        bool SaveUser();
    }

    /// <summary>
    /// 抽象產品
    /// </summary>
    public interface IEmployee
    {

        Employee GetEmployee();

        bool SaveEmployee();
    }

  3.3.4 具體產品的實現

    /// <summary>
    /// 與SqlServer相關的具體產品User
    /// </summary>
    public class SqlUser : IUser
    {
        public User GetUser()
        {

            return null;
        }

        public bool SaveUser()
        {

            return false;
        }

    }

    /// <summary>
    /// 與SqlServer相關的具體產品Employee
    /// </summary>
    public class SqlEmployee : IEmployee
    {

        public SqlEmployee()
        {

        }

        public Employee GetEmployee()
        {

            return null;
        }

        public bool SaveEmployee()
        {

            return false;
        }

    }

    /// <summary>
    /// 與Access相關的具體產品User
    /// </summary>
    public class AccessUser : IUser
    {

        public AccessUser()
        {

        }

        public User GetUser()
        {

            return null;
        }

        public bool SaveUser()
        {

            return false;
        }

    }

    /// <summary>
    /// 與Access相關的具體產品Employee
    /// </summary>
    public class AccessEmployee : IEmployee
    {

        public AccessEmployee()
        {

        }

        public Employee GetEmployee()
        {

            return null;
        }

        public bool SaveEmployee()
        {

            return false;
        }

    }

4. 模式總結

  4.1 優點
    4.1.1 具體產品從客戶代碼中被分離出來
    4.1.2 容易改變產品的系列(如SqlServer產品系列,Access產品系列)
    4.1.3 將一個系列的產品族統一到一起創建

  4.2 缺點
    在產品族中擴展新的產品是很困難的,它需要修改抽象工廠的接口,如增加一種產品Customer變得非常困難。

  4.3 實用范圍
    4.3.1 一個系統要獨立於它的產品的創建、組合和表示時。
    4.3.2 一個系統要由多個產品系列中的一個來配置時。
    4.3.3 當你要強調一系列相關的產品對象的設計以便進行聯合使用時。
    4.3.4 當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM