1. 程式人生 > >【設計模式】創建型模式之抽象工廠模式(四)

【設計模式】創建型模式之抽象工廠模式(四)

庫類 修改 create 配置 esp 指定 ase sse 種類

抽象工廠模式

提供一個創建一系列相關或相互依賴對象的接口,而無需指定他們的具體的類。

【為創建不同的產品對象,客戶端應使用不同的具體工廠】

通俗理解:我們可以理解成:一臺電腦。最基本的配件:CPU、主板、內存、硬盤【所定義的接口】,不同配置的電腦,則需要不同的類進行實現。

技術分享圖片

舉個例子,數據庫訪問的例子。

定義數據庫類:User、Department

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
6 7 namespace _15抽象工廠模式02 8 { 9 class User 10 { 11 private int _id; 12 public int ID 13 { 14 get { return _id; } 15 set { _id = value; } 16 } 17 private string _name; 18 public string Name 19 { 20
get { return _name; } 21 set { _name = value; } 22 } 23 } 24 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class Department
10 { 11 private int _id; 12 public int ID 13 { 14 get { return _id; } 15 set { _id = value; } 16 } 17 private string _deptname; 18 public string DeptName 19 { 20 get { return _deptname; } 21 set { DeptName = value; } 22 } 23 } 24 }

定義User、Department接口

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     interface IUser
10     {
11         void Insert(User user);
12         User GetUser(int id);
13     }
14 }
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     interface IDepartment
10     {
11         void Inster(Department department);
12         Department GetDepartment(int id);
13     }
14 }

SqlserverUser類,用於訪問SQL Server 的 User

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class SQLServerUser : IUser
10     {
11         public void Insert(User user)
12         {
13             Console.WriteLine("在SQL Server 中給User表增加一條記錄");
14         }
15         public User GetUser(int id)
16         {
17             Console.WriteLine("在SQL Server 中根據ID得到User表一條記錄");
18             return null;
19         }
20     }
21 }

AccessUser類,用於訪問Access的User

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class AccessDepartment : IDepartment
10     {
11         public Department GetDepartment(int id)
12         {
13             Console.WriteLine("在Access 中給Department表增加一條記錄");
14             return null;
15         }
16 
17         public void Inster(Department department)
18         {
19             Console.WriteLine("在Access 中根據ID得到Department表一條記錄");
20         }
21     }
22 }

SQLDepartment類,用於訪問SQL Server 的 Department

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class SQLDepartment : IDepartment
10     {
11         public void Inster(Department department)
12         {
13             Console.WriteLine("在SQL Server 中給Department表增加一條記錄");
14         }
15 
16         public Department GetDepartment(int id)
17         {
18             Console.WriteLine("在SQL Server 中根據ID得到Department表一條記錄");
19             return null;
20         }
21     }
22 }

AccessDepartment 類,用於訪問Access的Department

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class AccessDepartment : IDepartment
10     {
11         public Department GetDepartment(int id)
12         {
13             Console.WriteLine("在Access 中給Department表增加一條記錄");
14             return null;
15         }
16 
17         public void Inster(Department department)
18         {
19             Console.WriteLine("在Access 中根據ID得到Department表一條記錄");
20         }
21     }
22 }

IFactory接口。定義一個創建訪問User、Department 表對象的抽象的工廠接口。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     interface IFactory
10     {
11         IUser CreaterUser();
12         IDepartment CreateDepartment();
13     }
14 }

SqlServerFactory類,實現IFactory,實例化SqlserverUser和SqlserverDepartment

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class SQLFactory : IFactory
10     {
11         public IDepartment CreateDepartment()
12         {
13             return new SQLDepartment();
14         }
15 
16         public IUser CreaterUser()
17         {
18             return new SQLServerUser();
19         }
20     }
21 }

AccessFactory類,實現IFactory接口,實例化AccessUser和AccessDepartMent

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class AccessFactory : IFactory
10     {
11         public IDepartment CreateDepartment()
12         {
13             return new AccessDepartment();
14         }
15 
16         public IUser CreaterUser()
17         {
18             return new AccessUser();
19         }
20     }
21 }

