Метод Фабрика (шаблон)

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене
UML диаграма на Метод Фабрика

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

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

Примери[редактиране | edit source]

C++[редактиране | edit source]

#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#[редактиране | edit source]

 // 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[редактиране | edit source]

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[редактиране | edit source]

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