Wzorce projektowe (6)

Autor: Damian Chodorek • Opublikowany: 21 lipca 2015 • Kategoria: kursy, wzorce projektowe

Prototyp.

Prototyp to wzorzec obiektowy. Jego celem jest określenie grupy obiektów za pomocą jednego egzemplarza zwanego prototypem. Tworzenie nowych obiektów następuje za pomocą powielania prototypu.

Klasy

class Prototype{/*
abstrakcyjna klasa, po której dziedziczą konkretne prototypy
*/};

class ConcretePrototype: public Prototype{/*
konkretny prototyp, reprezentuje konkretny produkt, posiada metodę clone(), która zwraca kopię instancji obiektu za pomocą konstruktora kopiującego
*/};

class Manager{/*
przechowuje wszystkie prototypy, zwraca kopię odpowiedniego na podstawie parametru
*/};

class Client{/*
korzysta z interfejsu Managera
*/};

Etapy działania

  1. Tworzymy managera, który posiada wszystkie prototypy, a jeśli nie to sami je umieszczamy.
  2. Przekazując odpowiedni parametr otrzymujemy kopię zadanego produktu.

Konsekwencje

  1. Zwalnia klienta ze znajomości sposobu tworzenia produktu.
  2. Można z tego zrobić fabrykę obiektów, która używa kopiowania zamiast inicjalizacji.
  3. Kopiowanie jest dla dużych obiektów mniej kosztowne niż tworzenie.

Przykład

#include <iostream>
#include <map>
#include <string>

 
using namespace std;
 
enum RECORD_TYPE_en
{
  CAR,
  BIKE,
  PERSON
};
 
/**
 * Record jest prototypem
 */
 
class Record
{
  public :
 
    Record() {}
 
    virtual ~Record() {}
 
    virtual Record* Clone() const=0;
 
    virtual void Print() const=0;
};
 
/**
 * CarRecord jest konkretnym prototypem
 */
 
class CarRecord : public Record
{
  private :
    string m_oStrCarName;
 
    int ID;
 
  public :
 
    CarRecord(const string& _oStrCarName, int id)
      : Record(), m_oStrCarName(_oStrCarName),
        ID(id)
    {
    }
 
    CarRecord(const CarRecord& _oCarRecord)
      : Record()
    {
      m_oStrCarName = _oCarRecord.m_oStrCarName;
      ID = _oCarRecord.ID;
    }
 
    ~CarRecord() {}
 
    CarRecord* Clone() const
    {
      return new CarRecord(*this);
    }
 
    void Print() const
    {
      cout << "Car Record" << endl
        << "Name  : " << m_oStrCarName << endl
        << "Number: " << ID << endl << endl;
    }
};
 
 
/**
 * BikeRecord jest konkretnym prototypem
 */
 
class BikeRecord : public Record
{
  private :
    string m_oStrBikeName;
 
    int ID;
 
  public :
    BikeRecord(const string& _oStrBikeName, int id)
      : Record(), m_oStrBikeName(_oStrBikeName),
        ID(id)
    {
    }
 
    BikeRecord(const BikeRecord& _oBikeRecord)
      : Record()
    {
      m_oStrBikeName = _oBikeRecord.m_oStrBikeName;
      ID = _oBikeRecord.ID;
    }
 
    ~BikeRecord() {}
 
    BikeRecord* Clone() const
    {
      return new BikeRecord(*this);
    }
 
    void Print() const
    {
      cout << "Bike Record" << endl
        << "Name  : " << m_oStrBikeName << endl
        << "Number: " << ID << endl << endl;
    }
};
 
 
/**
 * PersonRecord to konkretny prototyp
 */
 
class PersonRecord : public Record
{
  private :
    string m_oStrPersonName;
 
    int Age;
 
  public :
    PersonRecord(const string& _oStrPersonName, int age)
      : Record(), m_oStrPersonName(_oStrPersonName),
        Age(age)
    {
    }
 
    PersonRecord(const PersonRecord& _oPersonRecord)
      : Record()
    {
      m_oStrPersonName = _oPersonRecord.m_oStrPersonName;
      Age = _oPersonRecord.Age;
    }
 
    ~PersonRecord() {}
 
    Record* Clone() const
    {
      return new PersonRecord(*this);
    }
 
    void Print() const
    {
      cout << "Person Record" << endl
        << "Name : " << m_oStrPersonName << endl
        << "Age  : " << Age << endl << endl ;
    }
};
 
 
/**
 * RecordFactory - manager
 */
 
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;
}

Źródło: https://it.wikipedia.org/wiki/Prototype_pattern.

część 7

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.