【設計模式】創建型模式之抽象工廠模式(四)
阿新 • • 發佈:2019-04-29
庫類 修改 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 { 20get { 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 Department10 { 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個功能集合,不同的配置【不同的抽象工廠】,組裝成不同配置的電腦【具體的實現類】
【設計模式】創建型模式之抽象工廠模式(四)