抽象……工厂模式:
提供了一个创建一系列相关或相互依赖对象的接口,不需要指定他们具体的类。
义如其名——抽象,开始读不太懂,但是细读吧,感觉这个定义言简意赅地说明了抽象工厂最大的特点。下面结合结构图来说一下:
AbstractProductA和 AbstractProductB 因为有多种实现所以是抽象产品,书上对这个图解析的也很是到位,感觉很容易理解。代码(后附)中user和department(数据库中的两个表)是两个不相关的产品,他们各有两种实现,客户端实例化某一数据库访问对象 将其赋给接口factory,访问数据库、调用方法。
自己了解还是有很多不足的地方,补两个链接增加一下含金量:
http://blog.youkuaiyun.com/zhengzhb/article/details/7359385
http://blog.youkuaiyun.com/ipqxiang/article/details/1955677
抽象工厂优缺点:
1、接口的存在使产品系列易于交换
2、具体创建实例过程与客户端分离,客户端通过接口操纵实例——开放封闭原则、依赖倒转原则
3、可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。(目前还不是太了解)
4、功能的扩展将是一件十分费力的事情,假如产品中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。
根据抽象工厂的缺点,书中介绍了“反射”技术:反射是一种宽泛的叫法,它通过 System.Reflection 命名空间 并 配合 System.Type 类,提供了在运行时(Runtime)对于 类型和对象(及其成员)的基本信息 以及 元数据(metadata)的访问能力。(链接)利用反射目的是为了指明要实例化的对象。
格式:
Assembly.load(“程序集名称”).CreateInstance(“命名空间.类名称”)
代码:
static void Main(string[] args)
{
User user = new User();
Department dept = new Department();
//实例化哪一个数据库访问对象给factory
//IFactory factory = new SqlServerFactory();
IFactory factory = new AccessFactory();
//与具体数据库访问解除了依赖
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment id = factory.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
Console.Read();
}
}
interface IUser//解除与具体数据库访问的耦合
{
void Insert(User user);
User GetUser(int id);
}
//user字段和属性
class User
{
private int _id;
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
#region
//抽象的工厂接口,访问user表对象
interface IFactory
{
IUser CreateUser();
IDepartment CreateDepartment();
}
// 实现接口,实例化**
class SqlServerFactory : IFactory
{
//具体工厂
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}
// SQL类,插入、得到记录;访问SQL Server
class AccessFactory : IFactory//实现接口,实例化**
{
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
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;
}
}
//接口,用于客户端访问,解除具体数据库访问的耦合
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
//访问sql server的department
class SqlserverDepartment:IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在SQL Server中给Department表添加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到了Department表一条记录");
return null;
}
}
class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Department表添加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到了Department表一条记录");
return null;
}
}
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给user表添加了一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到user表一条记录");
return null;
}
}
//新表
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; }
}
}