Modern C++ Design Pattern/Chatper 6. 어댑터

created : Tue, 07 Apr 2020 20:44:17 +0900
modified : Sat, 26 Sep 2020 23:19:03 +0900
cpp adaptor

Adapter Pattern

    struct Point
    {
      int x, y;
    };

    struct Line{
      Point start, end;
    };

    struct VectorObject
    {
      virtual std::vector<Line>::iterator begin() = 0;
      virtual std::vector<Line>::iterator end() = 0;
    };

    struct VectorRectangle : VectorObject
    {
      VectorRectangle(int x, int y, int width, int height)
      {
        lines.emplace_back(Line{ Point{x, y}, Point{x + width, y} });
        lines.emplace_back(Line{ Point{x + width, y}, Point {x + width, y + height} });
        lines.emplace_back(Line{ Point{x,y}, Point{x, y + height} });
        lines.emplace_back(Line{ Point{ x, y + height }, Point {x + width, y + height} });
      }

      std::vecotr<Line>::iterator begin() override {
        return lines.begin();
      }
      std::vector<Line>::iterator end() override {
        return lines.end();
      }

    private:
      std::vector<Line> lines;
    };

    void DrawPoints(CPaintDC& dc,
      std::vector<Point>::iterator start,
      std::vector<Point>::iterator end)
    {
      for (auto i = start; i != end; ++i)
        dc.SetPixel(i->x, i->y , 0);
    }

Adapter

    vector<shared_ptr<VectorObject>> vectorObjects{
      make_shared<VectorRectangle>(10, 10, 100, 100),
      make_shared<VectorRectangle>(30, 30, 60, 60)
    }

    struct LineToPointAdapter
    {
      typedef vector<Point> Points;

      LineToPointAdapter(Line& line);

      virtual Points::iterator begin() { return points.begin(); }
      virtual Points::iterator end() { return points.end(); }
    private:
      Points points;
    };

    LineToPointAdapter::LineToPointAdapter(Line& line)
    {
      int left = min(line.start.x, line.end.x);
      int right = max(line.start.x, line.end.x);
      int top = min(line.start.y, line.end.y);
      int bottom = max(line.start.y, line.end.y);
      int dx = right - left;
      int dy = line.end.y - line.start.y;

      if (dx == 0)
      {
        for (int y = top; y <= bottom; ++y)
        {
          points.emplace_back(Point{ left, y });
        }
      }
      else if (dy == 0)
      {
        for (int x = left; x <= right; ++x)
        {
          points.emplace_back(Point{ x, top });
        }
      }
    }


    for (auto& obj : vectorObjects)
    {
      for (auto& line : *obj)
      {
        LineToPointAdapter lpo{ line };
        DrawPoints(dc, lpo.begin(), lpo.end());
      }
    }

Temporary Adapter