Шаблон фабричного метода использует наследование, в то время как абстрактный фабричный шаблон использует композицию как?

Я рассматриваю разницу между абстрактным фабричным шаблоном и фабричным методом.
Я понял, что Factory Method используется для создания только одного продукта, но Abstract Factory — это создание семейств связанных или зависимых продуктов.
Но как шаблон фабричного метода использует наследование, а абстрактный фабричный шаблон использует композицию, мне неясно.

Я знаю, что об этом спрашивали пару раз. Может ли кто-нибудь объяснить с помощью приведенного ниже кода, как происходит наследование и состав?

Заводской код метода

class IRose
{
public:
virtual string Color(void)=0;
};

class RedRose: public IRose
{
public:
string Color(void)
{
return "Red";
}
};

class YellowRose: public IRose
{
public:
string Color(void)
{
return "Yellow";
}
};

class IFactory
{
public:
virtual IRose* Create(string type)=0;
//The factory create method in 90% of cases will take a parameter which
//determines what kind of the object the factory will return.
};

class Factory: public IFactory
{
public:
IRose* Create(string type)
{
if ("Red" == type)
return new RedRose();

if ("Yellow" == type)
return new YellowRose();

return NULL;
}
};

int main()
{
IRose* p = NULL;
IFactory* f = NULL;

f = new Factory();  //You have to create an INSTANCE of the factory

p = f->Create("Red");
cout<<"\nColor is: "<<p->Color()<<"\n";
delete p;
p = f->Create("Yellow");
cout<<"\nColor is: "<<p->Color()<<"\n";
delete p;
return 1;
}

Абстрактный заводской код.

class IFridge
{
public:
virtual string Run(void) = 0;
};

class FridgeSamsung : public IFridge
{
public:
string Run(void)
{
return "You are now running Samsung Fridge\n";
}
};

class FridgeWhirlpool : public IFridge
{
public:
string Run(void)
{
return "You are now running Whirlpool Fridge\n";
}
};

class IWashingMachine
{
public:
virtual string Run(void) = 0;
};

class WashingMachineSamsung : public IWashingMachine
{
public:
string Run(void)
{
return "You are now running Samsung Washing Machine\n";
}
};

class WashingMachineWhirlpool : public IWashingMachine
{
public:
string Run(void)
{
return "You are now running Whirlpool Washing Machine\n";
}
};

class IFactory
{
public:
virtual IFridge* GetFridge(void) = 0;
virtual IWashingMachine* GetWashingMachine(void) = 0;
};

class FactorySamsung : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeSamsung();
}

IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineSamsung();
}
};

class FactoryWhirlpool : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeWhirlpool();
}

IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineWhirlpool();
}
};

int main()
{
IFridge* fridge;    //Client just knows about fridge and washingMachine.
IWashingMachine* washingMachine; //and factory. He will write operations which
IFactory* factory; //work on fridges and washingMachines.

factory = new FactorySamsung;
//This is the only place where the client
//has to make a choice.

//The rest of the code below will remain same, even
//if the factory is changed. He can change the factory and the same range
//of products but from a different factory will be returned. No need to
//change any code.

fridge = factory->GetFridge();
cout << fridge->Run();
washingMachine = factory->GetWashingMachine();
cout << washingMachine->Run();
cout << "\n";

delete factory;
factory = new FactoryWhirlpool;

//See same client code.
fridge = factory->GetFridge();
cout << fridge->Run();
washingMachine = factory->GetWashingMachine();
cout << washingMachine->Run();
cout << "\n";
delete factory;
return 1;
}

1

Решение

Это пересмотренный ответ после некоторой мысли.

Фабричный метод: Обычно createObject () является методом объекта Creator.

Абстрактная ФабрикаОбычно фабричный объект является атрибутом объекта-создателя.

Предположим теперь, что createObject () и Factory Object принадлежат их соответствующим создателям.

Фабричный метод: createObject () может измениться в подклассах Создателя. Это происходит путем изменения реализация of creatObject () через наследство.

Абстрактная Фабрика: Фабричный объект также может меняться в подклассах Создателя. Однако это изменение происходит замена один Фабричный объект с другим Фабричным объектом, т.е. объект Создатель изменяется на состав.

