【抽象工厂模式】
抽象工厂模式是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模型,它提供了一种创建对象的最佳方式
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式的指定他们的类。每个生成的工厂都能按照工厂模式提供对象
【介绍】
-
主要解决:接口选择问题
-
如何解决:在一个产品族里面,定义多个产品
-
关键代码:在一个工厂里聚合多尔衮同类产品
-
优点:1、便于交换产品系列。2、让具体的创建实例过程和客户端分离
-
缺点:产品族拓展困难,要增加一个系列的某一产品,既要在抽象的creator里面增加代码,又要在具体的实例里面增加代码
-
注意事项:产品族难扩展,产品等级易扩展
【实现】
步骤一:用户类
class User
{
private int _id;
public int ID
{
get { return _id; }
set { _id = value; }
}
private int _name;
public int Name
{
get { return _name; }
set { _name = value; }
}
}
class Department
{
private int _id;
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _deptName;
public string DeptName
{
get { return _deptName; }
set { _deptName = value; }
}
}
步骤二:接口类
//IUser接口
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
//IDepartment接口,用于客户端访问,解除与具体数据库访问的耦合
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
步骤三:抽象产品类
class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在SQL中user表中增加一条新纪录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL根据ID得到user表一条纪录");
return null;
}
}
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("给ACCess给user表添加一条新纪录");
}
public User GetUser(int id)
{
Console.WriteLine("根据ID得到user表一条纪录");
return null;
}
}
//AccessUser类,用于访问Access的user
class AccessDepartment:IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("给ACCess给user表添加一条新纪录");
}
public Department GetDepartment (int id)
{
Console.WriteLine("根据ID得到user表一条纪录");
return null;
}
}
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("给ACCess给user表添加一条新纪录");
}
public User GetUser(int id)
{
Console.WriteLine("根据ID得到user表一条纪录");
return null;
}
}
步骤四:抽象工厂接口
i
nterface IFactory
{
IUser CreateUser();
IDepartment CreateDepartment();
}
步骤五:实现产品
class SqlserverFactory:IFactory
{
public IUser CreateUser()
{
return new SqlserverUser ();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}
//accessFacrtory类,实现IFactory接口,实例化Accessuser
class AccessFactory:IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
步骤六:客户端代码
static void Main(string[] args)
{
User user = new User();
IFactory factory = new SqlserverFactory();
Department dept = new Department();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = factory.CreateDepartment();//此时已与具体的数据库访问解除了依赖
id.Insert(dept);
id.GetDepartment(1);
Console.Read();
}
【总结】
反射的格式:Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")
将程序由编译时转为运行时,其中的字符串是可以写成变量,变量取值是由需求来决定的,去除了switch判断的麻烦。