Qua các series tự học về Design Pattern, Hôm nay cafedevn chia sẻ cho ace ví dụ và code cụ thể về cách sử dụng Strategy design pattern với ngôn ngữ lập trình C++. Nhằm giúp ace hiểu rõ cách sử Pattern này với C++ một cách nhanh nhất và áp dụng nó vào thực tế.

Mô tả code

Strategy pattern đề xuất: đóng gói một thuật toán trong một hệ thống phân cấp lớp, để các ứng dụng khách của thuật toán đó giữ một con trỏ đến lớp cơ sở của hệ thống phân cấp đó và ủy quyền tất cả các yêu cầu cho thuật toán với đối tượng được chứa “ẩn danh” đó.

Trong ví dụ này, lớp cơ sở Strategy biết cách thu thập một đoạn dữ liệu đầu vào và triển khai thuật toán “định dạng”. Nó xác định một số chi tiết của từng thuật toán riêng lẻ cho thành viên “justify” được cung cấp bởi mỗi lớp Strategy dẫn xuất cụ thể. Lớp TestBed mô hình hóa một lớp ứng dụng muốn tận dụng các dịch vụ của đối tượng “Strategy” dẫn xuất theo thời gian chạy.

Phần code

#include <iostream.h>
#include <fstream.h>
#include <string.h>

class Strategy;

class TestBed
{
  public:
    enum StrategyType
    {
        Dummy, Left, Right, Center
    };
    TestBed()
    {
        strategy_ = NULL;
    }
    void setStrategy(int type, int width);
    void doIt();
  private:
    Strategy *strategy_;
};

class Strategy
{
  public:
    Strategy(int width): width_(width){}
    void format()
    {
        char line[80], word[30];
        ifstream inFile("quote.txt", ios::in);
        line[0] = '\0';

        inFile >> word;
        strcat(line, word);
        while (inFile >> word)
        {
            if (strlen(line) + strlen(word) + 1 > width_)
              justify(line);
            else
              strcat(line, " ");
            strcat(line, word);
        }
        justify(line);
    }
  protected:
    int width_;
  private:
    virtual void justify(char *line) = 0;
};

class LeftStrategy: public Strategy
{
  public:
    LeftStrategy(int width): Strategy(width){}
  private:
     /* virtual */void justify(char *line)
    {
        cout << line << endl;
        line[0] = '\0';
    }
};

class RightStrategy: public Strategy
{
  public:
    RightStrategy(int width): Strategy(width){}
  private:
     /* virtual */void justify(char *line)
    {
        char buf[80];
        int offset = width_ - strlen(line);
        memset(buf, ' ', 80);
        strcpy(&(buf[offset]), line);
        cout << buf << endl;
        line[0] = '\0';
    }
};

class CenterStrategy: public Strategy
{
  public:
    CenterStrategy(int width): Strategy(width){}
  private:
     /* virtual */void justify(char *line)
    {
        char buf[80];
        int offset = (width_ - strlen(line)) / 2;
        memset(buf, ' ', 80);
        strcpy(&(buf[offset]), line);
        cout << buf << endl;
        line[0] = '\0';
    }
};

void TestBed::setStrategy(int type, int width)
{
  delete strategy_;
  if (type == Left)
    strategy_ = new LeftStrategy(width);
  else if (type == Right)
    strategy_ = new RightStrategy(width);
  else if (type == Center)
    strategy_ = new CenterStrategy(width);
}

void TestBed::doIt()
{
  strategy_->format();
}

int main()
{
  TestBed test;
  int answer, width;
  cout << "Exit(0) Left(1) Right(2) Center(3): ";
  cin >> answer;
  while (answer)
  {
    cout << "Width: ";
    cin >> width;
    test.setStrategy(answer, width);
    test.doIt();
    cout << "Exit(0) Left(1) Right(2) Center(3): ";
    cin >> answer;
  }
  return 0;
}

Kết quả:

Exit(0) Left(1) Right(2) Center(3): 2
Width: 75
Exit(0) Left(1) Right(2) Center(3): 3
Width: 75

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!