Фабрика (шаблон проектирования)

Фабрика (шаблон проектирования)

Фабричный метод (англ. Factory Method)порождающий шаблон проектирования, предоставляющий подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс инстанциировать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне. Также известен под названием виртуальный конструктор.

Содержание

Цель

Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанциировать. Фабричный метод позволяет классу делегировать создание подклассам. Используется, когда:

  • классу заранее неизвестно, объекты каких подклассов ему нужно создавать.
  • класс спроектирован так, чтобы объекты, которые он создаёт, специфицировались подклассами.
  • класс делегирует свои обязанности одному из нескольких вспомогательных подклассов, и планируется локализовать знание о том, какой класс принимает эти обязанности на себя.

Структура

Фабричный метод (Factory Method)

  • Product - продукт
    • определяет интерфейс объектов, создаваемых абстрактным методом;
  • ConcreteProduct - конкретный продукт
    • реализует интерфейс Product;
  • Creator - создатель
    • объявляет фабричный метод, который возвращает объект типа Product. Может также содержать реализацию этого метода "по умолчанию";
    • может вызывать фабричный метод для создания объекта типа Product;
  • ConcreteCreator - конкретный создатель
    • переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект класса ConcreteProduct.

Плюсы

  • позволяет сделать код создания объектов более универсальным, не привязываясь к конкретным классам (ConcreteProduct), а оперируя лишь общим интерфейсом (Product);
  • позволяет установить связь между параллельными иерархиями классов.

Минусы

  • необходимость создавать наследника Creator для каждого нового типа продукта (ConcreteProduct).

Примеры

 public class FactoryMethodExample
 {
     public static void main(String[] args)
     {
         // an array of creators
         Creator[] creators = new Creator[2];
         creators[0] = new ConcreteCreatorA();
         creators[1] = new ConcreteCreatorB();
 
         // iterate over creators and create products
         for (Creator creator: creators)
         {
             Product product = creator.factoryMethod();
             System.out.printf("Created {%s}\n", product.getClass());
         }
     }
 }
 
 // Product
 abstract class Product
 {
 }
 
 // ConcreteProductA
 class ConcreteProductA extends Product
 {
 }
 
 // ConcreteProductB
 class ConcreteProductB extends Product
 {
 }
 
 // Creator
 abstract class Creator
 {
     public abstract Product factoryMethod();
 }
 
 // У этого класса может быть любое кол-во наследников.
 // Для создания нужного нам объекта можно написать следующие Фабрики: ConcreteCreatorA, ConcreteCreatorB
 
 // ConcreteCreatorA
 class ConcreteCreatorA extends Creator
 {
     @Override
     public Product factoryMethod()
     {
         return new ConcreteProductA();
     }
 }
 
 // ConcreteCreatorB
 class ConcreteCreatorB extends Creator
 {
     @Override
     public Product factoryMethod()
     {
         return new ConcreteProductB();
     }
 }

Результат работы:
Created {class ConcreteProductA}
Created {class ConcreteProductB}

C++

#include<iostream>
#include<string>
using namespace std;
 
// "Product"
class Product{
public:
	virtual string getName() = 0;
};
 
// "ConcreteProductA"
class ConcreteProductA : public Product{
public:
	string getName(){
		return "ConcreteProductA";
	}
};
 
// "ConcreteProductB"
class ConcreteProductB : public Product{
public:
	string getName(){
		return "ConcreteProductB";
	}
};
 
// "Creator"
class Creator{
public: 
	virtual Product* FactoryMethod() = 0;
};
 
// "ConcreteCreatorA"
class ConcreteCreatorA : public Creator{
public:
	Product* FactoryMethod() {
		return new ConcreteProductA();
	}
};
 
// "ConcreteCreatorB"
class ConcreteCreatorB : public Creator{
public: 
	Product* FactoryMethod() {
		return new ConcreteProductB();
	}
};
 
