设计模式(3): 抽象工厂模式(Abstract Factory)
抽象工厂模式(Abstract Factory)
- 概述
- 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类. 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时由于需求的变化,往往存在着更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
-
抽象工厂模式(abstract Factory)结构图
-
- 以“新增用户”和“得到用户”为例。用户类,假设只有ID和Name两个字段
-
Code
- 常规做法:
-
Code
- 客户端代码:
-
Code
- 若要增加一个数据库Access 就会很那麻烦。在此运用抽象工厂模式:
-
- 添加IUser接口,用于客户端访问,解除与具体数据库访问的耦合.
-
interface IUser
{
void insert(User user);
User GetUser(int id);
} - SqlserverUser类,用于访问SQL Server的User.
-
class SqlserverUser:IUser
{
public void Insert(User user)
{
Console.WriteLine("在SQL Server中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
} - AccessUser类,用于访问Access的User.
-
class AccessUser:IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
public User getUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
} - IFactory接口,定义一个创建访问User表对象的抽象的工厂接口。
-
interface IFactory
{
IUser CreateUser();
} - SqlserverFactory类,实现IFactory接口,实例化SqlserverUser。
-
class SqlserverFactory:IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
} - AccessFactory类,实现IFactory接口,实例化AccessUser/
-
class AccessFactory:IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
} - 抽象工厂模式客户端代码:
-
static void Main(string[] args)
{
User user=new User();
IFactory factory=new SqlserverFctory();
//IFactory factory=new AccessFctory();
IUser iu=factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
} - 用DataAccess类代替IFatory ,sqlserverFactory和AccessFactiry三个工厂类
-
-
class DataAccess
{
private static readonly string db="Sqlserver";
//private static readonly string db="Access";
public static IUser CreateUser()
{
IUser result=null;
swith(db)
{
case"Sqlserver":
result=new SqlserverUser();
return result;
break;
case"Access":
result=new AccessUser();
return result;
break;
}
return result;
}
} - 客户端代码:
-
static void Main()
{
User user=new User();
IUser iu=DataAccess.CreateUser();
iu.Insert(user);
iu.Getuser(1);
} - 运用反射对DataAccess进行改进,消除swith:
反射技术的格式:Assembly.Load("程序集名称").CreateInstance("命名空间.类名称") -
using System.Reflection;
class DataAccess
{
private static readonly string AssemblyName="抽象工厂模式";
private static readonly string db="Sqlserver";
// private static readonly string db="Access";
public static IUser CreateUser()
{
string className=Assembly+"."+db+"User";
return (IUser)Assembly.load(AssemblyName).CreateInstance(className); //运用反射
}
} - 客户端代码:
-
static void Main(string[] args)
{
User user=new User();
Iuer iu=DataAccess.CreateUser();
iu.insert(user);
iu.GetUser(1);
Console.Read();
}