В вашей демоверсии creatObject () и Factory Object являются внешними по отношению к Создателю (ям), поэтому скрывается различие между составом / наследованием!

У Кристофера Охрави есть отличные видео YouTube о шаблонах.

Фабричный метод https://www.youtube.com/watch?v=EcFVTgRHJLM&Индекс = 4&список = PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc

Абстрактная Фабрика https://www.youtube.com/watch?v=v-GiuMmsXj4&Индекс = 5&список = PLrhzvIcii6GNjpARdnO4ueTUAVR9eMBpc

Как и было запрошено, здесь есть версия Factory Method (на этот раз в C ++!).
Если вам нужна помощь переводчика, дайте мне знать.

class IRose
{
public:
virtual const char * Color(void) = 0;
};

class RedRose : public IRose
{
public:
const char * Color(void)
{
return "I am a Red rose";
}
};

class YellowRose : public IRose
{
public:
const char * Color(void)
{
return "I am a Yellow rose";
}
};

class RoseGarden
{
protected: class IRose* rose;   // a pointer to the garden's rose

public:
virtual void createRose() { }  // abstract Factory Method

public: void sayColor() {
cout << rose->Color() << '\n';
}
};

class RedRoseGarden : public RoseGarden
{
public:
void createRose()
{
this->rose = new RedRose();   // concrete factory method
}
};

class YellowRoseGarden : public RoseGarden
{
public:
void createRose()
{
this->rose = new YellowRose();  // concrete factory method
}
};

int main()
{
RoseGarden * garden = NULL;

garden = new YellowRoseGarden;
garden->createRose();      // correct factory method is chosen via inheritance
garden->sayColor();
delete garden;

garden = new RedRoseGarden;
garden->createRose();      // correct factory method is chosen via inheritance
garden->sayColor();
delete garden;

return 1;
}

Также здесь есть немного измененная версия Abstract Factory, чтобы лучше показать, как она используется. Просто добавил объект дома. Обратите внимание, что я изменил все ваши «строковые» объекты на const char * для моего компилятора.

// make different types of fridges
class IFridge
{
public:
virtual const char* Run(void) = 0;
};

class FridgeSamsung : public IFridge
{
public:
const char* Run(void)
{
return "This house has a Samsung Fridge\n";
}
};

class FridgeWhirlpool : public IFridge
{
public:
const char* Run(void)
{
return "This house has a Whirlpool Fridge\n";
}
};

// make different types of washing machine
class IWashingMachine
{
public:
virtual const char*  Run(void) = 0;
};

class WashingMachineSamsung : public IWashingMachine
{
public:
const char* Run(void)
{
return "This house has a Samsung Washing Machine\n";
}
};

class WashingMachineWhirlpool : public IWashingMachine
{
public:
const char* Run(void)
{
return "This house has a Whirlpool Washing Machine\n";
}
};

// make different type of factory
class IFactory
{
public:
virtual IFridge* GetFridge(void) = 0;
virtual IWashingMachine* GetWashingMachine(void) = 0;
};

class FactorySamsung : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeSamsung();
}

IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineSamsung();
}
};

class FactoryWhirlpool : public IFactory
{
IFridge* GetFridge(void)
{
return new FridgeWhirlpool();
}

IWashingMachine* GetWashingMachine(void)
{
return new WashingMachineWhirlpool();
}
};

// Make a house object that has a fridge and a washing machine
class House
{
private:
class  IWashingMachine * washingMachine;
class  IFridge * fridge;

public:
House(IFactory * houseFactory) {
washingMachine = houseFactory->GetWashingMachine();
fridge = houseFactory->GetFridge();
}
void showAppliances() {
cout << washingMachine->Run();
cout << fridge->Run();
}
};

int main()
{
class IFactory * factory;
class House * house;

// make a samsung house
factory = new FactorySamsung;
house = new House(factory);     // passing the factory by injection
house->showAppliances();        // now we have a Samsung house
cout << '\n';

// clean up
delete house;
delete factory;

// make a whirlpool house
factory = new FactoryWhirlpool;
house = new House(factory);    // passing the factory by injection
house->showAppliances();       // now we have a WHilepool house
cout << '\n';

// clean up
delete house;
delete factory;

return 1;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector