C++ 如何与战略设计模式互动

C++ 如何与战略设计模式互动,c++,design-patterns,C++,Design Patterns,我想问几个关于设计模式的问题。 以战略设计模式为例: 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

我想问几个关于设计模式的问题。 以战略设计模式为例:

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();
};
类打印机{
公众:
作废打印(信息){
}
};
类消息{
公众:
作废打印();
};
类SingleMessage:公共消息{
字符串s;
公众:
作废打印();
};
类消息:公共消息{
向量v;
公众:
作废打印();
};
根据该模式的UML,打印机应具有方法打印(消息)。我不明白的是(如果这是一个愚蠢的问题,很抱歉)我们需要调用消息类print方法还是什么?我们需要打印出消息,但不能在Printer类中创建新的消息对象,因为这样它将是合成。那我们该怎么办呢

另外,也许您可以分享一些教程,其中将解释设计模式(如何使用它们,何时使用它们,等等)?

首先,合成的概念与设计模式完全不同。大多数设计模式都使用组合——这很好

其次,不,这里不使用构图。调用传递给打印机的参数的
print
函数:

class Printer{
public:
    void print(Message& m) {
        m.print();
    }
};

我已经修复了一个bug:参数需要通过引用(或作为指针)传递,否则将丢失动态类型。因此,
Message::print
函数也需要声明为
virtual

您可能想做的是提供一个
打印机作为策略。您可以指定
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";
   }
};
类打印机{
公众:
虚拟无效打印(常量字符串和消息)=0;
};
班机{
公众:
无效打印(常量字符串和消息)覆盖{
标准::cout
我不明白的是(如果这是一个愚蠢的问题,很抱歉)我们需要调用消息类print方法还是什么

是的。Message::print函数应该是抽象的,并在继承自Message的每个类中实现(作为不同的策略)

我们需要打印出消息,但我们不能在类Printer中创建新的消息对象,因为这样它将是合成。那个么我们应该怎么做呢

您不需要在打印机中创建新实例(即,此处不需要合成)。您在此处所做的只是通过决定将哪些具体实现传递到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);
};

1)
Message::print
必须是虚拟的,否则将不起作用。2)
Printer::print
必须接收其参数作为引用或指针,否则多态性将不起作用。
Printer
将调用其参数的
print
。您可能不希望从Message派生类消息,因为消息是虚拟的消息的向量,而不是消息本身。我会将
类消息
重命名为
类IPrintable
,并且它的唯一方法是纯抽象(
virtual void print()=0;
)您还要求提供一个教程,但我会推荐这本书,因为它很棒:如果一个新类是从Message派生的呢?您现有的打印机将如何处理它?您的打印机需要访问Message的成员变量吗?这就是策略模式的优点:添加新类型的消息与使用的策略是正交的(添加不同的策略与消息正交)。您可以使用类似于
struct multileMessage
的消息类型,在循环中调用p.print。无论您使用何种打印策略调用函数,这也会起作用。
struct PrintableContainer
作为消息和打印机之间的接口是否合理?比方说
message::to(PrintableContainer&)
打印机::打印(可打印容器&)
?我不知道。这取决于您的特定体系结构,这应该取决于您试图实现的目标。
int main()
{
    Messages messages {std::make_unique<CoutPrinter>()};
    messages.print();  // will print all messages to std::cout
}
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
}
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);
};