Метод Фабрика (шаблон)
Облик
За информацията в тази статия или раздел не са посочени източници. Въпросната информация може да е непълна, неточна или изцяло невярна. Имайте предвид, че това може да стане причина за изтриването на цялата статия или раздел. |

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