Flyweight_Pattern_2 - 8BitsCoding/RobotMentor GitHub Wiki
예를들어 이런경우를 가정해보자.
John Doe, John Smith라는 유저가 가입하려하는데 John이라는 공통된 이름의 메모리를 절약해보고 싶다면??
// 일반적으로는 이렇게 작성할 것이다.
struct User
{
string first_name, second_name;
};
int main(int ac, char* av[])
{
User user1{"John", "Doe"};
User user2{"John", "Smith"};
}
typedef uint32_t key;
struct User
{
User(const string& first_name, const string& last_name) : first_name{add(first_name)}, last_name{add(last_name)} {}
const string& get_first_name() const
{
return names.left.find(first_name)->second;
}
const string& get_last_name() const
{
return names.left.find(last_name)->second;
}
protected:
key first_name, last_name;
static bimap<key, string> names;
static key seed;
static key add(const string& s)
{
auto it = names.right.find(s);
if(it == names.right.end())
{
key id = ++seed;
names.insert({seed, s});
return id;
}
return it->second;
}
};
key User::seed{0};
bimap<key, string> User::names{};
int main(int ac. char* av[])
{
}
#include <iostream>
#include <string>
#include <cstdint>
using namespace std;
#include <boost/bimap.hpp>
#include <boost/flyweight.hpp>
#include <boost/flyweight/key_value.hpp>
using namespace boost;
using namespace flyweights;
// coloring in the console by-letter vs using ranges
// boost.flyweight
// naive
typedef uint32_t key;
// mmorpg
struct User
{
User(const string& first_name, const string& last_name)
: first_name{add(first_name)}, last_name{add(last_name)}
{
}
const string& get_first_name() const
{
return names.left.find(last_name)->second;
}
const string& get_last_name() const
{
return names.left.find(last_name)->second;
}
static void info()
{
for (auto entry : names.left)
{
cout << "Key: " << entry.first << ", Value: " << entry.second << endl;
}
}
friend ostream& operator<<(ostream& os, const User& obj)
{
return os
<< "first_name: " << obj.first_name << " " << obj.get_first_name()
<< " last_name: " << obj.last_name << " " << obj.get_last_name();
}
protected:
static bimap<key, string> names;
static int seed;
static key add(const string& s)
{
auto it = names.right.find(s);
if (it == names.right.end())
{
// add it
key id = ++seed;
names.insert(bimap<key, string>::value_type(seed, s));
return id;
}
return it->second;
}
key first_name, last_name;
};
int User::seed = 0;
bimap<key, string> User::names{};
void naive_flyweight()
{
User john_doe{ "John", "Doe" };
User jane_doe{ "Jane", "Doe" };
cout << "John " << john_doe << endl;
cout << "Jane " << jane_doe << endl;
User::info();
}
struct User2
{
// users share names! e.g., John Smith
flyweight<string> first_name, last_name;
//string first_name, last_name;
// ...
User2(const string& first_name, const string& last_name)
{
}
};
void boost_flyweight()
{
User2 john_doe{ "John", "Doe" };
User2 jane_doe{ "Jane", "Doe" };
cout << boolalpha << (&jane_doe.last_name.get() == &john_doe.last_name.get());
//cout << (&jane_doe.last_name == &john_doe.last_name);
}
int main_()
{
naive_flyweight();
boost_flyweight();
getchar();
return 0;
}
#include <iostream>
#include <string>
#include <ostream>
#include <vector>
using namespace std;
class FormattedText
{
string plain_text;
bool *caps;
public:
explicit FormattedText(const string& plainText)
: plain_text{plainText}
{
caps = new bool[plainText.length()];
}
~FormattedText()
{
delete[] caps;
}
void capitalize(int start, int end)
{
for (int i = start; i <= end; ++i)
caps[i] = true;
}
friend std::ostream& operator<<(std::ostream& os, const FormattedText& obj)
{
string s;
for (int i = 0; i < obj.plain_text.length(); ++i)
{
char c = obj.plain_text[i];
s += (obj.caps[i] ? toupper(c) : c);
}
return os << s;
}
};
class BetterFormattedText
{
public:
struct TextRange
{
int start, end;
bool capitalize, bold, italic;
bool covers(int position) const
{
return position >= start && position <= end;
}
};
TextRange& get_range(int start, int end)
{
formatting.emplace_back(TextRange{ start, end });
return *formatting.rbegin();
}
explicit BetterFormattedText(const string& plainText)
: plain_text{plainText}
{
}
friend std::ostream& operator<<(std::ostream& os, const BetterFormattedText& obj)
{
string s;
for (size_t i = 0; i < obj.plain_text.length(); i++)
{
auto c = obj.plain_text[i];
for (const auto& rng : obj.formatting)
{
if (rng.covers(i) && rng.capitalize)
c = toupper(c);
s += c;
}
}
return os << s;
}
private:
string plain_text;
vector<TextRange> formatting;
};
int main(int argc, char* argv[])
{
FormattedText ft("This is a brave new world");
ft.capitalize(10, 15);
cout << ft << endl;
BetterFormattedText bft("This is a brave new world");
bft.get_range(10, 15).capitalize = true;
cout << bft << endl;
}