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

Contra

Aplicație

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

  1. Abstract Factory Pattern . Consultat la 14 iunie 2013. Arhivat din original pe 14 iunie 2013.
  2. Generarea de modele: Fabrică abstractă . Consultat la 14 iunie 2013. Arhivat din original pe 14 iunie 2013.
  3. 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.