抽象工厂, 将工厂抽象出来
工厂方法模式和抽象工厂模式都是创建型设计模式,它们的主要区别在于所创建的对象范围不同。
工厂方法模式(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();    } }