abstract factory pattern
抽象工厂模式的定义:提供一个接口,用于创建相关对象或从属对象的族,而不指定它们的具体类
当客户机需要创建以某种方式相关的对象时,此模式非常有用。如果需要创建相关或依赖对象的族,那么可以使用抽象工厂模式。我们可以在这个模式中使用以下类:
AbstractFactory:声明用于创建抽象产品的操作的接口
ConcreteFactory:实现创建具体产品对象的操作
AbstractProduct:声明产品对象类型的接口
产品:定义由相应的具体对象创建的产品对象工厂实现抽象产品接口
客户机:使用AbstractFactory和AbstractProduct类声明的接口
这里是工厂设计模式的实现。
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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | interface IWorst { string Name(); string Cost(); string Millage(); } interface IBest { string Name(); string Cost(); string Millage(); } class Splender : IWorst { public string Name() { return"Splender"; } public string Cost() { return"40000 Rupees"; } public string Millage() { return"70 KM/Lit"; } } class platina : IWorst { public string Name() { return"Platina"; } public string Cost() { return"35000 Rupees"; } public string Millage() { return"90 KM/Lit"; } } class Vector : IWorst { public string Name() { return"Victor Plus"; } public string Cost() { return"38000 Rupees"; } public string Millage() { return"80 KM/Lit"; } } class Shine : IWorst { public string Name() { return"Shine"; } public string Cost() { return"45000 Rupees"; } public string Millage() { return"60 KM/Lit"; } } class Karizma : IBest { public string Name() { return"Karizma ZMR"; } public string Cost() { return"115000 Rupees"; } public string Millage() { return"30 KM/Lit"; } } class Plusar : IBest { public string Name() { return"Plusar 220"; } public string Cost() { return"90000 Rupees"; } public string Millage() { return"35 KM/Lit"; } } class Apache : IBest { public string Name() { return"Apache 200"; } public string Cost() { return"85000 Rupees"; } public string Millage() { return"40 KM/Lit"; } } class CBR : IBest { public string Name() { return"CBR 250"; } public string Cost() { return"125000 Rupees"; } public string Millage() { return"25 KM/Lit"; } } interface iBikeFactory { IBest GetBest(); IWorst GetWorst(); } class HeroFactory : iBikeFactory { public IBest GetBest() { return new Karizma(); } public IWorst GetWorst() { return new Splender(); } } class BajajFactory : iBikeFactory { public IBest GetBest() { return new Plusar(); } public IWorst GetWorst() { return new platina(); } } class TVSFactory : iBikeFactory { public IBest GetBest() { return new Apache(); } public IWorst GetWorst() { return new Vector(); } } class HondaFactory : iBikeFactory { public IBest GetBest() { return new CBR(); } public IWorst GetWorst() { return new Shine(); } } enum MANUFACTURERS { HERO, BAJAJ, TVS, HONDA } class BikeTypeChecker { iBikeFactory factory; MANUFACTURERS manu; public BikeTypeChecker(MANUFACTURERS m) { manu = m; } public void CheckProducts() { switch (manu) { case MANUFACTURERS.HERO: factory = new HeroFactory(); break; case MANUFACTURERS.BAJAJ: factory = new BajajFactory(); break; case MANUFACTURERS.TVS: factory = new TVSFactory(); break; case MANUFACTURERS.HONDA: factory = new HondaFactory(); break; } Console.WriteLine(" "+manu.ToString() +": Best Bike:" + factory.GetBest().Name() +" Cost :" + factory.GetBest().Cost() +" Millage :" + factory.GetBest().Millage()+" Worst Bike:" + factory.GetWorst().Name() +" Cost :" + factory.GetWorst().Cost() + " Millage :" + factory.GetWorst().Millage()); } } class MainApp { static void Main(string[] args) { BikeTypeChecker checker = new BikeTypeChecker(MANUFACTURERS.HERO); checker.CheckProducts(); Console.ReadLine(); checker = new BikeTypeChecker(MANUFACTURERS.BAJAJ); checker.CheckProducts(); Console.ReadLine(); checker = new BikeTypeChecker(MANUFACTURERS.HONDA); checker.CheckProducts(); Console.ReadLine(); checker = new BikeTypeChecker(MANUFACTURERS.TVS); checker.CheckProducts(); Console.Read(); } } |
号
如果您熟悉.NET,请检查DBProviderFactory类。这个类提供了任何数据库访问的抽象。类定义了用于创建数据库连接、数据库命令等的工厂方法。所有这些方法都再次返回常规抽象类型。依赖于特定的数据库服务器/驱动程序返回连接类或命令类的具体实现取决于工厂的具体实现。例如,
考虑使用工厂模式概念的以下简单代码:
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 | #include <iostream> #include <string> using namespace std; // Abstract Base Class class Shape { public: virtual void Draw() = 0; // Static class to create objects // Change is required only in this function to create a new object type static Shape* Create(string type); }; class Circle : public Shape { public: void Draw() { cout <<"I am circle" << endl; } friend class Shape; }; class Square : public Shape { public: void Draw() { cout <<"I am square" << endl; } friend class Shape; }; Shape* Shape::Create(string type) { if ( type =="circle" ) return new Circle(); if ( type =="square" ) return new Square(); return NULL; } void main() { // Give me a circle Shape* obj1 = Shape::Create("circle"); // Give me a square Shape* obj2 = Shape::Create("square"); obj1->Draw(); obj2->Draw(); } OUTPUT: I am circle I am square |
现在想象一下,如果形状类在
您不需要包含这两个文件的原因是,创建
我认为这里的模式是基于一组类。我将它用于类集,这些类通过访问数据库的方式与这些类相关。
所以我会有一个名为nwindabstractFactory的抽象类。这个类将返回IProductReportory和IOrderRepository的两个抽象方法。您不能直接实现任何东西,但是您的业务逻辑是根据这个抽象工厂和接口编程的。
然后我将创建iproductrepository和iorderrepository的具体实现。也许它们被称为sqlproductrepository和sqlorderrepository。然后我可以创建一个抽象工厂的具体实现,它的名称类似于nwindsqlfactory。
也许我会有另一个名为nwindxmlFactory的具体工厂,它可以创建一个xmlProductRepository和xmlOrderRepository。
然后,我可以在运行时决定要使用抽象工厂的哪个实现。可能是nwindsqlFactory或nwindsxmlFactory,甚至可能是nwindaccessFactory。
我再次认为,当您有一组相关的类,但您不想针对它们的具体实现进行编程时,它是有效的。
您可以使用配置设置,该设置将使用反射来实例化您想要的实际实现。你只需要一个设置就可以做到这一点。您只需要指定具体工厂——因为一旦您拥有了具体工厂,它就可以获得所有其他实现。