int main(){
	const int size = 2;
	// An array of creators
	Creator* creators[size];
      creators[0] = new ConcreteCreatorA();
      creators[1] = new ConcreteCreatorB();    
 
 
	// Iterate over creators and create products
	for(int i=0;i<size;i++){
		Product* product = creators[i]->FactoryMethod();
		cout<<product->getName()<<endl;
		delete product;
	}
 
	int a;
	cin>>a;
 
	for(int i=0;i<size;i++){
		delete creators[i];
	}
	return 0;
}

C#

 // Factory Method pattern -- Structural example
 
  class MainApp
  {
    static void Main()
    {
      // An array of creators
      Creator[] creators = new Creator[2];
      creators[0] = new ConcreteCreatorA();
      creators[1] = new ConcreteCreatorB();
 
      // Iterate over creators and create products
      foreach(Creator creator in creators)
      {
        Product product = creator.FactoryMethod();
        Console.WriteLine("Created {0}",
          product.GetType().Name);
      }
 
      // Wait for user
      Console.Read();
    }
  }
 
  // "Product"
 
  abstract class Product
  {
  }
 
  // "ConcreteProductA"
 
  class ConcreteProductA : Product
  {
  }
 
  // "ConcreteProductB"
 
  class ConcreteProductB : Product
  {
  }
 
  // "Creator"
 
  abstract class Creator
  {
    public abstract Product FactoryMethod();
  }
 
  // "ConcreteCreatorA"
 
  class ConcreteCreatorA : Creator
  {
    public override Product FactoryMethod()
    {
      return new ConcreteProductA();
    }
  }
 
  // "ConcreteCreatorB"
 
  class ConcreteCreatorB : Creator
  {
    public override Product FactoryMethod()
    {
      return new ConcreteProductB();
    }
  }

// "интерфейс" Product
function Product() {}
 
// ConcreteProduct (реализация Product)
function ProductA() {}
ProductA.prototype = new Product();
ProductA.prototype.constructor = ProductA;
 
function ProductB() {}
ProductB.prototype = new Product();
ProductB.prototype.constructor = ProductB;
 
// "интерфейс" Creator
function Creator() {
	this.factoryMethod = function() {};
}
 
// ConcreteCreator (реализация Creator)
function CreatorA() {
	this.factoryMethod = function() {
		return new ProductA();
	};
}
CreatorA.prototype = new Creator();
CreatorA.prototype.constructor = CreatorA;
 
function CreatorB() {
	this.factoryMethod = function() {
		return new ProductB();
	};
}
CreatorB.prototype = new Creator();
CreatorB.prototype.constructor = CreatorB;
 
// использование:
var creatorA = new CreatorA();
var creatorB = new CreatorB();
 
var productA1 = creatorA.factoryMethod();
var productA2 = creatorA.factoryMethod();
var productB1 = creatorB.factoryMethod();

PHP5

abstract class User{
 
	function __construct($name){
	$this->name = $name;
	}
 
	function getName(){
	return $this->name;
	}
 
	// Permission methods
	function hasReadPermission(){
	return true;
	}
 
	function hasModifyPermission(){
	return false;
	}
 
	function hasDeletePermission(){
	return false;
	}
 
	// Customization methods
	function wantsFlashInterface(){
	return true;
	}
 
	protected $name = NULL;
}
 
class GuestUser extends User {
}
 
class CustomerUser extends User {
	function hasModifyPermission(){
	return true;
	}
}
 
class AdminUser extends User {
	function hasModifyPermission(){
	return true;
	}
 
	function hasDeletePermission(){
	return true;
	}
 
	function wantsFlashInterface(){
	return false;
	}
}
 
class UserFactory {
	private static $users = array("Andi"=>"admin", "Stig"=>"guest", "Derick"=>"customer");
 
	static function Create($name){
		if(!isset(self::$users[$name])){
		// Error out because the user doesn't exist
		}
		switch(self::$users[$name]){
		case "guest": return new GuestUser($name);
		case "customer": return new CustomerUser($name);
		case "admin": return new AdminUser($name);
		default: // Error out because the user kind doesn't exist
		}
	}
}
 
