三大工廠設計模式的演變與優缺點思考


以前都是以記錄筆記的方式寫很短的隨筆;然而這一次比較長,由於時間,表達能力,理解能力有限,肯定有很多不完整和錯誤的地方,請各位多多包含,后期會不斷完善和修改;謝謝!

三大工廠模式:簡單工廠模式,工廠方法模式,抽象工廠模式

我們先來舉例子,比如我們要從SQLServer數據庫獲取與新增Department。

面向過程編程: 

static void Main(string[] args)
{
    try
    {
        Console.Write("請輸入數字Get or Insert:");
        string strOperation=Console.ReadLine();
        switch(strOperation)
        {
            case "Get": 
          Console.WriteLine("在SQL Server中給Department表增加一條記錄");
           break; case "Insert":
          Console.WriteLine("在SQL Server中根據ID得到給Department表一條記錄");
          break; } } catch(Exception e) { Console.WriteLine("程序出現異常:"+e.Message); } }

 

但以上代碼修改時會牽一發而動全身,很可能牽扯到其他不應該修改的代碼,如果代碼長的話進行維護時甚至自己都不認識,而且代碼的復用性也不高。這時面向對象編程就起到了作用。所以我們需要對代碼進行封裝。

面向對象方法設計就是用封裝,繼承,多態來實現代碼的可維護,可擴展,可復用,靈活性好。

面向對象編程,對界面與業務的分離

public class Department
{        
        public static string GetResult(string strOperation)
        {
            string result=string.Empty;
            switch(strOperation)
            {
                 case "Insert": result = "在SQL Server中給Department表增加一條記錄"; 
                   break; case "Get": result = "在SQL Server中根據ID得到給Department表一條記錄";
                    break; } return result; } } public class Program {    static void Main(string[] args)    { try { Console.Write("請輸入數字Insert or Get:"); string strOperation=Console.ReadLine(); string strResult = Department.GetResult(strOperation); Console.WriteLine(strResult); } catch(Exception e) { Console.WriteLine("程序出現異常:"+e.Message); } } }

 但是,這時,如果我們需要對業務中新增其他功能,如刪除,那就會對修改開放了,違背了“開放-封閉”原則:只能對擴展開放,而不能對修改開放。所以我們需要對操作進行分離和封裝,並且使用接口,它的好處就是讓功能的定義與實現分離,這樣對於用戶來說,他們以相同的方式調用接口,而卻有不同的實現方式。所以我繼續對業務層進行分離.

 
         
public class Department
    {
        public string strResult = string.Empty;
        public virtual string GetResult()
        {               
               return strResult;
        }
    }
    class InsertSqlserverDepartment : Department
    {
         public override string GetResult()
         {
             strResult = "在SQL Server中給Department表增加一條記錄";
             return strResult;
         }
    }
    class GetSqlserverDepartment : Department
    {
         public override string GetResult()
         {
             strResult = "在SQL Server中根據ID得到給Department表一條記錄";
             return strResult;
         }
    }

    public class Program 
    {
       static void Main(string[] args)
       {
           //Console.WriteLine("請輸入你所要的操作,Insert or Get");
           //string strOperation = Console.ReadLine();
           Department oper;
           oper = new GetSqlserverDepartment();
           string strResult = oper.GetResult();
           Console.WriteLine(strResult);
           Console.ReadLine();
          }
     }      
 
         
但是我想根據客戶端的選擇條件動態實例化相關的類

1.簡單工程模式

public class Department
    {
        public string strResult = string.Empty;
        public virtual string GetResult()
        {               
               return strResult;
        }
    }
    class InsertSqlserverDepartment : Department
    {
         public override string GetResult()
         {
             strResult = "在SQL Server中給Department表增加一條記錄";
             return strResult;
         }
    }
    class GetSqlserverDepartment : Department
    {
         public override string GetResult()
         {
             strResult = "在SQL Server中根據ID得到給Department表一條記錄";
             return strResult;
         }
    }
    public class DepartmentFactory
    {
        public static Department createDepartmentOperation(string type)
        {
            Department dept = null;
            switch (type)
            {
                case "Insert": dept = new InsertSqlserverDepartment(); break;
                case "Get": dept = new GetSqlserverDepartment(); break;
            }
            return dept;
        }
    }
 
    public class Program 
    {
       static void Main(string[] args)
       {
           Console.WriteLine("請輸入你所要的操作,Insert or Get");
           string strOperation = Console.ReadLine();
           Department oper;
           oper =DepartmentFactory.createDepartmentOperation(strOperation);
           string strResult = oper.GetResult();
           Console.WriteLine(strResult);
           Console.ReadLine();
          }
     }        

 這里我們的代碼已經達到了"高內聚,低耦合".但在后期擴展維護方面可能還會有問題,這里我們只是操作SQL Server數據庫,以后我們可能操作不同數據庫的同一個產品,此時就要添加另一種數據操作類了,以下的模式就派上用場了。

