Strategy_Pattern_2 - 8BitsCoding/RobotMentor GitHub Wiki

목차

Strategy : Enables the exact behavior of a system to be selected either at run-time(dynamic) or compile-time(static).


Dynamic Strategy

enum class OutputFormat
{
    makrdown,
    html
};

struct ListStrategy
{
    virtual void start(ostringstream& oss) {}
    virtual void add_list_item(ostringstream& oss, const string& item) = 0;
    virtual void end(ostringstream& oss) {}
};

struct MarkdownListStrategy : ListStrategy{
    void add_list_item(ostringstream& oss, const string& item) overrid
    {
        oss << "* " << item << "\n";
    }
};

struct HtmlListStrategy : ListStrategy{
    void start(ostringstream& oss) override
    {
        oss << "<ul>\n";
    }

    void add_list_item(ostringstream& oss, const string& item) override
    {
        oss << " <li>" << item << " </li>";
    }

    void end(ostringstream& oss) override 
    {
        oss << "</ul>\n";
    }
};

struct TextProcessor
{
    void clear() {
        oss.str("");
    }

    void append_list(const vector<string>& items) {
        list_strategy->start(oss);
        for(auto& item : items)
            list_strategy->add_list_item(oss, item);
        list_strategy->end(oss);
    }

    void set_output_format(const OutputFormat& format)
    {
        switch(format)
        {
            case OutputFormat::markdown:
                list_strategy = make_unique<MarkdownListStrategy>();
                break;
            case OutputFormat::html:
                list_strategy = make_unique<HtmlListStrategy>();
                break;
        }
    }

    string str() const { return oss.str(); }

private:
    stringstream oss;
    unique_ptr<ListStrategy> list_strategy;
};

int main(int ac, char* av[])
{
    vector<string> items{"foo", "bar", "baz"};

    TextProcessor tp;
    tp.set_output_format(OutptFormat::markdown);
    tp.append_list(items);

    cout << tp.str() << "\n";

    tp.clear();

    tp.set_output_format(OutputFormat::html);
    tp.append_list(items);

    cout << tp.str() << "\n";

    return 0;
}

Dynamic Strategy 전체코드

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <vector>
using namespace std;

enum class OutputFormat
{
  Markdown,
  Html
};

struct ListStrategy
{
  virtual ~ListStrategy() = default;
  virtual void add_list_item(ostringstream& oss, const string& item) {};
  virtual void start(ostringstream& oss) {};
  virtual void end(ostringstream& oss) {};
};

struct MarkdownListStrategy : ListStrategy
{
  void add_list_item(ostringstream& oss, const string& item) override
  {
    oss << " * " << item << endl;
  }
};

struct HtmlListStrategy : ListStrategy
{
  void start(ostringstream& oss) override
  {
    oss << "<ul>" << endl;
  }

  void end(ostringstream& oss) override
  {
    oss << "</ul>" << endl;
  }

  void add_list_item(ostringstream& oss, const string& item) override
  {
    oss << "<li>" << item << "</li>" << endl;
  }
};

struct TextProcessor
{
  void clear()
  {
    oss.str("");
    oss.clear();
  }
  void append_list(const vector<string> items)
  {
    list_strategy->start(oss);
    for (auto& item : items)
      list_strategy->add_list_item(oss, item);
    list_strategy->end(oss);
  }

  void set_output_format(const OutputFormat format)
  {
    switch(format)
    {
    case OutputFormat::Markdown: 
      list_strategy = make_unique<MarkdownListStrategy>();
      break;
    case OutputFormat::Html: 
      list_strategy = make_unique<HtmlListStrategy>();
      break;
    default:
      throw runtime_error("Unsupported strategy.");
    }
  }
  string str() const { return oss.str(); }
private:
  ostringstream oss;
  unique_ptr<ListStrategy> list_strategy;
};

int main_()
{
  // markdown
  TextProcessor tp;
  tp.set_output_format(OutputFormat::Markdown);
  tp.append_list({"foo", "bar", "baz"});
  cout << tp.str() << endl;

  // html
  tp.clear();
  tp.set_output_format(OutputFormat::Html);
  tp.append_list({"foo", "bar", "baz"});
  cout << tp.str() << endl;

  getchar();
  return 0;
}

Static Strategy

template <typename LS>
struct TextProcessor
{
  void clear()
  {
    oss.str("");
    oss.clear();
  }
  void append_list(const vector<string> items)
  {
    list_strategy.start(oss);
    for (auto& item : items)
      list_strategy.add_list_item(oss, item);
    list_strategy.end(oss);
  }
  string str() const { return oss.str(); }
private:
  ostringstream oss;
  LS list_strategy;
};

int main()
{
  // markdown
  TextProcessor<MarkdownListStrategy> tpm;
  tpm.append_list({"foo", "bar", "baz"});
  cout << tpm.str() << endl;

  // html
  TextProcessor<HtmlListStrategy> tph;
  tph.append_list({"foo", "bar", "baz"});
  cout << tph.str() << endl;

  getchar();
  return 0;
}

Static Strategy 전체코드

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <vector>
using namespace std;

enum class OutputFormat
{
  Markdown,
  Html
};

struct ListStrategy
{
  virtual ~ListStrategy() = default;
  virtual void add_list_item(ostringstream& oss, const string& item) = 0;
  virtual void start(ostringstream& oss) = 0;
  virtual void end(ostringstream& oss) = 0;
};

struct MarkdownListStrategy : ListStrategy
{
  void start(ostringstream& oss) override
  {
  }

  void end(ostringstream& oss) override
  {
  }

  void add_list_item(ostringstream& oss, const string& item) override
  {
    oss << " * " << item << endl;
  }
};

struct HtmlListStrategy : ListStrategy
{
  void start(ostringstream& oss) override
  {
    oss << "<ul>" << endl;
  }

  void end(ostringstream& oss) override
  {
    oss << "</ul>" << endl;
  }

  void add_list_item(ostringstream& oss, const string& item) override
  {
    oss << "<li>" << item << "</li>" << endl;
  }
};

template <typename LS>
struct TextProcessor
{
  void clear()
  {
    oss.str("");
    oss.clear();
  }
  void append_list(const vector<string> items)
  {
    list_strategy.start(oss);
    for (auto& item : items)
      list_strategy.add_list_item(oss, item);
    list_strategy.end(oss);
  }
  string str() const { return oss.str(); }
private:
  ostringstream oss;
  LS list_strategy;
};

int main()
{
  // markdown
  TextProcessor<MarkdownListStrategy> tpm;
  tpm.append_list({"foo", "bar", "baz"});
  cout << tpm.str() << endl;

  // html
  TextProcessor<HtmlListStrategy> tph;
  tph.append_list({"foo", "bar", "baz"});
  cout << tph.str() << endl;

  getchar();
  return 0;
}
⚠️ **GitHub.com Fallback** ⚠️