SingleTon_Pattern_2 - 8BitsCoding/RobotMentor GitHub Wiki

๋ชฉ์ฐจ


Singleton Implementation

NewYork
1256776
Busan
109455

์œ„์™€ ๊ฐ™์ด ๋„์‹œ๋ช… ๊ทธ๋ฆฌ๊ณ  ์ธ๊ตฌ์ˆ˜๊ฐ€ ์ ํžŒ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค(capitals.txt)๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์˜ ์‹ฑ๊ธ€ํ„ด์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.


Singleton Implementation ์ „์ฒด์ฝ”๋“œ

#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <boost/lexical_cast.hpp>
#include <vector>

class Database
{
public:
  virtual int get_population(const std::string& name) = 0;
};

class SingletonDatabase : public Database
{
  SingletonDatabase()
  {
    std::cout << "Initializing database" << std::endl;

    std::ifstream ifs("capitals.txt");

    std::string s, s2;
    while (getline(ifs, s))
    {
      getline(ifs, s2);
      int pop = boost::lexical_cast<int>(s2);
      capitals[s] = pop;
    }
    //instance_count++;
  }

  std::map<std::string, int> capitals;

public:
  //static int instance_count;

  SingletonDatabase(SingletonDatabase const&) = delete;
  void operator=(SingletonDatabase const&) = delete;

  static SingletonDatabase& get()
  {
    static SingletonDatabase db;
    return db;
  }

  int get_population(const std::string& name) override
  {
    return capitals[name];
  }

  /*
  static SingletonDatabase* get_instance()
  {
    if (!instance)
      instance = new SingletonDatabase;
    return instance; // atexit
  }
  */
};

//int SingletonDatabase::instance_count = 0;

class DummyDatabase : public Database
{
  std::map<std::string, int> capitals;
public:


  DummyDatabase()
  {
    capitals["alpha"] = 1;
    capitals["beta"] = 2;
    capitals["gamma"] = 3;
  }

  int get_population(const std::string& name) override {
    return capitals[name];
  }
};

struct SingletonRecordFinder
{
  int total_population(std::vector<std::string> names)
  {
    int result = 0;
    for (auto& name : names)
      result += SingletonDatabase::get().get_population(name);
    return result;
  }
};

struct ConfigurableRecordFinder
{
  explicit ConfigurableRecordFinder(Database& db)
    : db{db}
  {
  }

  int total_population(std::vector<std::string> names) const
  {
    int result = 0;
    for (auto& name : names)
      result += db.get_population(name);
    return result;
  }

  Database& db;
};

Monostate

์ž˜๋ชป๋œ Singleton์˜ ๋ฌธ์ œ์ ์„ ์ œ์‹œํ•œ๋‹ค.

class Printer
{
  static int id;
public:
  int get_id() const { return id; }
  void set_id(int value) { id = value; }
};

int main() 
{
  Printer p;
  int id = p.get_id();

  Printer p2;
  int id2 = p2.get_id();
  // id == id2 ๊ฐ™์€ id๋ฅผ ๋‹ค๋ฃจ๊ฒŒ ๋œ๋‹ค.
  // ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ์ ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋ฅผ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.
}

Multiton

์—ฌ๋Ÿฌ๊ฐœ์˜ ์š”์†Œ๋ฅผ Singleton์œผ๋กœ ์ €์žฅํ•ด ๋‘๊ณ  ์‹ถ์„๋•Œ ์‚ฌ์šฉ

#include <map>
#include <memory>
#include <iostream>
using namespace std;

enum class Importance
{
  primary,
  secondary,
  tertiary
};

template <typename T, typename Key = std::string>
class Multiton
{
public:
  static shared_ptr<T> get(const Key& key)
  {
    if (const auto it = instances.find(key);
        it != instances.end())
    {
      return it->second;
    }

    auto instance = make_shared<T>();
    instances[key] = instance;
    return instance;
  }
protected:
  Multiton() = default;
  virtual ~Multiton() = default;
private:
  static map<Key, shared_ptr<T>> instances;
};

template <typename T, typename Key>
map<Key, shared_ptr<T>> Multiton<T, Key>::instances;

class Printer
{
public:
  Printer()
  {
    ++Printer::totalInstanceCount;
    cout << "A total of " <<
      Printer::totalInstanceCount <<
      " instances created so far\n";
  }
private:
  static int totalInstanceCount;
};
int Printer::totalInstanceCount = 0;

int main()
{
  typedef Multiton<Printer, Importance> mt;

  auto main = mt::get(Importance::primary);
  auto aux = mt::get(Importance::secondary);
  auto aux2 = mt::get(Importance::secondary);
}
โš ๏ธ **GitHub.com Fallback** โš ๏ธ