Метод Фабрика (шаблон)
от Уикипедия, свободната енциклопедия
UML диаграма на Метод Фабрика
Метод Фабрика е създаващ шаблон за дизайн, който се използва в обектно-ориентираното програмиране.
Фабриката има за цел инстанцирането на различни обекти, чиито типове не са предефинирани. Обектите се създават динамично в зависимост от параметрите предадени на фабриката. По принцип фабриките са единствени в дадена програма, затова за създаването им често се използва шаблонът Сек (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[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(); } }
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[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}
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