-
객체 생성 : 프로토타입 패턴 ( Prototype Pattern )Programming/패턴 2020. 9. 26. 16:57
정의
원형이 되는 인스턴스를 사용하여 생성할 객체의 종류를 명시하고, 이렇게 만든 견본을 복사해서 새로운 객체를 생성
왜 사용해야 할까?
객체가 이미 존재하고 그 객체의 복사본을 만들고 싶을 때 사용한다. 그러면 새로운 객체를 만들 때 모든 필드를 확인하고 해당 값을 새 객체에 할당하는 것은 좋은 생각이긴 하지만, 일부 필드가 private이고 객체 자체가 외부에서 보이지 않을 수 있는 이유로 모든 객체를 복사할 수 있는 것은 아니라고 한다
모든 객체에 대한 공통 인터페이스를 선언하고 이 인터페이스를 통해서 객체의 클래스에 연결하지 않고 객체를 복제한다.
clone 함수를 구현함으로써 이전 객체의 모든 필드 값을 새 객체로 전달하는 역할을 한다.
실생활에서의 프로토타입은 다양한 테스트 및 빠른 결과물을 보여주기 위해 만들어진다.
- Prototype : 자신을 복제하는데 필요한 인터페이스를 정의함
- ConcretePrototype : 자신을 복제하는 연산을 구현한다
- Client : 원형에 자기 자신의 복제를 요청하여 새로운 객체를 생성한다
참고예제 (위키)
#include <iostream> #include <map> #include <string> #include <cstdint> using namespace std; enum RECORD_TYPE_en { CAR, BIKE, PERSON }; /** * Record is the Prototype */ class Record { public : Record() {} virtual ~Record() {} virtual Record* Clone() const=0; virtual void Print() const=0; }; /** * CarRecord is Concrete Prototype */ class CarRecord: public Record { private : string m_oStrCarName; uint32_t m_ui32ID; public : CarRecord(const string& _oStrCarName, uint32_t _ui32ID) : Record(), m_oStrCarName(_oStrCarName), m_ui32ID(_ui32ID) { } CarRecord(const CarRecord& _oCarRecord) : Record() { m_oStrCarName = _oCarRecord.m_oStrCarName; m_ui32ID = _oCarRecord.m_ui32ID; } ~CarRecord() {} CarRecord* Clone() const { return new CarRecord(*this); } void Print() const { cout << "Car Record" << endl << "Name : " << m_oStrCarName << endl << "Number: " << m_ui32ID << endl << endl; } }; /** * BikeRecord is the Concrete Prototype */ class BikeRecord: public Record { private : string m_oStrBikeName; uint32_t m_ui32ID; public : BikeRecord(const string& _oStrBikeName, uint32_t _ui32ID) : Record(), m_oStrBikeName(_oStrBikeName), m_ui32ID(_ui32ID) { } BikeRecord(const BikeRecord& _oBikeRecord) : Record() { m_oStrBikeName = _oBikeRecord.m_oStrBikeName; m_ui32ID = _oBikeRecord.m_ui32ID; } ~BikeRecord() {} BikeRecord* Clone() const { return new BikeRecord(*this); } void Print() const { cout << "Bike Record" << endl << "Name : " << m_oStrBikeName << endl << "Number: " << m_ui32ID << endl << endl; } }; /** * PersonRecord is the Concrete Prototype */ class PersonRecord: public Record { private : string m_oStrPersonName; uint32_t m_ui32Age; public : PersonRecord(const string& _oStrPersonName, uint32_t _ui32Age) : Record(), m_oStrPersonName(_oStrPersonName), m_ui32Age(_ui32Age) { } PersonRecord(const PersonRecord& _oPersonRecord) : Record() { m_oStrPersonName = _oPersonRecord.m_oStrPersonName; m_ui32Age = _oPersonRecord.m_ui32Age; } ~PersonRecord() {} Record* Clone() const { return new PersonRecord(*this); } void Print() const { cout << "Person Record" << endl << "Name: " << m_oStrPersonName << endl << "Age : " << m_ui32Age << endl << endl ; } }; /** * RecordFactory is the client */ class RecordFactory { private : map<RECORD_TYPE_en, Record* > m_oMapRecordReference; public : RecordFactory() { m_oMapRecordReference[CAR] = new CarRecord("Ferrari", 5050); m_oMapRecordReference[BIKE] = new BikeRecord("Yamaha", 2525); m_oMapRecordReference[PERSON] = new PersonRecord("Tom", 25); } ~RecordFactory() { delete m_oMapRecordReference[CAR]; delete m_oMapRecordReference[BIKE]; delete m_oMapRecordReference[PERSON]; } Record* CreateRecord(RECORD_TYPE_en enType) { return m_oMapRecordReference[enType]->Clone(); } }; int main() { RecordFactory* poRecordFactory = new RecordFactory(); Record* poRecord; poRecord = poRecordFactory->CreateRecord(CAR); poRecord->Print(); delete poRecord; poRecord = poRecordFactory->CreateRecord(BIKE); poRecord->Print(); delete poRecord; poRecord = poRecordFactory->CreateRecord(PERSON); poRecord->Print(); delete poRecord; delete poRecordFactory; return 0; }
반응형'Programming > 패턴' 카테고리의 다른 글
객체 생성 : 팩토리 메서드 ( Factory Method ) (0) 2020.11.09 UML 관계 종류 (0) 2020.09.22 객체 생성 : 빌더 패턴 ( Builder Pattern ) (0) 2020.09.22 객체 생성 : 추상 팩토리 패턴 ( Abstract Factory Pattern ) (0) 2020.09.04 객체 생성 : 싱글턴 패턴 ( Singleton Pattern ) (0) 2020.05.04