- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究抽象工厂模式与工厂方法模式之间的区别。我了解到工厂方法仅用于创建一个产品,而抽象工厂用于创建相关或依赖产品的系列。但是我不清楚工厂方法模式如何使用继承而抽象工厂模式使用组合。
我知道这个问题被问过几次了,有人可以用下面的代码解释一下继承和组合是如何发生的吗?
工厂方法代码
class IRose
{
public:
virtual string Color(void)=0;
};
class RedRose: public IRose
{
public:
string Color(void)
{
return "Red";
}
};
class YellowRose: public IRose
{
public:
string Color(void)
{
return "Yellow";
}
};
class IFactory
{
public:
virtual IRose* Create(string type)=0;
//The factory create method in 90% of cases will take a parameter which
//determines what kind of the object the factory will return.
};
class Factory: public IFactory
{
public:
IRose* Create(string type)
{
if ("Red" == type)
return new RedRose();
if ("Yellow" == type)
return new YellowRose();
return NULL;
}
};
int main()
{
IRose* p = NULL;
IFactory* f = NULL;
f = new Factory(); //You have to create an INSTANCE of the factory
p = f->Create("Red");
cout<<"\nColor is: "<<p->Color()<<"\n";
delete p;
p = f->Create("Yellow");
cout<<"\nColor is: "<<p->Color()<<"\n";
delete p;
return 1;
}
抽象工厂代码。
class IFridge
{
public:
virtual string Run(void) = 0;
};
class FridgeSamsung : public IFridge
{
public:
string Run(void)
{
return "You are now running Samsung Fridge\n";
}
};
class FridgeWhirlpool : public IFridge
{
public:
string Run(void)
{
return "You are now running Whirlpool Fridge\n";
}
};
class IWashingMachine
{
public:
virtual string Run(void) = 0;
};
class WashingMachineSamsung : public IWashingMachine
{
public:
string Run(void)
{
return "You are now running Samsung Washing Machine\n";
}
};
class WashingMachineWhirlpool : public IWashingMachine
{
public:
string Run(void)
{
return "You are now running Whirlpool Washing Machine\n";
}
};
class IFactory
{
public:
virtual IFridge* GetFridge(void) = 0;
virtual IWashingMachine* GetWashingMachine(void) = 0;
};
class FactorySamsung : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeSamsung();
}
IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineSamsung();
}
};
class FactoryWhirlpool : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeWhirlpool();
}
IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineWhirlpool();
}
};
int main()
{
IFridge* fridge; //Client just knows about fridge and washingMachine.
IWashingMachine* washingMachine; //and factory. He will write operations which
IFactory* factory; //work on fridges and washingMachines.
factory = new FactorySamsung;
//This is the only place where the client
//has to make a choice.
//The rest of the code below will remain same, even
//if the factory is changed. He can change the factory and the same range
//of products but from a different factory will be returned. No need to
//change any code.
fridge = factory->GetFridge();
cout << fridge->Run();
washingMachine = factory->GetWashingMachine();
cout << washingMachine->Run();
cout << "\n";
delete factory;
factory = new FactoryWhirlpool;
//See same client code.
fridge = factory->GetFridge();
cout << fridge->Run();
washingMachine = factory->GetWashingMachine();
cout << washingMachine->Run();
cout << "\n";
delete factory;
return 1;
}
最佳答案
这是经过深思熟虑后修改的回复。
工厂方法:通常,createObject()是Creator对象的一个方法。
抽象工厂:通常工厂对象是Creator对象的一个属性。
现在假设 createObject() 和 Factory Object 属于它们各自的 Creator。
工厂方法:createObject() 可能会在 Creator 的子类中发生变化。这是通过通过继承更改 creatObject() 的实现来实现的。
Abstract Factory:Factory Object 也可能在 Creator 的子类中发生变化。然而,这种变化是通过用不同的工厂对象替换一个工厂对象来实现的,即 Creator 对象被组合改变了。
在您的演示中,creatObject() 和 Factory Object 在 Creator(s) 之外,因此模糊了组合/继承之间的区别!
Christopher Okhravi 在 YouTube 上有很棒的模式视频。
工厂方法 https://www.youtube.com/watch?v=EcFVTgRHJLM&index=4&list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc
抽象工厂https://www.youtube.com/watch?v=v-GiuMmsXj4&index=5&list=PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc
这里要求的是工厂方法的一个版本(这次是在 C++ 中!)。如果您需要任何口译帮助,请告诉我。
class IRose
{
public:
virtual const char * Color(void) = 0;
};
class RedRose : public IRose
{
public:
const char * Color(void)
{
return "I am a Red rose";
}
};
class YellowRose : public IRose
{
public:
const char * Color(void)
{
return "I am a Yellow rose";
}
};
class RoseGarden
{
protected: class IRose* rose; // a pointer to the garden's rose
public:
virtual void createRose() { } // abstract Factory Method
public: void sayColor() {
cout << rose->Color() << '\n';
}
};
class RedRoseGarden : public RoseGarden
{
public:
void createRose()
{
this->rose = new RedRose(); // concrete factory method
}
};
class YellowRoseGarden : public RoseGarden
{
public:
void createRose()
{
this->rose = new YellowRose(); // concrete factory method
}
};
int main()
{
RoseGarden * garden = NULL;
garden = new YellowRoseGarden;
garden->createRose(); // correct factory method is chosen via inheritance
garden->sayColor();
delete garden;
garden = new RedRoseGarden;
garden->createRose(); // correct factory method is chosen via inheritance
garden->sayColor();
delete garden;
return 1;
}
这里还有一个稍微修改过的抽象工厂版本,以更好地展示它是如何使用的。刚刚添加了一个房子对象。请注意,我为我的编译器将所有“字符串”对象更改为 const char*。
// make different types of fridges
class IFridge
{
public:
virtual const char* Run(void) = 0;
};
class FridgeSamsung : public IFridge
{
public:
const char* Run(void)
{
return "This house has a Samsung Fridge\n";
}
};
class FridgeWhirlpool : public IFridge
{
public:
const char* Run(void)
{
return "This house has a Whirlpool Fridge\n";
}
};
// make different types of washing machine
class IWashingMachine
{
public:
virtual const char* Run(void) = 0;
};
class WashingMachineSamsung : public IWashingMachine
{
public:
const char* Run(void)
{
return "This house has a Samsung Washing Machine\n";
}
};
class WashingMachineWhirlpool : public IWashingMachine
{
public:
const char* Run(void)
{
return "This house has a Whirlpool Washing Machine\n";
}
};
// make different type of factory
class IFactory
{
public:
virtual IFridge* GetFridge(void) = 0;
virtual IWashingMachine* GetWashingMachine(void) = 0;
};
class FactorySamsung : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeSamsung();
}
IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineSamsung();
}
};
class FactoryWhirlpool : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeWhirlpool();
}
IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineWhirlpool();
}
};
// Make a house object that has a fridge and a washing machine
class House
{
private:
class IWashingMachine * washingMachine;
class IFridge * fridge;
public:
House(IFactory * houseFactory) {
washingMachine = houseFactory->GetWashingMachine();
fridge = houseFactory->GetFridge();
}
void showAppliances() {
cout << washingMachine->Run();
cout << fridge->Run();
}
};
int main()
{
class IFactory * factory;
class House * house;
// make a samsung house
factory = new FactorySamsung;
house = new House(factory); // passing the factory by injection
house->showAppliances(); // now we have a Samsung house
cout << '\n';
// clean up
delete house;
delete factory;
// make a whirlpool house
factory = new FactoryWhirlpool;
house = new House(factory); // passing the factory by injection
house->showAppliances(); // now we have a WHilepool house
cout << '\n';
// clean up
delete house;
delete factory;
return 1;
}
关于c++ - 工厂方法模式使用继承,而抽象工厂模式使用组合如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51394566/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!