Метод Фабрика е създаващ шаблон за дизайн, който се използва в обектно-ориентираното програмиране.

Фабриката има за цел инстанцирането на различни обекти, чиито типове не са предефинирани. Обектите се създават динамично в зависимост от параметрите предадени на фабриката. По принцип фабриките са единствени в дадена програма, затова за създаването им често се използва шаблонът Сек (Singleton).

Примери 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 = new ConcreteCreatorA(); creators = 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; creators = new ConcreteCreatorA(); creators = 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();

Java abstract class Pizza { public abstract double getPrice(); }

class HamAndMushroomPizza extends Pizza { private double price = 8.5;

public double getPrice() { return price;

class DeluxePizza extends Pizza { private double price = 10.5;

public double getPrice() { return price;

class HawaiianPizza extends Pizza { private double price = 11.5;

public double getPrice() { return price;

class PizzaFactory { public enum PizzaType { HamMushroom, Deluxe, Hawaiian

public static Pizza createPizza(PizzaType pizzaType) { switch (pizzaType) { case HamMushroom: return new HamAndMushroomPizza(); case Deluxe: return new DeluxePizza(); case Hawaiian: return new HawaiianPizza();

throw new IllegalArgumentException("The pizza type " + pizzaType + " is not recognized.");

class PizzaLover { /** * Create all available pizzas and print their prices */ public static void main (String args[]) { for (PizzaFactory.PizzaType pizzaType: PizzaFactory.PizzaType.values()) { System.out.println("Price of " + pizzaType + " is " + PizzaFactory.createPizza(pizzaType).getPrice());

public class FactoryMethodExample { public static void main(String[] args)

// an array of creators Creator[] creators = new Creator; creators = new ConcreteCreatorA(); creators = 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}

Perl START ===== D:\etl\Perl\DesignPatterns\RunFactoryDesignPattern.cmd perl -w "D:\etl\Perl\DesignPatterns\RunFactoryDesignPattern.pl"

pause END ================== D:\etl\Perl\DesignPatterns\RunFactoryDesignPattern.cmd

. START ===== D:\etl\Perl\DesignPatterns\RunFactoryDesignPattern.pl use strict; use warnings;

use GreetFactory;

my $greeter_n = GreetFactory->instantiate("Repeat", "I am repeating Hello x amount of times \n", 3); $greeter_n->greet();

my $greeter_stamp = GreetFactory->instantiate("Stamp", "The Stamp says Good-bye\n"); $greeter_stamp->greet(); END ================== D:\etl\Perl\DesignPatterns\RunFactoryDesignPattern.pl

. START ===== D:\etl\Perl\DesignPatterns\GreetFactory.pm package GreetFactory; use strict; use warnings;

# ARHH NO TIME HARDCODING ... BEGIN{ push @INC, 'D:/etl/Perl/DesignPatterns'; }

sub instantiate { my $class = shift; my $requested_type = shift; my $location = "Greet/$requested_type.pm"; my $class = "Greet::$requested_type";

require $location;

return $class->new(@_);

1; END ================== D:\etl\Perl\DesignPatterns\GreetFactory.pm

. START ===== D:\etl\Perl\DesignPatterns\Greet\Repeat.pm package Greet::Repeat;

sub new { my $class = shift; my $self = { greeting => shift, repeat => shift,

return bless $self, $class; }

sub greet { my $self = shift; print ($self->{greeting} x $self->{repeat}); }

1; END ================== D:\etl\Perl\DesignPatterns\Greet\Repeat.pm

. START ===== D:\etl\Perl\DesignPatterns\Greet\Stamp.pm package Greet::Stamp; use strict; use warnings;

sub new { my $class = shift; my $greeting = shift; return bless \$greeting, $class; }

sub greet { my $greeting = shift; my $stamp = timestamp(); print "$stamp $$greeting"; }

sub timestamp { # # Purpose: returns the time in yyyymmdd-format # my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); #---- change 'month'- and 'year'-values to correct format ---- $min = "0$min" if ($min < 10); $hour = "0$hour" if ($hour < 10); $mon = $mon + 1; $mon = "0$mon" if ($mon < 10); $year = $year + 1900; $mday = "0$mday" if ($mday < 10); return "$year$mon$mday" . "_" . "$hour$min" . "_" . $sec; }

1; END ================== D:\etl\Perl\DesignPatterns\Greet\Stamp.pm

Категория:Шаблони за софтуерен дизайн