function boolToStr($b){
	if($b == true){
	return "Yes\n";
	}
	else{
	return "No\n";
	}
}
 
function displayPermissions(User $obj){
	print $obj->getName()."'s permissions:\n";
	print "Read: ".boolToStr($obj->hasReadPermission());
	print "Modify: ".boolToStr($obj->hasModifyPermission());
	print "Delete: ".boolToStr($obj->hasDeletePermission());
}
function displayRequirements(User $obj){
	if ($obj->wantsFlashInterface()) {
	print $obj->getName()." requires Flash\n";
	}
}
 
$logins = array("Andi", "Stig", "Derick");
 
foreach($logins as $login){
	displayPermissions(UserFactory::Create($login));
	displayRequirements(UserFactory::Create($login));
}

См. также

Литература

  • Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. — СПб: «Питер», 2007. — С. 366. — ISBN 978-5-469-01136-1 (также ISBN 5-272-00355-1)



порождающие шаблоны проектирования
[править]
абстрактная фабрика | строитель | фабричный метод | прототип | одиночка | отложенная инициализация

ghdndnfg


Wikimedia Foundation. 2010.

Игры ⚽ Поможем написать курсовую

Полезное


Смотреть что такое "Фабрика (шаблон проектирования)" в других словарях:

  • Абстрактная фабрика (шаблон проектирования) — Шаблон проектирования Абстрактная фабрика Abstract factory Тип: порождающий Описан в Design Patterns Да Абстрактная фабрика (англ. Abstract factory) порождающий шаблон проектирования, позволяющий изменять поведение системы …   Википедия

  • Шаблон проектирования — У этого термина существуют и другие значения, см. Паттерн. В разработке программного обеспечения, шаблон проектирования или паттерн (англ. design pattern) повторимая архитектурная конструкция, представляющая собой решение проблемы… …   Википедия

  • Интерфейс (шаблон проектирования) — Шаблон проектирования Интерфейс Interface Описан в Design Patterns Нет В информатике, шаблон интерфейса не является особым шаблоном среди шаблонов проектирования. Он является общим методом для структурирования компьютерных программ для того …   Википедия

  • Состояние (шаблон проектирования) — Шаблон проектирования Состояние State Тип: поведенческий Описан в Design Patterns Да Состояние (англ. State)  шаблон проектирования. Используется в тех случаях, когда во время выполнения программы объект …   Википедия

  • Приспособленец (шаблон проектирования) — Шаблон проектирования Приспособленец Flyweight Тип: структурный Описан в Design Patterns Да Приспособленец (англ. Flyweight)  это объект, представляющий себя как уникальный экземпляр в разных местах программы, но по факту не… …   Википедия

  • Хранитель (шаблон проектирования) — Шаблон проектирования Хранитель Memento Тип: поведенческий Описан в Design Patterns Да Хранитель (также известный как Memento, Token, Лексема) поведенческий шаблон проектирования. Позволяет, не нарушая инкапсуляцию, зафикс …   Википедия

  • Итератор (шаблон проектирования) — Шаблон проектирования Итератор Iterator Тип: поведенческий Описан в Design Patterns Да Шаблон Iterator (также известный как Cursor)  Шаблон проектирования, относится к паттернам поведения. Представляет собой объект, позволяющий получить …   Википедия

  • Интерпретатор (шаблон проектирования) — Шаблон проектирования Интерпретатор Interpreter Тип: поведенческий Назначение: решает часто встречающуюся, подверженную изменениям задачу Описан в Design Patterns Да Шаблон Интерпретатор (англ.  …   Википедия

  • Компоновщик (шаблон проектирования) — Шаблон проектирования Компоновщик Composite Тип: структурный Описан в Design Patterns Да Компоновщик (англ. Composite pattern) шаблон проектирования, относится к структурным паттернам, объединяет объек …   Википедия

  • Адаптер (шаблон проектирования) — У этого термина существуют и другие значения, см. Адаптер. Шаблон проектирования Адаптер Adapter …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»