Абстрактная фабрика (шаблон проектирования)
Материал из Википедии — свободной энциклопедии
| Это незавершённая статья по информатике. Вы можете помочь проекту, исправив и дополнив её. |
Абстрактная фабрика, Abstract factory — шаблон проектирования, позволяющий изменять поведение системы, варьируя создаваемые объекты, при этом сохраняя интерфейсы. Он позволяет создавать целые группы взаимосвязанных объектов, которые, будучи созданными одной фабрикой, реализуют общее поведение. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы (например, для оконного интерфейса, он может создавать окна и кнопки). Затем пишутся наследующиеся от него классы, реализующие этот интерфейс.
Содержание |
[править] Цель
Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов
[править] Плюсы
- изолирует конкретные классы;
- упрощает замену семейств продуктов;
- гарантирует сочетаемость продуктов.
[править] Минусы
- сложно добавить поддержку нового вида продуктов.
[править] Применимость
Система не должна зависеть от того, как создаются, компонуются и представляются входящие в нее объекты; Входящие в семейство взаимосвязанные объекты должны использоваться вместе и вам необходимо обеспечить выполнение этого ограничения; Система должна конфигурироваться одним из семейств составляющих ее объектов; требуется предоставить библиотеку объектов, раскрывая только их интерфейсы, но не реализацию.
[править] Пример Java
// Factories package com.apwebco.patterns.gof.abstractfactory; public abstract class FinancialToolsFactory { public abstract TaxProcessor createTaxProcessor(); public abstract ShipFeeProcessor createShipFeeProcessor(); } public class CanadaFinancialToolsFactory extends FinancialToolsFactory { public TaxProcessor createTaxProcessor() { return new CanadaTaxProcessor(); } public ShipFeeProcessor createShipFeeProcessor() { return new CanadaShipFeeProcessor(); } } public class EuropeFinancialToolsFactory extends FinancialToolsFactory { public TaxProcessor createTaxProcessor() { return new EuropeTaxProcessor(); } public ShipFeeProcessor createShipFeeProcessor() { return new EuropeShipFeeProcessor(); } } // Products public abstract class ShipFeeProcessor { abstract void calculateShipFee(Order order); } public abstract class TaxProcessor { abstract void calculateTaxes(Order order); } public class EuropeShipFeeProcessor extends ShipFeeProcessor { public void calculateShipFee(Order order) { // insert here Europe specific ship fee calculation } } public class CanadaShipFeeProcessor extends ShipFeeProcessor { public void calculateShipFee(Order order) { // insert here Canada specific ship fee calculation } } public class EuropeTaxProcessor extends TaxProcessor { public void calculateTaxes(Order order) { // insert here Europe specific taxt calculation } } public class CanadaTaxProcessor extends TaxProcessor { public void calculateTaxes(Order order) { // insert here Canada specific taxt calculation } } // Client public class OrderProcessor { private TaxProcessor taxProcessor; private ShipFeeProcessor shipFeeProcessor; public OrderProcessor(FinancialToolsFactory factory) { taxProcessor = factory.createTaxProcessor(); shipFeeProcessor = factory.createShipFeeProcessor(); } public void processOrder (Order order) { // .... taxProcessor.calculateTaxes(order); shipFeeProcessor.calculateShipFee(order); // .... } } // Integration with the overall application public class Application { public static void main(String[] args) { // ..... String countryCode = "EU"; Customer customer = new Customer(); Order order = new Order(); OrderProcessor orderProcessor = null; FinancialToolsFactory factory = null; if (countryCode == "EU") { factory = new EuropeFinancialToolsFactory(); } else if (countryCode == "CA") { factory = new CanadaFinancialToolsFactory(); } orderProcessor = new OrderProcessor(factory); orderProcessor.processOrder(order); } }
[править] Пример С++
#include <iostream> // AbstractProductA class ICar { public: virtual void info() = 0; }; // ConcreteProductA1 class Ford : public ICar { public: virtual void info() { std::cout << "Ford" << std::endl; } }; //ConcreteProductA2 class Toyota : public ICar { public: virtual void info() { std::cout << "Toyota" << std::endl; } }; // AbstractProductB class IEngine { public: virtual void getPower() = 0; }; // ConcreteProductB1 class FordEngine : public IEngine { public: virtual void getPower() { std::cout << "Ford Engine 4.4" << std::endl; } }; //ConcreteProductB2 class ToyotaEngine : public IEngine { public: virtual void getPower() { std::cout << "Toyota Engine 3.2" << std::endl; } }; // AbstractFactory class CarFactory { public: ICar* getNewCar() { return createCar(); } IEngine* getNewEngine() { return createEngine(); } protected: virtual ICar* createCar() = 0; virtual IEngine* createEngine() = 0; }; // ConcreteFactory1 class FordFactory : public CarFactory { protected: // from CarFactory virtual ICar* createCar() { return new Ford(); } virtual IEngine* createEngine() { return new FordEngine(); } }; // ConcreteFactory2 class ToyotaFactory : public CarFactory { protected: // from CarFactory virtual ICar* createCar() { return new Toyota(); } virtual IEngine* createEngine() { return new ToyotaEngine(); } }; int main() { CarFactory* curFactory = NULL; ICar* myCar = NULL; IEngine* myEngine = NULL; ToyotaFactory toyotaFactory; FordFactory fordFactory; curFactory = &toyotaFactory; myCar = curFactory->getNewCar(); myCar->info(); myEngine = curFactory->getNewEngine(); myEngine->getPower(); delete myCar; delete myEngine; curFactory = &fordFactory; myCar = curFactory->getNewCar(); myCar->info(); myEngine = curFactory->getNewEngine(); myEngine->getPower(); delete myCar; delete myEngine; return 0; }
[править] Пример С#
class MainApp { public static void Main() { // Abstract factory #1 AbstractFactory factory1 = new ConcreteFactory1(); Client c1 = new Client(factory1); c1.Run(); // Abstract factory #2 AbstractFactory factory2 = new ConcreteFactory2(); Client c2 = new Client(factory2); c2.Run(); // Wait for user input Console.Read(); } } // "AbstractFactory" abstract class AbstractFactory { public abstract AbstractProductA CreateProductA(); public abstract AbstractProductB CreateProductB(); } // "ConcreteFactory1" class ConcreteFactory1 : AbstractFactory { public override AbstractProductA CreateProductA() { return new ProductA1(); } public override AbstractProductB CreateProductB() { return new ProductB1(); } } // "ConcreteFactory2" class ConcreteFactory2 : AbstractFactory { public override AbstractProductA CreateProductA() { return new ProductA2(); } public override AbstractProductB CreateProductB() { return new ProductB2(); } } // "AbstractProductA" abstract class AbstractProductA { } // "AbstractProductB" abstract class AbstractProductB { public abstract void Interact(AbstractProductA a); } // "ProductA1" class ProductA1 : AbstractProductA { } // "ProductB1" class ProductB1 : AbstractProductB { public override void Interact(AbstractProductA a) { Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } // "ProductA2" class ProductA2 : AbstractProductA { } // "ProductB2" class ProductB2 : AbstractProductB { public override void Interact(AbstractProductA a) { Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name); } } // "Client" - the interaction environment of the products class Client { private AbstractProductA AbstractProductA; private AbstractProductB AbstractProductB; // Constructor public Client(AbstractFactory factory) { AbstractProductB = factory.CreateProductB(); AbstractProductA = factory.CreateProductA(); } public void Run() { AbstractProductB.Interact(AbstractProductA); } }
[править] Object Pascal
program AbstractFactory; {$APPTYPE CONSOLE} uses SysUtils; type // AbstractProduct ICar = Class public function info: String; virtual; abstract; end; // ConcreteProductA Ford = Class(ICar) public function info: String; override; end; // ConcreteProductB Toyota = Class(ICar) public function info: String; override; end; // AbstractFactory CarFactory = Class public function CreateCar:ICar; virtual; abstract; end; // ConcreteFactoryA FordFactory = Class(CarFactory) private function CreateCar:ICar; override; end; // ConcreteFactoryB ToyotaFactory = Class(CarFactory) private function CreateCar:ICar; override; end; { Ford } function Ford.info: String; begin Result:='Ford'; end; { Toyota } function Toyota.info: String; begin Result:='Toyota'; end; { FordFactory } function FordFactory.CreateCar: ICar; begin Result:=Ford.Create; end; { ToyotaFactory } function ToyotaFactory.CreateCar: ICar; begin Result:=Toyota.Create; end; var CF: CarFactory; C: ICar; i: Char; begin writeln('Abstract factory'); writeln('ToyotaFactory'); Cf:= ToyotaFactory.Create; C:=CF.CreateCar; writeln(C.info); C.Free; Readln(i); writeln('FordFactory'); Cf:= FordFactory.Create; C:=CF.CreateCar; writeln(C.info); C.Free; Readln(i); end.
[править] См. также
[править] Литература
| порождающие шаблоны проектирования |
| абстрактная фабрика | строитель | фабричный метод | прототип | одиночка | ленивая инициализация |

