Proxy_Pattern_2 - 8BitsCoding/RobotMentor GitHub Wiki

목차


Smart Pointers

Smart Pointers의 간단한 사용방법

int main()
{
    // 일반 포인터의 사용
    BankAccount * a = new CurrentAccount(123);
    a->deposit(321);
    delete a;

    // Smart Pointer 사용
    auto b = make_shared<CurrentAccount>(123);
    BankAccount * actual = b.get(); // enhancement
}

Property Proxy

Property is mean getter or setter

struct Creature
{
    int strength{10};
    int agility{10};

    // 일반적으로 getter, setter를 다음과 같이 작성한다.
    int getStrength() const {
        return strength;
    }

    void setStrength(int strength) {
        Creature::strength = strength;
    }

    int getAgility() const {
        return agility;
    }

    void setAgility(int agility) {
        Creature::agility = agility;
    }
};

int main()
{
    Creature c;
    c.setStrength(10);

    return 0;
}

좀 더 간단하게 사용할 방법은 없는가?

template <typename T> struct Property
{
    T value;

    Property(T value)
    {
        *thist = value;
    }

    operator T()
    {
        return value;
    }

    T operator=(T new_value)
    {
        cout << "Assignment! \n";
        return value = new_value;
    }
};

struct Creature
{
    Property<int> strength{10};
    Property<int> agility{10};
};

int main()
{
    Creature c;
    c.strength = 11;
    int x = c.agility;

    return 0;
}

흠... getter, setter를 주르륵 안 적게 해준다는 점은 있지만... 이렇게 작성하면 위험이 많을꺼 같은데...


Virtual Proxy

struct Image
{
    virtual void draw() = 0;
};

struct Bitmap : Image
{
    Bitmap(const string& filename)
    {
        cout << "Loading bitmap from " << filename << endl;
    }

    void draw() override {
        cout << "Drawing bitmap " << endl;
    }
};

struct LazyBitmap : Image
{
    LazyBitmap(const string & filename) : filename(filename) {
    }

    void draw() override {
        if(!bmp)
            bmp = new Bitmap(filename);
        bmp->draw();
    }

private:
    string filename;
    Bitmap * bmp{nullptr};
};

int main()
{
    //Bitmap bmp{"pokemon.png"};
    LazyBitmap bmp{"pokemon.png"};
    bmp.draw();
}

Communication Proxy

struct Pingable
{
    virtual wstring ping(const wstring& message) = 0;
};

struct Pong : Pingable
{
    wstring ping(const wstring& message) override
    {
        return message + L" pong";
    }
};

void tryit(Pingable& pp)
{
    wcout << pp.ping(L"ping") << "\n";
}

int main()
{
    Pong pp;
    for(size_t i = 0; i < 3; i++)
    {
        tryit(pp);
    }
    
    return 0;
}

전체코드

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

struct BankAccount
{
  virtual ~BankAccount() = default;
  virtual void deposit(int amount) = 0;
  virtual void withdraw(int amount) = 0;
};

struct CurrentAccount : BankAccount // checking
{
  explicit CurrentAccount(const int balance)
    : balance(balance)
  {
  }

  void deposit(int amount) override
  {
    balance += amount;
  }

  void withdraw(int amount) override
  {
    if (amount <= balance) balance -= amount;
  }

  friend ostream& operator<<(ostream& os, const CurrentAccount& obj)
  {
    return os << "balance: " << obj.balance;
  }

private:
  int balance;
};

struct Image
{
  virtual ~Image() = default;
  virtual void draw() = 0;
};

struct Bitmap : Image
{
  Bitmap(const string& filename)
  {
    cout << "Loading image from " << filename << endl;
  }

  void draw() override
  {
    cout << "Drawing image" << endl;
  }
};

struct LazyBitmap : Image
{
  LazyBitmap(const string& filename): filename(filename) {}
  ~LazyBitmap() { delete bmp; }
  void draw() override
  {
    if (!bmp)
      bmp = new Bitmap(filename);
    bmp->draw();
  }

private:
  Bitmap* bmp{nullptr};
  string filename;
};

void draw_image(Image& img)
{
  cout << "About to draw the image" << endl;
  img.draw();
  cout << "Done drawing the image" << endl;
}

void virtual_proxy()
{
  LazyBitmap img{ "pokemon.png" };
  draw_image(img); // loaded whether the bitmap is loaded or not
  draw_image(img);
}

void smart_pointers()
{
  BankAccount* a = new CurrentAccount(123);
  a->deposit(321);
  delete a;

  // << will not work if you make this a shared_ptr<BankAccount>
  auto b = make_shared<CurrentAccount>(123);

  BankAccount* actual = b.get(); // pointer's own operations on a .
  b->deposit(321); // underlying object's operations are on ->
                   // note this expression is identical to what's above
  cout << *b << endl;
  // no delete

  // see shared_ptr in file structure window
}

struct Pingable
{
  virtual ~Pingable() = default;
  virtual wstring ping(const wstring& message) = 0;
};

struct Pong : Pingable
{
  wstring ping(const wstring& message) override
  {
    return message + L" pong";
  }
};

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
using namespace utility;                    // Common utilities like string conversions
using namespace web;                        // Common features like URIs.
using namespace web::http;                  // Common HTTP functionality
using namespace web::http::client;          // HTTP client features
using namespace concurrency::streams;       // Asynchronous streams

struct RemotePong : Pingable
{
  wstring ping(const wstring& message) override
  {
    wstring result;
    http_client client(U("http://localhost:9149/"));
    uri_builder builder(U("/api/pingpong/"));
    builder.append(message);
    pplx::task<wstring> task = client.request(methods::GET, builder.to_string())
      .then([=](http_response r)
    {
      return r.extract_string();
    });
    task.wait();
    return task.get();
  }
};

void tryit(Pingable& pp)
{
  wcout << pp.ping(L"ping") << "\n";
}

void communication_proxy()
{
  Pong pp;
  for (int i = 0; i < 3; ++i)
  {
    tryit(pp);
  }
}

// ======== Property Proxy ======================

template <typename T> struct Property
{
  T value;
  Property(const T initialValue)
  {
    *this = initialValue;
  }
  operator T()
  {
    return value;
  }
  T operator =(T newValue)
  {
    return value = newValue;
  }
};

// ===========================================

struct Creature
{
  Property<int> strength{ 10 };
  Property<int> agility{ 5 };
};

void property_proxy()
{
  Creature creature;
  creature.agility = 20;
  cout << creature.agility << endl;
}

int main()
{
  //property_proxy();
  //smart_pointers();
  //virtual_proxy();
  communication_proxy();

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