参与者
AbstractFactory3)定义可扩展的工厂 AbstractFactory通常为每一种它可以生产的产品定义一个操作。产品的种类被编码在操作型构中。增加一种新的产品要求改变AbstractFactory的接口以及所有与它相关的类。一个更灵活但不太安全的设计是给创建对象的操作增加一个参数。该参数指定了将被创建的对象的种类。它可以是一个类标识符、一个整数、一个字符串,或其他任何可以标识这种产品的东西。
工厂方法
在抽象工厂中使用工厂方法
代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory { public interface IFactory { IUser CreateeUser(); IDepartment CreateDepartment(); } public class SqlserverFactory : IFactory { public IUser CreateeUser() { return new SqlserverUser(); } public IDepartment CreateDepartment() { return new SqlserverDepartment(); } } public class AccessFactory : IFactory { public IUser CreateeUser() { return new AccessUser(); } public IDepartment CreateDepartment() { return new AccessDepartment(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory { public interface IUser { void Insert(string user); string GetUser(int id); } public class SqlserverUser : IUser { public void Insert(string user) { Console.WriteLine("在SQL server中给User表增加一条记录"); } public string GetUser(int id) { Console.WriteLine("在SQL server中根据ID得到User表一条记录"); return null; } } public class AccessUser : IUser { public void Insert(string user) { Console.WriteLine("在Access中给User表增加一条记录"); } public string GetUser(int id) { Console.WriteLine("在Access中根据ID得到User表一条记录"); return null; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory { public interface IDepartment { void Insert(string dapartment); string GetDepartment(int id); } public class SqlserverDepartment : IDepartment { public void Insert(string dapartment) { Console.WriteLine("在SQL server中给Department表增加一条记录"); } public string GetDepartment(int id) { Console.WriteLine("在SQL server中根据ID得到Department表一条记录"); return null; } } public class AccessDepartment : IDepartment { public void Insert(string dapartment) { Console.WriteLine("在Access中给Department表增加一条记录"); } public string GetDepartment(int id) { Console.WriteLine("在Access中根据ID得到Department表一条记录"); return null; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory { class Program { static void Main(string[] args) { string user = "user"; string dept = "Department"; IFactory factory = new AccessFactory(); // 实例化工厂 IUser iu = factory.CreateeUser(); // 实例化产品 iu.Insert(user); iu.GetUser(1); IDepartment id = factory.CreateDepartment(); // 实例化产品 id.Insert(dept); id.GetDepartment(1); Console.ReadKey(); } } }(C#) 在使用简单工厂的地方,可以考虑用 反射技术 来去除switch或if,解除分支判断带来的耦 合。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Configuration; namespace MyAbstractFactory2 { // class DataAccess // 简单工厂 // { // //private static readonly string db = "Sqlserver"; // private static readonly string db = "Access"; // // public static IUser CreateUser() // { // IUser result = null; // switch (db) // { // case "Sqlserver": // result = new SqlserverUser(); // break; // case "Access": // result = new AccessUser(); // break; // } // return result; // } // // public static IDepartment CreateDepartment() // { // IDepartment result = null; // switch (db) // { // case "Sqlserver": // result = new SqlserverDepartment(); // break; // case "Access": // result = new AccessDepartment(); // break; // } // return result; // } // } class DataAccess // 利用反射 { private static readonly string assemblyName = "MyAbstractFactory2"; // private static readonly string db = "Sqlserver"; // 可以放到配置文件中 private static readonly string db = ConfigurationManager.AppSettings["DB"]; public static IUser CreateUser() { string className = assemblyName + "." + db + "User"; return (IUser)Assembly.Load(assemblyName).CreateInstance(className); } public static IDepartment CreateDepartment() { string className = assemblyName + "." + db + "Department"; return (IDepartment)Assembly.Load(assemblyName).CreateInstance(className); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory2 { public interface IUser { void Insert(string user); string GetUser(int id); } public class SqlserverUser : IUser { public void Insert(string user) { Console.WriteLine("在SQL server中给User表增加一条记录"); } public string GetUser(int id) { Console.WriteLine("在SQL server中根据ID得到User表一条记录"); return null; } } public class AccessUser : IUser { public void Insert(string user) { Console.WriteLine("在Access中给User表增加一条记录"); } public string GetUser(int id) { Console.WriteLine("在Access中根据ID得到User表一条记录"); return null; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory2 { public interface IDepartment { void Insert(string dapartment); string GetDepartment(int id); } public class SqlserverDepartment : IDepartment { public void Insert(string dapartment) { Console.WriteLine("在SQL server中给Department表增加一条记录"); } public string GetDepartment(int id) { Console.WriteLine("在SQL server中根据ID得到Department表一条记录"); return null; } } public class AccessDepartment : IDepartment { public void Insert(string dapartment) { Console.WriteLine("在Access中给Department表增加一条记录"); } public string GetDepartment(int id) { Console.WriteLine("在Access中根据ID得到Department表一条记录"); return null; } } }
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="DB" value="Sqlserver"/> </appSettings> </configuration>
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyAbstractFactory2 { class Program { static void Main(string[] args) { string user = "user"; string dept = "Department"; IUser iu = DataAccess.CreateUser(); // 简单工厂 iu.Insert(user); iu.GetUser(1); IDepartment id = DataAccess.CreateDepartment(); id.Insert(dept); id.GetDepartment(1); Console.ReadKey(); } } }