【设计模式】创建型模式之抽象工厂模式(四)

抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体的类。

 【为创建不同的产品对象,客户端应使用不同的具体工厂】

通俗理解:我们可以理解成:一台电脑。最基本的配件: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个功能集合,不同的配置【不同的抽象工厂】,组装成不同配置的电脑【具体的实现类】

猜你喜欢

转载自www.cnblogs.com/YHeng/p/10780770.html