Design patterns 设计模式:抽象工厂与工厂方法
注:问题在文章末尾 我已经阅读了其他有关抽象工厂与工厂方法的stackoverflow线程。我理解每种模式的意图。但是,我不清楚这个定义 工厂方法定义了一个接口 用于创建对象,但让 子类决定选择哪一个 实例化。工厂方法允许 类将实例化推迟到 子类 相比之下,抽象工厂 提供一个用于创建 亲属或依亲家庭 对象而不指定其 具体课程 - 抽象工厂看起来非常类似于工厂方法。我画了几个UML类来说明我的观点 注:Design patterns 设计模式:抽象工厂与工厂方法,design-patterns,language-agnostic,uml,factory-method,abstract-factory,Design Patterns,Language Agnostic,Uml,Factory Method,Abstract Factory,注:问题在文章末尾 我已经阅读了其他有关抽象工厂与工厂方法的stackoverflow线程。我理解每种模式的意图。但是,我不清楚这个定义 工厂方法定义了一个接口 用于创建对象,但让 子类决定选择哪一个 实例化。工厂方法允许 类将实例化推迟到 子类 相比之下,抽象工厂 提供一个用于创建 亲属或依亲家庭 对象而不指定其 具体课程 - 抽象工厂看起来非常类似于工厂方法。我画了几个UML类来说明我的观点 注: 该图来自www.yuml.com,因此它们没有完全定向。但这是一项免费服务:) 这些图表可能
- 该图来自www.yuml.com,因此它们没有完全定向。但这是一项免费服务:)
- 这些图表可能并不完美。我仍在学习GoF的设计模式
这两种模式当然是相关的 模式之间的区别通常在于意图 工厂方法的意图是“定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法让类将实例化推迟到子类。” 抽象工厂的意图是“提供一个接口,用于创建相关或从属对象的族,而无需指定它们的具体类。” 纯粹基于这些意图陈述(引自GoF),我想说的是,实际上工厂方法在某种意义上是一个“退化的”抽象工厂,有一个家族 它们通常在实现上有所不同,因为工厂方法比抽象工厂简单得多 然而,它们在实施中也有关联。正如GoF的书中提到的 AbstractFactory仅声明用于创建产品的接口。实际创建它们取决于具体的产品子类。最常见的方法是为每个产品定义一个工厂方法
这也有一些关于这个话题的有趣的讨论。希望这有帮助。它描述了各种类型的工厂。我用这本书作为参考书。我过去常画图表 静态工厂 是一个使用静态方法生成各种子类型产品的类 简单工厂 是一个可以生成各种子类型产品的类。(比静态工厂更好。添加新类型时,基本产品类不需要更改,只需更改简单的工厂类) 工厂方法 包含一种方法来生成与其类型相关的一种产品类型。(它比简单工厂好,因为类型被推迟到子类。) 抽象工厂 生成相关的类型族。它与工厂方法明显不同,因为它有多种类型的方法。(这很复杂,请参阅下一个图表以了解更好的实际示例) 来自.NET框架的示例 DbFactoriesProvider是一个简单的工厂,因为它没有子类型。DbFactoryProvider是一个抽象工厂,因为它可以创建各种相关的数据库对象,例如连接和命令对象
如果我创建了一个抽象(通过接口或抽象基类引用)工厂类,该类创建的对象只有一个方法来创建对象,那么它将是一个工厂方法 如果抽象工厂有多个方法来创建对象,那么它将是一个抽象工厂 假设我制作了一个管理器,它将处理MVC控制器的动作方法需求。 如果它有一种方法,比如说创建用于创建视图模型的引擎对象,那么它将是一种工厂方法模式。 另一方面,如果它有两种方法:一种是创建视图模型引擎,另一种是创建动作模型引擎(或者任何你想调用动作方法包含消费者的模型的方法),那么它将是一个抽象工厂
public ActionResult DoSomething(specific actionmodel)
{
var actionModelEngine=manager.GetActionModelEngine();
actionModelEngine.Execute(SpecificActionModelEnum.Value);
var viewmodelnengine=manager.getviewmodelnengine();
返回视图(viewModelEngine.GetViewModel(SpecificViewModelEnum.Value);
}
就我理解抽象工厂和工厂方法定义的含义而言,第一个定义是在静态上下文中实现的,并基于输入参数提供对象
第二种方法使用已经创建的对象(族),它实现了工厂方法接口。工厂方法然后创建与原始对象相关的特定实例
/*
//Factory methods:
//1. Factory Method - Abstract Creator Class
#include <iostream>
#include <string.h>
using namespace std;
const std::string nineNintyCC = std::string("990CC");
const std::string thousandTwoHundredCC = std::string("1200CC");
const std::string ThousandFiveHundredCC = std::string("1500CC");
const std::string fiveThousandCC = std::string("5000CC");
// Product
class Engine
{
public:
virtual void packEngine() = 0;
};
// Concrete products
// concrete product class one
class C990CCEngine: public Engine
{
public:
void packEngine()
{
cout << "Pack 990CC engine" << endl;
}
};
// concrete class Two
class C1200CCEngine: public Engine
{ public:
void packEngine()
{
cout << "pack 1200CC engine" << endl;
}
};
// Concrete class Three
class C1500CCEngine: public Engine
{
public:
void packEngine()
{
cout << "Pack 1500CC engine" << endl;
}
};
// Car Factory:
class CarFactory{
public:
virtual Engine* createEngine(const std::string& type) = 0;
};
class Factory: public CarFactory
{
public:
Engine *createEngine(const std::string& type)
{
if(0 == nineNintyCC.compare(type))
{
return new C990CCEngine;
}
else if(0 == thousandTwoHundredCC.compare(type))
{
return new C1200CCEngine;
}
else if(0 == ThousandFiveHundredCC.compare(type))
{
return new C1500CCEngine;
}
else
{
cout << "Invalid factory input" << endl;
return NULL;
}
return NULL;
}
};
int main()
{
CarFactory* ptr = new Factory;
Engine*pEngine = ptr->createEngine(nineNintyCC);
if(pEngine)
{
pEngine->packEngine();
delete pEngine;
}
else
{
cout << "No engine exists of your type in our factory" << endl;
}
pEngine = ptr->createEngine(ThousandFiveHundredCC);
if(pEngine)
{
pEngine->packEngine();
delete pEngine;
}
else
{
cout << "No engine exists of your type in our factory" << endl;
}
pEngine = ptr->createEngine(thousandTwoHundredCC);
if(pEngine)
{
pEngine->packEngine();
delete pEngine;
}
else
{
cout << "No engine exists of your type in our factory" << endl;
}
pEngine = ptr-> createEngine(fiveThousandCC);
if(pEngine)
{
pEngine->packEngine();
delete pEngine;
}
else
{
cout << "No engine exists of your type in our factory" << endl;
}
return 0;
}
*/
/*
//
// interface product
#include <iostream>
#include <string>
using namespace std;
class Engine
{
public:
virtual void EngineType() = 0;
};
// concrte product
class AltoEngine: public Engine
{
public:
void EngineType()
{
cout << "Alto Engine" << endl;
}
};
//Concrte product
class SwiftEngine : public Engine
{
public:
void EngineType()
{
cout << "Swift Engine" << endl;
}
};
class Body
{
public:
virtual void bodyType() = 0;
};
class AltoBody: public Body
{
public:
virtual void bodyType()
{
cout << "Alto Car Body" << endl;
}
};
class SwiftBody : public Body
{
public:
void bodyType()
{
cout << "SwiftCar Body" << endl;
}
};
class CarFactory
{
public:
virtual Engine* createEngineProduct() = 0;
virtual Body* createBodyPoduct() = 0;
};
class AltoCarFactory: public CarFactory
{
public:
Engine * createEngineProduct()
{
return new AltoEngine;
}
Body* createBodyPoduct()
{
return new AltoBody;
}
};
class SwiftCarFactory: public CarFactory
{
public:
Engine * createEngineProduct()
{
return new SwiftEngine;
}
Body* createBodyPoduct()
{
return new SwiftBody;
}
};
int main()
{
CarFactory* pAltoFactory = new AltoCarFactory;
Engine* pAltoEngine = pAltoFactory->createEngineProduct();
pAltoEngine->EngineType();
Body* pAltoBody = pAltoFactory->createBodyPoduct();
pAltoBody->bodyType();
CarFactory* pSwiftFactory = NULL;
pSwiftFactory = new SwiftCarFactory;
Engine* pSwiftEngine = pSwiftFactory->createEngineProduct();
pSwiftEngine->EngineType();
Body* pSwfitBody = pSwiftFactory->createBodyPoduct();
pSwfitBody->bodyType();
delete pAltoBody;
delete pAltoFactory;
delete pSwfitBody;
delete pSwiftFactory;
return 0;
}
*/
/*
// One more Factory example;
#include <iostream>
#include <string>
using namespace std;
const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");
// Interface
class CarEngine
{
public:
virtual void engineType() = 0;
};
// Concrete class
class FiatEngine: public CarEngine
{
public:
void engineType()
{
cout << "Fait Engine Engine" << endl;
}
};
// ConcreteClass
class RenaultEngine : public CarEngine
{
public:
void engineType()
{
cout << "Renault Engine" << endl;
}
};
// Concrete class
class MaruthiEngine : public CarEngine
{
public:
void engineType()
{
cout << "Maruthi Engine" << endl;
}
};
// Factory
class CarFactory
{
public:
virtual CarEngine* createFactory(const std::string&) = 0;
};
// EngineFactory
class CarEngineFactory : public CarFactory
{
public:
CarEngine* createFactory(const std::string& type)
{
if(0 == maruthi.compare(type))
{
return new MaruthiEngine;
}
else if(0 == fiat.compare(type))
{
return new FiatEngine;
}
else if(0 == renault.compare(type))
{
return new RenaultEngine;
}
else
{
cout << "Invalid Engine type" << endl;
return NULL;
}
}
};
int main()
{
CarFactory* pCarFactory = new CarEngineFactory;
CarEngine* pMaruthiCarEngine = pCarFactory->createFactory(maruthi);
pMaruthiCarEngine->engineType();
CarEngine* pFiatCarEngine = pCarFactory->createFactory(fiat);
pFiatCarEngine->engineType();
CarEngine* pRenaultCarEngine = pCarFactory->createFactory(renault);
pRenaultCarEngine->engineType();
return 0;
}
*/
/*
// One more Factory example;
#include <iostream>
#include <string>
using namespace std;
const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");
// Interface
class CarEngine
{
public:
virtual void engineType() = 0;
};
// Concrete class
class FiatEngine: public CarEngine
{
public:
void engineType()
{
cout << "Fait Car Engine" << endl;
}
};
// ConcreteClass
class RenaultEngine : public CarEngine
{
public:
void engineType()
{
cout << "Renault Car Engine" << endl;
}
};
// Concrete class
class MaruthiEngine : public CarEngine
{
public:
void engineType()
{
cout << "Maruthi Car Engine" << endl;
}
};
// Interface
class CarBody
{
public:
virtual void bodyType() = 0;
};
// Concrete class
class FiatBody: public CarBody
{
public:
void bodyType()
{
cout << "Fait car Body" << endl;
}
};
// ConcreteClass
class RenaultBody : public CarBody
{
public:
void bodyType()
{
cout << "Renault Body" << endl;
}
};
// Concrete class
class MaruthiBody : public CarBody
{
public:
void bodyType()
{
cout << "Maruthi body" << endl;
}
};
// Factory
class CarFactory
{
public:
virtual CarEngine* createCarEngineProduct() = 0;
virtual CarBody* createCarBodyProduct() = 0;
};
// FiatFactory
class FaitCarFactory : public CarFactory
{
public:
CarEngine* createCarEngineProduct()
{
return new FiatEngine;
}
CarBody* createCarBodyProduct()
{
return new FiatBody;
}
};
// Maruthi Factory
class MaruthiCarFactory : public CarFactory
{
public:
CarEngine* createCarEngineProduct()
{
return new MaruthiEngine;
}
CarBody* createCarBodyProduct()
{
return new MaruthiBody;
}
};
// Renault Factory
class RenaultCarFactory : public CarFactory
{
public:
CarEngine* createCarEngineProduct()
{
return new RenaultEngine;
}
CarBody* createCarBodyProduct()
{
return new RenaultBody;
}
};
int main()
{
// Fiat Factory
CarFactory* pFiatCarFactory = new FaitCarFactory;
CarEngine* pFiatEngine = pFiatCarFactory->createCarEngineProduct();
CarBody* pFiatBody = pFiatCarFactory->createCarBodyProduct();
pFiatEngine->engineType();
pFiatBody->bodyType();
// Renault Car Factory
return 0;
}
*/