공유를 통해 많은 수의 객체를 효율적으로 지원하는 디자인 패턴
같은 데이터는 한 번만 메모리에 저장
여러 객체가 공유해서 사용
메모리 절약이 목적
Flyweight : Slime
Context : SType
FlyweightFactory : SlimeFactory
#include <iostream> #include <map> // std::map을 사용하기 위해 포함합니다. #include <vector> // std::vector를 사용하기 위해 포함합니다. #include <string> // std::string을 사용하기 위해 포함합니다. // 플라이웨이트(Flyweight) 객체 클래스입니다. // 여러 Slime 객체들이 공유할 데이터를 담고 있습니다. (본질적 상태, Intrinsic State) class SType { private: std::string image; // 이미지 데이터 std::string sound; // 사운드 데이터 public: // 생성자: 이미지와 사운드 데이터를 받아 초기화합니다. SType(const std::string& _image, const std::string& _sound) : image(_image), sound(_sound) {} // 이미지 정보를 출력하는 함수 void imagePrint() { std::cout << image << std::endl; } // 사운드 정보를 출력하는 함수 void SoundOutput() { std::cout << sound << std::endl; } }; // 실제 게임에 등장할 Slime 객체 클래스입니다. class Slime { private: int hp; // 각 슬라임마다 다른 고유 데이터 (외재적 상태, Extrinsic State) int attack; // 각 슬라임마다 다른 고유 데이터 (외재적 상태, Extrinsic State) std::shared_ptr<SType> type; // 공유되는 데이터(SType)에 대한 포인터 public: // 생성자: 고유 데이터(hp, attack)와 공유 데이터(type)를 받아 초기화합니다. Slime(int _hp, int _attack, std::shared_ptr<SType> _type) : hp(_hp), attack(_attack), type(_type) {} // Slime의 모든 정보를 출력하는 함수 void ShowInfo() { std::cout << "HP : " << hp << ", 공격력 : " << attack << std::endl; type->imagePrint(); // 공유 데이터의 이미지 출력 함수 호출 type->SoundOutput(); // 공유 데이터의 사운드 출력 함수 호출 } }; // 플라이웨이트 객체(SType)를 생성하고 관리하는 팩토리 클래스입니다. class SlimeFactory { private: // SType 객체들을 저장하는 맵. string(타입 이름)을 키로 사용합니다. std::map<std::string, std::shared_ptr<SType>> stype; public: // SType 객체를 가져오는 함수. 없으면 새로 만들고, 있으면 기존 객체를 반환합니다. std::shared_ptr<SType> getSlimeType(std::string _name, std::string _color, std::string _sound) { // 맵에서 _name 키를 가진 SType이 있는지 확인합니다. if (stype.find(_name) == stype.end()) { // 없으면 새로 생성하여 맵에 추가합니다. std::cout << "[생성] - " << _name << " 타입 생성" << std::endl; stype[_name] = std::make_shared<SType>(_color, _sound); } else { // 이미 존재하면 메시지를 출력하고 기존 객체를 재사용합니다. std::cout << "[재사용] - " << _name << " 타입 재사용" << std::endl; } // 해당 SType 객체를 반환합니다. return stype[_name]; } }; int main() { SlimeFactory factory; std::vector<Slime> slimes; // 생성된 슬라임들을 담을 벡터 // "파란슬라임" 타입을 팩토리로부터 가져옵니다. // 이 시점에 "파란슬라임" SType 객체가 처음으로 생성됩니다. auto bluetype = factory.getSlimeType("파란슬라임", "이미지 : 파랑색", "울음소리 : 꾸오오옥"); // 100마리의 슬라임을 생성합니다. for (int i = 0; i < 100; i++) { // 모든 슬라임이 위에서 만든 bluetype 객체 하나를 공유하게 됩니다. // SType 객체는 1개만 존재하고, 100개의 Slime 객체는 각자 다른 hp와 attack만 가집니다. slimes.push_back(Slime(10 + i, 20 + i, bluetype)); } // 생성된 슬라임들의 정보를 출력합니다. for (auto slime : slimes) { slime.ShowInfo(); } return 0; }
- 100마리의 슬라임을 만들어도 SType 객체는 단 하나만 유지한다.