定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
优点:1.易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置;
2.让具体的创建实例过程与客户端分离,客户端通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中;
缺点:当增加新功能时,必须做相应类的增加和相应类的修改:比如当增加项目表Project的时候,就至少要增加IProject、SqlseverProject、AccessProject三个类,还要更改IFactory、SqlserverFactory、AccessFactory这三个类才能实现。
使用时机:只有一个User类和User操作类的时候,是只需要工厂方法模式的,但现在显然你数据库中有很多的表,而SQL Server与Access有两大不同的分类,所以解决这种涉及多个产品系列的问题需要用到抽象工厂模式。游戏中例如QQ农场不同系列的建筑生成逻辑。
class Program
{
static void Main(string[] args)
{
//User user = new User() ; //最开始最简单的没有调用设计模式的写法
//SqlserverUser su = new SqlserverUser();
//su.Insert(user);
//su.GetUser(1);
//Console.Read();
//User user = new User(); //第二次改进后的代码 //执行步骤:1.实例化User对象;
//IFactory factory = new SqlserverFactory(); // 2.将继承于IFactory的SqlserverFactory实例化对象传递到factory;
//IUser iu = factory.CreatUser(); // 3.将factory中的方法CreatUser实例后的对象(SqlserverUser())传递给继承的父类IUser的对象iu;
//iu.Insert(user); // 4.iu通过方法Insert调用相应的方法(为了表现使用了User,我在这里传递了User的Name);
//iu.GetUser(1); // 5.iu通过方法GetUser调用相应的方法(这里直接传递了一个Id);
//Console.Read();
//User user = new User(); //第三次改进后的代码,用到抽象工厂模式 //执行步骤:1.实例化User/Department对象;
//Department dept = new Department(); // 2.将继承于IFactory的SqlserverFactory实例化对象传递到factory;
//IFactory factory = new SqlserverFactory();//或者“new AccessFactory();”只需确定实例化哪一个数据库访问对象给factory // 3.将factory.CreatUser()方法获得的对象SqlserverUser()传递给继承的父类IUser的对象iu;
//IUser iu = factory.CreatUser(); // 4.iu通过方法Insert调用相应的方法(为了表现使用了User,我在这里传递了User的Name);
//iu.Insert(user); // 5.iu通过方法GetUser调用相应的方法(这里直接传递了一个Id);
//iu.GetUser(1); // 6.IDepartment 重复3.4.5.步骤
//IDepartment iDerpart = factory.CreatDepartment();
//iDerpart.Insert(dept);
//iDerpart.GetDepartment(1);
//Console.Read();
User user = new User(); //第四次改进后的代码,结合了简单工厂;第五次改进后使用反射实现 //执行步骤:1.实例化User/Department对象,并将Name添加相应值;
user.Name = "毛毛都的无聊生活 "; // 2.通过DataAccess.CreatUser()和DataAccess.CreatDepartment()获得的对象传递【注意第五次改进后用到的反射方法,很方便】
Department dept = new Department(); // 3.执行iu所获得对象里面的Insert和GetUser方法
dept.Name = "毛毛都的无聊生活 "; // 4.执行idept所获得对象里面的Insert和GetUser方法
IUser iu = DataAccess.CreatUser();
iu.Insert(user);
iu.GetUser(1);
IDepartment idept = DataAccess.CreatDepartment();
idept.Insert(dept);
idept.GetDepartment(1);
Console.Read();
}
}
interface IFactory
{
IUser CreatUser();
IDepartment CreatDepartment();
}
class SqlserverFactory:IFactory
{
public IUser CreatUser()
{
return new SqlserverUser();
}
public IDepartment CreatDepartment()
{
return new SqlserverDepartment();
}
}
class AccessFactory:IFactory
{
public IUser CreatUser()
{
return new AccessUser();
}
public IDepartment CreatDepartment()
{
return new AccessDepartment();
}
}
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; }
}
}
//class SqlserverUser //跟上面类的配套初始写法
//{
// public void Insert(User user)
// {
// Console.WriteLine("在SQL Server中给User表增加一条记录");
// }
// public User GetUser(int id)
// {
// Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
// return null;
// }
//}
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
class SqlserverUser:IUser
{
List<User> users = new List<User>();
public void Insert(User user)
{
users.Add(user);
Console.WriteLine("在SQL Server中给User表增加一条记录[{0}]",user.Name);
}
public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID[{0}]得到User表一条记录",id);
User date = users[id];
if (date != null)
{
return date;
}
return null;
}
}
class AccessUser:IUser
{
List<User> users = new List<User>();
public void Insert(User user)
{
users.Add(user);
Console.WriteLine("在Access中给User表增加一条记录[{0}]", user.Name);
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID[{0}]得到User表一条记录", id);
User date = users[id];
if (date != null)
{
return date;
}
return null;
}
}
class Department
{
private int id;
public int ID
{
get { return id; }
set { id = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
class SqlserverDepartment:IDepartment
{
List<Department> departments = new List<Department>();
public void Insert(Department department)
{
departments.Add(department);
Console.WriteLine("在SQL Server中给User表增加一条记录[{0}]", department.Name);
}
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID[{0}]得到User表一条记录", id);
if (departments[id] != null)
return departments[id];
return null;
}
}
class AccessDepartment : IDepartment
{
List<Department> departments = new List<Department>();
public void Insert(Department department)
{
departments.Add(department);
Console.WriteLine("在Access中给User表增加一条记录[{0}]", department.Name);
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID[{0}]得到User表一条记录", id);
if (departments[id] != null)
return departments[id];
return null;
}
}
class DataAccess
{
//private static readonly string db = "Sqlserver";//或者"Access" 数据库名称
//public static IUser CreatUser()
//{
// IUser result = null;
// switch (db)
// {
// case "Sqlserver":
// result = new SqlserverUser();
// break;
// case "Access":
// result = new AccessUser();
// break;
// }
// return result;
//}
//public static IDepartment CreatDepartment()
//{
// IDepartment result = null;
// switch (db)
// {
// case "Sqlserver":
// result = new SqlserverDepartment();
// break;
// case "Access":
// result = new AccessDepartment();
// break;
// }
// return result;
//}
//第五次改进,应用反射时的写法--------所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断带来的耦合
private static readonly string AssemblyName = "抽象工厂模式";
private static readonly string db = "Sqlserver";//或者“Access”,如果此时需要增加“Oracle”数据访问,就将其换成这个就行了
public static IUser CreatUser()
{
string className = AssemblyName + "." + db + "User";
return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
}
public static IDepartment CreatDepartment()
{
string className = AssemblyName + "." + db + "Department";
return (IDepartment )Assembly.Load(AssemblyName).CreateInstance(className);
}
}
转载请注明出处!!!
欢迎加入951815219群聊,共享知识,讨论交流~