如何与战略设计模式互动
How to interact with the strategy design patten
我想问几个关于设计模式的问题。让我们以战略设计模式为例:
class Printer{
public:
void print(Message){
}
};
class Message{
public:
void print();
};
class SingleMessage : public Message{
string s;
public:
void print();
};
class Messages : public Message{
vector<Message> v;
public:
void print();
};
根据这个模式的UML,Printer应该有方法print(Message)。我不明白的是(如果这是一个愚蠢的问题,很抱歉)我们需要调用Message类打印方法还是什么?我们需要打印出消息,但我们不能在类Printer中创建新的message对象,因为那样它将是合成的。那么我们该怎么办呢?
此外,也许你可以分享一些教程,其中会解释设计模式(如何使用它们,何时使用它们,等等)?
首先,组合的概念与设计模式完全不同。大多数设计模式都使用组合——这完全没问题。
第二,不,你在这里不用作文。调用传递给打印机的参数的print
函数:
class Printer{
public:
void print(Message& m) {
m.print();
}
};
我已经修复了一个错误:参数需要通过引用(或作为指针)传递,否则就会丢失动态类型。因此,Message::print
函数也需要声明为virtual
。
我不明白的是(如果这是一个愚蠢的问题,很抱歉)我们需要调用Message类打印方法还是什么?
是。Message::print函数应该是抽象的,并在继承自Message的每个类中实现(作为不同的策略)。
我们需要打印出消息,但我们不能在类Printer中创建新的message对象,因为那样它将是合成的。那么我们该怎么办呢?
您不需要在打印机中创建新实例(即,您不需要此处的组合)。您在这里所要做的就是通过决定传递到Printer::print函数中的具体实现来选择打印的实现策略。
此外,也许你可以分享一些教程,在其中解释设计模式(如何使用它们,何时使用它们,等等)?
通常情况下,设计模式是重复出现的设计问题的惯用解决方案。你可以在维基百科上找到关于何时使用它们的详细信息。例如,这个页面上写着:
"在计算机编程中,策略模式(也称为策略模式)是一种软件设计模式可以在运行时选择行为。">
顺便说一句,这不是战略模式的一个很好的例子。更好的方法是抽象打印的含义,而不是消息的含义:
class Message{
public:
void display(Printer& p) {
p.print(*this); // what printing strategy is applied to
// display the message depends on the
// concrete type of the parameter (on what
// Printer specialization you call
// the function with)
}
};
struct Printer{
virtual void print(Message& m);
};
struct BWPrinter: Printer {
virtual void print(Message& m);
};
struct ColorPrinter: Printer {
virtual void print(Message& m);
};
struct IOStreamPrinter: Printer {
IOStreamPrinter(std::iostream& s);
virtual void print(Message& m);
};
您可能想要做的是提供一个Printer
作为策略。您可以指定CoutPrinter
FilePrinter
或PrinterPrinter
。。。
class Printer{
public:
virtual void print(const string& message) = 0;
};
class CoutPrinter{
public:
void print(const string& message) override {
std::cout << message << "n";
}
};
然后,您可以使用这个概念来打印消息:
class Message{
public:
virtual print(Printer& printer) = 0;
};
class SingleMessage : public Message {
string s;
public:
void print(Printer& printer) override
{
printer.print(s)
}
};
class Messages {
vector<Message> messages;
std::unique_ptr<Printer> printer;
public:
/// Inject the concrete Printer strategy here
Messages(std::unique_ptr<Printer> printerStrategy) :
printer(move(printer))
{}
void print() {
for(auto& m : messages)
m.print(*printer);
}
};
您可以知道使用构造函数注入为您的消息选择不同的打印机
int main()
{
Messages messages {std::make_unique<CoutPrinter>()};
messages.print(); // will print all messages to std::cout
}
复合图案
在您的示例中,您从Message派生了Messages。这就是复合图案。您可以将两者结合:
class Messages : public Messages {
vector<Message> messages;
public:
void print(Printer& printer) override {
for(auto& m : messages)
m.print(*printer);
}
};
int main()
{
Messages messages;
CoutPrinter printer;
messages.print(printer); // will print all messages to std::cout
}
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 是否有可以处理方法调用依赖关系的设计模式?
- 使用 C++ 设计模式