2.工廠方法模式

 

class Department
    {
        public int ID{get;set;}
        public int DeptName{get;set;}
    }

    interface IDepartment
    {
        void Insert(Department dept);
        Department GetDepartment(int id);
    }
    class SqlserverDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在SQL Server中給Department表增加一條記錄");
        }
        public void GetDepartment(int id)
        {
            Console.WriteLine("在SQL Server中根據ID得到給Department表一條記錄");
        }
    }
    class OracleDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在Oracle中給Department表增加一條記錄");
        }
        public void GetDepartment(int id)
        {
            Console.WriteLine("在Oracle中根據ID得到給Department表一條記錄");
        }
    }
    interface IFactory
    {
        IDepartment CreateDepartment();
    }
    class SqlServerFactory : IFactory
    {
       
        public IDepartment CreateDepartment()
        {
            return new SqlserverDepartment();
        }
    }
    class OracleFactory : IFactory
    {
       
        public IDepartment CreateDepartment()
        {
            return new OracleDepartment();
        }
    }
    public class Program 
    {
       static void Main(string[] args)
       {         
           Department dept = new Department();
           //IFactory factory = new SqlServerFactory();
           IFactory factory = new OracleFactory();

           IDepartment idept = factory.CreateDepartment();
           idept.Insert(dept);
           idept.GetDepartment(1);

           Console.ReadLine();
          }
 }      

以上的代碼我就實現了對不同數據庫的操作,當我們想要改變數據庫時,我們只需要在客戶端初始化時告訴他們就可以了,其他地方的代碼都不需要改變了.是不是很強大,哈哈.

但這里還會有變動的地方,因為我們數據庫一般不只是操作一張表,很可能還會多張表,比如用戶表,那我們繼續添加,這里就有了以下的設計模式

3.抽象工廠模式

  class Department
    {
        public int ID{get;set;}
        public int DeptName{get;set;}
    }
    class User
    {
        public int ID { get; set; }
        public int UserName { get; set; }
    }
    interface IDepartment
    {
        void Insert(Department department);
        Department GetDepartment(int id);
    }
    interface IUser
    {
        void Insert(User user);
        User GetUser(int id);
    }
    class SqlserverDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在SQL Server中給Department表增加一條記錄");
        }
        public void GetDepartment(int id)
        {
            Console.WriteLine("在SQL Server中根據ID得到給Department表一條記錄");
        }
    }
    class OracleDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在Oracle中給Department表增加一條記錄");
        }
        public void GetDepartment(int id)
        {
            Console.WriteLine("在Oracle中根據ID得到給Department表一條記錄");
        }
    }
    class SqlserverUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在SQL Server中給User表增加一條記錄");
        }
        public void GetDUser(int id)
        {
            Console.WriteLine("在SQL Server中根據ID得到給User表一條記錄");
        }
    }
    class OracleUser : IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在Oracle中給User表增加一條記錄");
        }
        public void GetUser(int id)
        {
            Console.WriteLine("在Oracle中根據ID得到給User表一條記錄");
        }
    }
    interface IFactory
    {
        IUser CreateUser();
        IDepartment CreateDepartment();
    }
    class SqlServerFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new SqlserverUser();
        }
        public IDepartment CreateDepartment()
        {
            return new SqlserverDepartment();
        }
    }
    class OracleFactory : IFactory
    {
        public IUser CreateUser()
        {
            return new OracleUser();
        }
        public IDepartment CreateDepartment()
        {
            return new OracleDepartment();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            Department dept = new Department();
            //IFactory factory = new SqlServerFactory();
            IFactory factory = new OracleFactory();

            IUser iu = factory.CreateUser();
            iu.Insert(user);
            iu.GetUser(1);

            IDepartment idept = factory.CreateDepartment();
            idept.Insert(dept);
            idept.GetDepartment(1);

            Console.ReadLine();
        }
    }

 

總結:

簡單工廠模式:他的最大優點就是在於工廠類包含了必要的邏輯判斷,根據客戶端的選擇條件動態實例化相關的類,對於客戶端來說,去除了與具體產品的依賴,當算法比較穩定,一般不會對它進行新增,或刪除等就適合用詞模式;否則就會違背了“開放-封閉”原則

工廠方法模式:它定義了用於創建對象的接口,讓子類決定實例化哪一個類,工廠方法使一個類的實例化延遲到其子類。

抽象方法模式:當產品有不同的系列,而不同的系列又有不同的創建方式,此時就適合用此模式

 

本人文筆表達有限,如有不到位的地方,還請包涵,如有解決你的問題,請轉發或點贊,謝謝。

本人聯系方式:

                更多精彩分享,可關注我的微信公眾號:

                                    

                 微信號:WeixinJungle

              

                 郵箱:oneou6688@163.com


免責聲明!

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



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