抽象工厂, 将工厂抽象出来
工厂方法模式和抽象工厂模式都是创建型设计模式,它们的主要区别在于所创建的对象范围不同。
工厂方法模式(Factory Method)通过让子类实现工厂接口,来决定具体应该创建哪一个产品类的实例对象。它允许我们在不改变现有代码基础上添加新的产品类型,并且可以将具体产品的实现与调用方分离开来。
抽象工厂模式(Abstract Factory)与工厂方法模式类似,也是用于创建一系列相关的对象。不同之处在于,抽象工厂是针对多个产品族而言的,即每个工厂可以创建多种不同类型的产品。这样的话,抽象工厂为创建一组相关或独立的对象提供了一种方式。
工厂方法模式通常只针对一个抽象产品类进行创建,而抽象工厂模式则需要针对多种抽象产品进行创建。
示例为实现切换不同数据库
原程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class User { private int id; public int ID { get {return id;} set {id = ID;} } private string name; public string Name { get {return name;} set {name = value ;} } } class SqlServerUser { public void Insert (User user ) { Console.WriteLine("在SQLServer中增加一条记录" ); } public User GerUser (int id ) { Console.WriteLine("在SQLServer中根据ID获取User表的一条记录" ) return null ; } } User user = new User(); SqlServerUser su = new SqlServerUser(); su.Insert(user); su.GetUser(1 );
工厂方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 interface IUser { void Insert (User user ) ; User GetUser (int id ) ; } class SqlServerUser : IUser { public void Insert (User user ) { Console.WriteLine("在SQLServer中增加一条记录" ); } public User GerUser (int id ) { Console.WriteLine("在SQLServer中根据ID获取User表的一条记录" ) return null ; } } class AccessUser : IUser { public void Insert (User user ) { Console.WriteLine("在Access中增加一条记录" ); } public User GerUser (int id ) { Console.WriteLine("在Access中根据ID获取User表的一条记录" ) return null ; } } interface IFactory { IUser CreateUser () ; } class SqlserverFactory : IFactory { public IUser CreateUser () { return new SqlserverUser(); } } class AccessFactory : IFactory { public IUser CreateUser () { return new AccessUser(); } } User user = new User(); IFactory factory = new SqlserverFactory(); IUser iu = factory.CreateUser(); iu.Insert(user); iu.GetUser(1 );
抽象工厂 工厂方法模式通常只针对一个抽象产品类进行创建,而抽象工厂模式则需要针对多种抽象产品进行创建。
随着表的增多(比如增加一个Department部门表), 需要增加很多类(IDepartment, SqlserverDepartment, AccessDepartment), 还要修改很多类(IFactory, SqlserverFactory, AccessFactory)增加接口函数
简单工厂优化抽象工厂 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class DataAccess { private static readonly string db = "Sqlserver" ; public static IUser CreateUser () { IUser user = null ; switch (db) { case "Sqlserver" : user = new SqlserverUser(); break ; case "Access" : user = new AccessUser(); break ; } return user; } public static IDepartment CreateDepartment () { IDepartment deparement = null ; switch (db) { case "Sqlserver" : deparement = new SqlserverDeparement(); break ; case "Access" : deparement = new AccessDeparement(); break ; } return deparement; } } User user = new User(); Department department = new Department(); IUser iu = DataAccess.CreateUser(); iu.Insert(user); iu.GetUser(1 ); IDepartment id = DataAccess.CreateDepartment(); id.Insert(department); id.GetDepartment(1 );
简单工厂去除了工厂类, 比如但若是增加Oracle数据库的访问, 抽象工厂只需要增加OracleFactory, 简单工厂却需要更改DataAccess类中的case
反射+抽象工厂 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 using System.Reflection;class DataAccess { private static readonly string assemblyName = "抽象工厂模式" ; private static readonly string db = "Sqlserver" ; 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); } } User user = new User(); Department department = new Department(); IUser iu = DataAccess.CreateUser(); iu.Insert(user); iu.GetUser(1 ); IDepartment id = DataAccess.CreateDepartment(); id.Insert(department); id.GetDepartment(1 );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 public interface Shape { void draw () ; } public class Rectangle implements Shape { @Override public void draw () { System.out.println("Inside Rectangle::draw() method." ); } } public class Square implements Shape { @Override public void draw () { System.out.println("Inside Square::draw() method." ); } } public class Circle implements Shape { @Override public void draw () { System.out.println("Inside Circle::draw() method." ); } } public interface Color { void fill () ; } public class Red implements Color { @Override public void fill () { System.out.println("Inside Red::fill() method." ); } } public class Green implements Color { @Override public void fill () { System.out.println("Inside Green::fill() method." ); } } public class Blue implements Color { @Override public void fill () { System.out.println("Inside Blue::fill() method." ); } } public abstract class AbstractFactory { public abstract Color getColor (String color) ; public abstract Shape getShape (String shape) ; } public class ShapeFactory extends AbstractFactory { @Override public Shape getShape (String shapeType) { if (shapeType == null ){ return null ; } if (shapeType.equalsIgnoreCase("CIRCLE" )){ return new Circle (); } else if (shapeType.equalsIgnoreCase("RECTANGLE" )){ return new Rectangle (); } else if (shapeType.equalsIgnoreCase("SQUARE" )){ return new Square (); } return null ; } @Override public Color getColor (String color) { return null ; } } public class ColorFactory extends AbstractFactory { @Override public Shape getShape (String shapeType) { return null ; } @Override public Color getColor (String color) { if (color == null ){ return null ; } if (color.equalsIgnoreCase("RED" )){ return new Red (); } else if (color.equalsIgnoreCase("GREEN" )){ return new Green (); } else if (color.equalsIgnoreCase("BLUE" )){ return new Blue (); } return null ; } } public class FactoryProducer { public static AbstractFactory getFactory (String choice) { if (choice.equalsIgnoreCase("SHAPE" )){ return new ShapeFactory (); } else if (choice.equalsIgnoreCase("COLOR" )){ return new ColorFactory (); } return null ; } } public class AbstractFactoryPatternDemo { public static void main (String[] args) { AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE" ); Shape shape1 = shapeFactory.getShape("CIRCLE" ); shape1.draw(); Shape shape2 = shapeFactory.getShape("RECTANGLE" ); shape2.draw(); Shape shape3 = shapeFactory.getShape("SQUARE" ); shape3.draw(); AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR" ); Color color1 = colorFactory.getColor("RED" ); color1.fill(); Color color2 = colorFactory.getColor("GREEN" ); color2.fill(); Color color3 = colorFactory.getColor("BLUE" ); color3.fill(); } }