Fabrică abstractă (model de design)
Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de
versiunea revizuită la 2 martie 2018; verificările necesită
25 de modificări .
Fabrica de abstracte |
---|
fabrică abstractă |
Tip de |
generatoare |
Scop |
Oferă o interfață pentru crearea familiilor de obiecte înrudite sau interdependente fără a specifica clasele lor concrete. |
Structura |
|
Se aplică în cazuri |
- Când programul trebuie să fie independent de procesul și tipurile de obiecte noi create.
- Când este necesar să se creeze familii sau grupuri de obiecte interdependente, excluzând posibilitatea utilizării simultane a obiectelor din aceste seturi diferite în același context [1] .
|
pro |
- izolează clase specifice;
- simplifică înlocuirea familiilor de produse;
- garanteaza compatibilitatea produsului.
|
Minusuri |
- este dificil să adăugați suport pentru un nou tip de produs.
|
Descris în Design Patterns |
da |
O fabrică abstractă este un model de proiectare generativ care oferă o interfață pentru crearea unor familii de obiecte interconectate sau interdependente fără a specifica clasele lor concrete. Modelul este implementat prin crearea unei clase abstracte Factory, care este o interfață pentru crearea componentelor sistemului (de exemplu, pentru o interfață de fereastră, poate crea ferestre și butoane). Apoi sunt scrise clase care implementează această interfață [2] .
Numire
Oferă o interfață pentru crearea familiilor de obiecte înrudite sau interdependente fără a specifica clasele lor concrete.
Implementare
Pro
- izolează clase specifice;
- simplifică înlocuirea familiilor de produse;
- garanteaza compatibilitatea produsului.
Contra
- este dificil să adăugați suport pentru un nou tip de produs.
Aplicație
- Sistemul nu ar trebui să depindă de modul în care sunt create, asamblate și prezentate obiectele incluse în el.
- Obiectele înrudite dintr-o colecție trebuie utilizate împreună și trebuie să aplicați această restricție.
- Sistemul trebuie configurat de una dintre familiile obiectelor sale constitutive.
- Este necesar să se furnizeze o bibliotecă de obiecte, expunând doar interfețele lor, nu implementarea lor.
Exemple
Exemplu rapid
Cod sursă rapid
//: Loc de joacă - substantiv: un loc unde oamenii se pot juca
/// <summary>
/// Abstract factory class
/// </summary>
protocol AbstractFactory {
func createProductA () -> AbstractProductA
func createProductB () -> AbstractProductB
}
/// <summary>
/// Factory class #1
/// </summary>
class ConcreteFactory1 : AbstractFactory {
public func createProductA () -> AbstractProductA {
return ProductA1 ()
}
public func createProductB () -> AbstractProductB {
return ProductB1 ()
}
}
/// <summary>
/// Factory class #2
/// </summary>
class ConcreteFactory2 : AbstractFactory {
public func createProductA () -> AbstractProductA {
return ProductA2 ()
}
public func createProductB () -> AbstractProductB {
return ProductB2 ()
}
}
/// <summary>
/// Abstract product class A
/// </summary>
protocol AbstractProductA {}
//
/// <summary>
/// Abstract product class B
/// </summary>
protocol AbstractProductB {
func interacționează ( a : AbstractProductA )
}
/// <summary>
/// Prima clasă de produs de tip A
/// </summary>
clasa ProductA1 : AbstractProductA {}
/// <summary>
/// Prima clasă de produs de tip B
/// </summary>
class ProductB1 : AbstractProductB {
public func interact ( a : AbstractProductA ) {
print ( " \( type ( of : self ) )) interacționează cu \ ( tip ( de : a . sine )) " )
}
}
/// <summary>
/// A doua clasă de produs de tip A
/// </summary>
class ProductA2 : AbstractProductA {}
/// <summary>
/// A doua clasă de produs de tip B
/// </summary>
class ProductB2 : AbstractProductB {
public func interact ( a : AbstractProductA ) {
print ( " \( type ( of : self ) )) interacționează cu \ ( tip ( de : a . sine )) " )
}
}
/// <summary>
/// Clasa de client în care are loc interacțiunea dintre obiecte
/// </summary>
class Client {
private let _abstractProductA : AbstractProductA
private let _abstractProductB : AbstractProductB
// Constructor
public init ( fabrică : AbstractFactory ) {
_abstractProductB = fabrică . createProductB ();
_abstractProductA = fabrică . createProductA ();
}
public func run () {
_abstractProductB . interacționează ( a : _abstractProductA )
}
}
/// <summary>
/// Punct de intrare în aplicație
/// </summary>
// Apelarea abstract factory #1
let factory1 = ConcreteFactory1 ()
let client1 = Client ( fabrică : fabrică1 )
client1 . alerga ()
// Apelați abstract factory #2
let factory2 = ConcreteFactory2 ()
let client2 = Client ( fabrică : fabrică2 )
client2 . alerga ()
Exemplu în C# [3]
Cod sursă în
C Sharp
folosind System ;
namespace DoFactory.GangOfFour.Abstract.Structural
{
class MainApp
{
/// <summary>
/// Punct de intrare în aplicație
/// </summary>
public static void Main ()
{
// Apel de fabrică abstract # 1 Fabrica de
fabrică abstractă1 = new ConcreteFactory1 (); Client client1 = client nou ( fabrică1 ); client1 . alerga ();
// Apelați fabrică abstractă #2
AbstractFactory factory2 = new ConcreteFactory2 ();
Client client2 = client nou ( fabrică2 ); client2 . alerga ();
// Se așteaptă intrarea
Consolă . ReadKey ();
}
}
/// <summary>
/// Abstract factory class
/// </summary>
abstract class AbstractFactory
{
abstract public AbstractProductA CreateProductA (); abstract public AbstractProductB CreateProductB (); }
/// <summary>
/// Factory class #1
/// </summary>
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA ()
{
return new ProductA1 ();
}
public override AbstractProductB CreateProductB ()
{
return new ProductB1 ();
}
}
/// <summary>
/// Factory class #2
/// </summary>
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA ()
{
return new ProductA2 ();
}
public override AbstractProductB CreateProductB ()
{
return new ProductB2 ();
}
}
/// <summary>
/// Abstract product class A
/// </summary>
abstract class ProductA
{
}
/// <summary>
/// Abstract product class B
/// </summary>
abstract class AbstractProductB
{
public abstract void Interact ( AbstractProductA a );
}
/// <summary>
/// Prima clasă de produs de tip A
/// </summary>
clasa ProductA1 : AbstractProductA
{
}
/// <summary>
/// Prima clasă de produs de tip B
/// </summary>
class ProductB1 : AbstractProductB
{
public override void Interact ( AbstractProductA a )
{
Console . WriteLine ( acest . GetType (). Nume +
" interacționează cu " + a . GetType (). Nume );
}
}
/// <summary>
/// A doua clasă de produs de tip A
/// </summary>
class ProductA2 : AbstractProductA
{
}
/// <summary>
/// A doua clasă de produs de tip B
/// </summary>
class ProductB2 : AbstractProductB
{
public override void Interact ( AbstractProductA a )
{
Console . WriteLine ( acest . GetType (). Nume +
" interacționează cu " + a . GetType (). Nume );
}
}
/// <summary>
/// Clasa client în care are loc interacțiunea dintre obiecte
/// </summary>
class Client
{
private AbstractProductA _abstractProductA ;
privat AbstractProductB _abstractProductB ;
// Constructor
public Client ( AbstractFactory factory )
{
_abstractProductB = factory . CreateProductB ();
_abstractProductA = fabrică . CreateProductA ();
}
public void Run ()
{
_abstractProductB . Interact ( _abstractProductA );
}
}
}
Exemplu Java
Sursa
Java
clasă publică AbstractFactoryExample {
public static void main ( String [] args ) {
AbstractFactory fabrică1 = noua Fabrică de beton1 ();
Client client1 = client nou ( fabrică1 ); client1 . executa ();
Fabrica AbstractFactory2 = noua Fabrica de Beton2 (); Client client2 = client nou ( fabrică2 ); client2 . executa (); } }
class Client {
private AbstractProductA productA ;
privat AbstractProductB productB ;
Client ( fabrică AbstractFactory ) { produsA = fabrică . createProductA (); produsB = fabrică . createProductB (); }
void execute () {
produsB . interacționează ( produsA );
}
}
interfață AbstractFactory {
AbstractProductA createProductA ();
AbstractProductB createProductB ();
}
interfață AbstractProductA {
void interact ( AbstractProductB b );
}
interfață AbstractProductB {
void interact ( AbstractProductA a );
}
clasa ConcreteFactory1 implementează AbstractFactory {
@Override
public AbstractProductA createProductA () {
return new ProductA1 ();
}
@Override
public AbstractProductB createProductB () {
return new ProductB1 ();
}
}
clasa ConcreteFactory2 implementează AbstractFactory {
@Override
public AbstractProductA createProductA () {
return new ProductA2 ();
}
@Override
public AbstractProductB createProductB () {
return new ProductB2 ();
}
}
clasa ProductA1 implementează AbstractProductA {
@Override
public void interact ( AbstractProductB b ) {
System . afară . println ( acest . getClass (). getName () + " interactioneaza cu " + b . getClass (). getName ());
}
}
clasa ProductB1 implementează AbstractProductB {
@Override
public void interact ( AbstractProductA a ) {
System . afară . println ( acest . getClass (). getName () + " interactioneaza cu " + a . getClass (). getName ());
}
}
clasa ProductA2 implementează AbstractProductA {
@Override
public void interact ( AbstractProductB b ) {
System . afară . println ( acest . getClass (). getName () + " interactioneaza cu " + b . getClass (). getName ());
}
}
clasa ProductB2 implementează AbstractProductB {
@Override
public void interact ( AbstractProductA a ) {
System . afară . println ( acest . getClass (). getName () + " interactioneaza cu " + a . getClass (). getName ());
}
}
Exemplu PHP5
Cod sursă
PHP5
interfață IHead
{
funcția publică drawHead ( $x , $y ); }
class RedHead implementează IHead
{
public function drawHead ( $x , $y ) {
echo 'Capul tău roșu în axa x = ' . $x . ' și axa y = ' . $y . „</br>” . PHP_EOL ;
}
}
class WhiteHead implementează IHead
{
public function drawHead ( $x , $y ) {
echo 'Capul tău alb în axa x = ' . $x . ' și axa y = ' . $y . „</br>” . PHP_EOL ;
}
}
interfață IBody
{
funcția publică drawBody ( $x , $y ); }
class RedBody implementează IBody
{
public function drawBody ( $x , $y ) {
echo 'Corpul tău roșu în axa x = ' . $x . ' și axa y = ' . $y . „</br>” . PHP_EOL ;
}
}
class WhiteBody implementează IBody
{
public function drawBody ( $x , $y ) {
echo 'Corpul tău alb în axa x = ' . $x . ' și axa y = ' . $y . „</br>” . PHP_EOL ;
}
}
/**
* Interfață ISnowman - aceasta este o fabrică abstractă
*/
interfață ISnowman
{
public function drawHead ( $x , $y );
funcția publică drawBody ( $x , $y ); }
/**
* Clasa WhiteSnowman - fabrica de beton
*/
class WhiteSnowman implementeaza ISnowman
{
protected $head ;
protejat $corp ;
public function __construct () {
$this -> head = new WhiteHead ();
$this -> body = new WhiteBody ();
}
funcția publică drawHead ( $x , $y ) { $this -> head -> drawHead ( $x , $y ); } funcția publică drawBody ( $x , $y ) { $this -> body -> drawBody ( $x , $y ); } } /** * Clasa RedSnowman - fabrica de beton */ class RedSnowman implementeaza ISnowman { protected $head ; protejat $corp ;
public function __construct () {
$this -> head = new RedHead ();
$this -> body = new RedBody ();
}
funcția publică drawHead ( $x , $y ) { $this -> head -> drawHead ( $x , $y ); } funcția publică drawBody ( $x , $y ) { $this -> body -> drawBody ( $x , $y ); } }
function om de zapada ( ISnowman $om de zapada ) {
$om de zapada -> drawHead ( 1 , 1 );
$om de zapada -> drawBody ( 1 , 2 );
}
$typeSnowman = 'rosu' ;
// selectăm tipul familiei la începutul codului
if ( $typeSnowman == 'red' )
$snowman = new RedSnowman ();
else
$om de zăpadă = new WhiteSnowman ();
om de zăpadă ( $om de zăpadă );
Exemplu Python
Cod sursă în
Python
din abc import ABCMeta , abstractmethod
clasa Bere ( metaclass = ABCMeta ):
trece
clasa gustare ( metaclass = ABCMeta ):
@abstractmethod
def interact ( self , beer : Beer ) -> None :
pass
clasa AbstractShop ( metaclasa = ABCMeta ):
@abstractmethod
def buy_beer ( self ) -> Bere :
trece
@abstractmethod
def buy_snack ( self ) -> Gustare :
trece
clasa Tuborg ( Bere ):
trece
clasa Staropramen ( Bere ):
trece
clasa Arahide ( Gustare ):
def interact ( self , beer : Beer ) -> None :
print ( 'Am băut o sticlă de bere {} și am mâncat-o cu alune' . format (
bere . __class__ . __name__ ))
clasa Chips ( Gustare ):
def interact ( self , beer : Beer ) -> None :
print ( 'Am băut câteva beri {} și am mâncat o pungă de chipsuri' . format (
bere . __class__ . __name__ ))
clasa ExpensiveShop ( AbstractShop ):
def buy_beer ( self ) -> Beer :
return Tuborg ()
def buy_snack ( self ) -> Gustare :
returnează Peanuts ()
clasa CheapShop ( AbstractShop ):
def buy_beer ( self ) -> Bere :
return Staropramen ()
def buy_snack ( self ) -> Snack :
returnează chipsuri ()
if __name__ == '__main__' :
expensive_shop = ExpensiveShop ()
cheap_shop = CheapShop ()
print ( 'OUTPUT:' )
beer = expensive_shop . buy_beer ()
gustare = ieftin_shop . buy_snack ()
gustare . interact ( bere )
bere = ieftin_shop . buy_beer ()
gustare = expensive_shop . buy_snack ()
gustare . interacționează ( bere )
'''
REZULTARE:
Am băut câteva cutii de bere Tuborg și am mâncat o pungă de chipsuri
Am băut o sticlă de bere Staropramen și am mușcat-o cu alune
'''
Exemplu Scala
Codul sursă
Scala
clasa abstractă AbstractTerrestrialAnimal {
def walk : șir
}
clasa abstracta _ _
def swim : String
_
clasa abstracta _ _
def getCity : String
def getTerrestrialAnimal : AbstractTerrestrialAnimal
def getWaterAnimal : AbstractWaterAnimal
}
clasa Wolverine extinde AbstractTerrestrialAnimal {
suprascrie def walk : String = „Wolverine merge”
}
clasa HoneyBadger extinde AbstractTerrestrialAnimal {
suprascrie def walk : String = „Busucul de miere se plimbă”
}
clasa Walrus extinde AbstractWaterAnimal {
override def swim : String = „Morsa înoată”
}
clasa SeaLion extinde AbstractWaterAnimal {
override def swim : String = „Leul de mare înoată”
}
clasa MunichZoo extinde AbstractZoo {
suprascrie def getCity : String = "München"
suprascrie def getTerrestrialAnimal : AbstractTerrestrialAnimal = noul Wolverine
suprascrie def getWaterAnimal : AbstractWaterAnimal = nou Morsa
}
clasa CapeTownZoo extinde AbstractZoo {
suprascrie def getCity : String = "CapeTown"
suprascrie def getTerrestrialAnimal : AbstractTerrestrialAnimal = nou HoneyBadger
suprascrie def getWaterAnimal : AbstractWaterAnimal = nou SeaLion
}
obiect AbstractFactoryTest {
private def testZoo ( zoo : AbstractZoo ): Unitate = {
println ( s"Grădina zoologică ${ zoo . getCity } :" )
println ( zoo . getTerrestrialAnimal . plimbare )
println ( zoo . getWaterAnimal . înot )
}
def main ( args : Array [ String ]) Unit = {
testZoo ( new CapeTownZoo )
testZoo ( new MunichZoo )
}
}
Du-te exemplu
Cod sursă în
Go
pachet principal
import "fmt"
Type Unit interface {
Ce () șir
}
tip Interfață de acțiune { Ce șir () }
introduceți interfața de plasare {
Ce șir () }
tip TransportFactory interface {
MakeUnit () Unit
MakeAction () Action
MakePlace () Place
}
tip Car struct {}
func ( self Car ) What () string {
return "car"
}
tip Ride struct {}
func ( self Ride ) What () string {
return "ride"
}
tip drum struct {}
func ( self Road ) What () string {
return "road"
}
tip LandTransportFactory struct {}
func ( self LandTransportFactory ) MakeUnit () Unit {
return & Car {}
}
func ( self LandTransportFactory ) MakeAction () Action {
return & Ride {}
}
func ( self LandTransportFactory ) MakePlace () Place {
retur & Road {}
}
tip Boat struct {}
func ( self Boat ) What () string {
return "boat"
}
tip Sail struct {}
func ( self Sail ) What () string {
return "sail"
}
tip Sea struct {}
func ( self Sea ) What () string {
return "sea"
}
tip SeaTransportFactory struct {}
func ( self SeaTransportFactory ) MakeUnit () Unit {
return & Boat {}
}
func ( self SeaTransportFactory ) MakeAction () Action {
return & Sail {}
}
func ( self SeaTransportFactory ) MakePlace () Place {
return & Sea {}
}
func action ( fabrică TransportFactory ) {
unit := fabrică . MakeUnit ()
unit_action := fabrică . MakeAction ()
loc := fabrică . MakePlace ()
fmt . Printf ( „%s %ss peste %s.\n” ,
unitate . Ce (), unit_action . Ce (), loc . Ce ())
}
func main () {
action ( & LandTransportFactory {})
action ( & SeaTransportFactory {})
}
Concluzie
Mașina trece peste drum.
Barca navighează peste mare.
Exemplu Ruby
Cod sursă
Ruby
modul AbstractFactoryPattern
# Furnizează o interfață pentru crearea familiilor de obiecte înrudite sau fără a specifica clasele lor concrete
# Abstract Factory
class WarriorFactory
def create_knight
raise NotImplementedError
end
def create_archer
raise NotImplementedError
end
end
# Concrete Factory
class OrcWarriorFactory < WarriorFactory
def create_knight
OrcKnight . sfârşit nou
def create_archer
OrcArcher . sfârşit nou
_
#
Clasa Fabrica de beton ElfWarriorFactory < WarriorFactory
def create_knight
ElfKnight . sfârşit nou
def create_archer
ElfArcher . sfârşit nou
_
# Rezumat
Clasa de produs Knight
def inspectați -vă
. clasa . nume . împărțit ( '::' ) . ultimul capăt _
# Rezumat
Clasa de produs Archer
def inspect
self . clasa . nume . împărțit ( '::' ) . ultimul
capăt
_
#
Clasa de produse OrcKnight < Knight
end
#
Clasa de produse ElfKnight < Knight
end
#
Clasa de produs OrcArcher < Archer
end
#
Clasa de produs ElfArcher < Archer
end
# Clasa client Army
def initialize ( fabrică )
@knights = []
3 . ori { @knights << fabrică . crea_cavaler }
@arcași = []
3 . ori { @arcași << fabrică . create_archer }
end
def inspect
"Cavalerii #{ @knights . map ( & :inspect ) } Arcași #{ @archers . map ( & :inspect ) } "
end
end
def sine . run
orcs = Army . new ( OrcWarriorFactory . new )
pune „Orcs army: #{ orcs . inspect } ”
elfi = armata . new ( ElfWarriorFactory . new )
pune „Elves army: #{ elves . inspect } ”
end
end
AbstractFactoryPattern . alerga
# Armata orcilor: Cavaleri ["OrcKnight", "OrcKnight", "OrcKnight"] Arcași ["OrcArcher", "OrcArcher", "OrcArcher"]
# Armata elfilor: Cavaleri ["ElfKnight", "ElfKnight", "ElfKnight"] Arcași [„ElfArcher”, „ElfArcher”, „ElfArcher”]
Literatură
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Tehnici de proiectare orientată pe obiecte. Design Patterns = Design Patterns: Elements of Reusable Object-Oriented Software. - Sankt Petersburg. : „Petru” , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (și ISBN 5-272-00355-1 )
Link -uri
Note
- ↑ Abstract Factory Pattern . Consultat la 14 iunie 2013. Arhivat din original pe 14 iunie 2013. (nedefinit)
- ↑ Generarea de modele: Fabrică abstractă . Consultat la 14 iunie 2013. Arhivat din original pe 14 iunie 2013. (nedefinit)
- ↑ Abstract Factory .NET Design Pattern în C# și VB - dofactory.com . www.dofactory.com Data accesului: 3 martie 2016. Arhivat din original pe 3 martie 2016. (nedefinit)