客戶端代碼

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式02
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             User user = new User();
14             Department dept = new Department();
15      
16             IFactory factory = new AccessFactory();
17             IUser iu = factory.CreaterUser();
18             iu.Insert(user);
19             iu.GetUser(1);
20 
21             IDepartment id = factory.CreateDepartment();
22             id.Inster(dept);
23             id.GetDepartment(1);
24 
25             Console.ReadLine();
26         }
27     }
28 }

使用簡單工廠來改進抽象工廠

上面的例子中,每一個類開始都需要 IFactory factory = new AccessFactory(),如果有100個調用數據庫的訪問類,同時就要修改100次 ,IFactory factory = new AccessFactory(),這是非常不合理的

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式03
 8 {
 9     class DataAccess
10     {
11         private static readonly string db = "Access";
12         public static IUser CreateUser()
13         {
14             IUser result = null;
15             switch(db)
16             {
17                 case "SQL":
18                     result = new SQLServerUser();
19                     break;
20                 case "Access":
21                     result = new AccessUser();
22                     break;
23             }
24             return result;
25         }
26 
27         public static IDepartment CreateDepartment()
28         {
29             IDepartment result = null;
30             switch (db)
31             {
32                 case "SQL":
33                     result = new SQLDepartment();
34                     break;
35                 case "Access":
36                     result = new AccessDepartment();
37                     break;
38             }
39             return result;
40         }
41     }
42 }

客戶端代碼

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式03
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             User user = new User();
14             Department dept = new Department();
15             IUser iu = DataAccess.CreateUser();
16             iu.Insert(user);
17             iu.GetUser(1);
18 
19             IDepartment id = DataAccess.CreateDepartment();
20             id.Inster(dept);
21             id.GetDepartment(1);
22             Console.ReadLine();
23         }
24     }
25 }

通過反射+抽象工廠優化數據庫訪問

我們還可以通過反射的方式,進行優化

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Reflection;
 7 
 8 namespace _15抽象工廠模式04
 9 {
10     class DataAccess
11     {
12         private static readonly string AssemblyName = "15抽象工廠模式04"; 
13         private static readonly string db = "SQLServer";
14         public static IUser CreateUser()
15         {
16             string classname = "_" + AssemblyName + "." + db + "User";
17             Assembly s = Assembly.Load(AssemblyName);
18             //Type[] type = s.GetTypes();
19             IUser us = (IUser)Assembly.Load(AssemblyName).CreateInstance(classname); ;
20             return us;
21         }
22 
23         public static IDepartment CreateDepartment()
24         {
25             string classname = "_" + AssemblyName + "." + db + "Department";
26             Assembly s = Assembly.Load(AssemblyName);
27             Type[] type = s.GetTypes();
28             return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(classname);
29         }
30     }
31 }

客戶端代碼

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _15抽象工廠模式04
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             User user = new User();
14             Department dept = new Department();
15             IUser iu = DataAccess.CreateUser();
16             iu.Insert(user);
17             iu.GetUser(1);
18 
19             IDepartment id = DataAccess.CreateDepartment();
20             id.Inster(dept);
21             id.GetDepartment(1);
22             Console.ReadLine();
23         }
24     }
25 }

上述的db字符串。我們也可以通過app.config文件來定義

在使用:ConfigurationManager.AppSettings["db"],來獲取所需要的訪問的數據庫。

簡單工廠、工廠模式、抽象工廠模式的區別

1、簡單工廠模式:由工廠內部指定具體的實例。倉庫指定了只有這幾種道具,你只能根據我告訴你的這幾種類型中去選擇。當你需要道具一的時候,我就給你道具一,如果你需要道具二,而我只能叫你等待:添加新的道具,並放到倉庫中。

2、工廠模式:倉庫不在存放道具,而是直接告訴你有道具(具體是哪一類道具,並沒有說明),這時候你需要道具N,就告訴你去某某道具店拿。

3、抽象工廠模式:可以理解成組裝電腦,可以組裝成N個功能集合,不同的配置【不同的抽象工廠】,組裝成不同配置的電腦【具體的實現類】

【設計模式】創建型模式之抽象工廠模式(四)