Abstrakt fabrik (designmönster)

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 2 mars 2018; kontroller kräver 25 redigeringar .
Abstrakt fabrik
abstrakt fabrik
Sorts alstrande
Ändamål Ger ett gränssnitt för att skapa familjer av relaterade eller beroende av varandra utan att specificera deras konkreta klasser.
Strukturera
Gäller i ärenden
  • När programmet måste vara oberoende av processen och typer av nya objekt som skapas.
  • När det är nödvändigt att skapa familjer eller grupper av inbördes relaterade objekt, exklusive möjligheten till samtidig användning av objekt från dessa olika uppsättningar i samma sammanhang [1] .
fördelar
  • isolerar specifika klasser;
  • förenklar utbytet av produktfamiljer;
  • garanterar produktkompatibilitet.
Minus
  • det är svårt att lägga till stöd för en ny typ av produkt.
Beskrivs i Design Patterns Ja

En  abstrakt fabrik är ett generativt designmönster som ger ett gränssnitt för att skapa familjer av sammanhängande eller beroende av varandra utan att specificera deras konkreta klasser. Mönstret implementeras genom att skapa en abstrakt klass Factory, som är ett gränssnitt för att skapa systemkomponenter (till exempel för ett fönstergränssnitt kan det skapa fönster och knappar). Sedan skrivs klasser som implementerar detta gränssnitt [2] .

Utnämning

Ger ett gränssnitt för att skapa familjer av relaterade eller beroende av varandra utan att specificera deras konkreta klasser.

Implementering

Fördelar

Nackdelar

Applikation

Exempel

Snabbexempel

Swift källkod //: Lekplats - substantiv: en plats där människor kan leka /// <sammanfattning> /// Abstrakt fabriksklass /// </summary> protokoll AbstractFactory { func createProductA () -> AbstractProductA func createProductB () -> AbstractProductB } /// <sammanfattning> /// Fabriksklass #1 /// </summary> klass ConcreteFactory1 : AbstractFactory { public func createProductA () -> AbstractProductA { return ProductA1 () } public func createProductB () -> AbstractProductB { return ProductB1 () } } /// <sammanfattning> /// Fabriksklass #2 /// </summary> klass ConcreteFactory2 : AbstractFactory { public func createProductA () -> AbstractProductA { return ProductA2 () } public func createProductB () -> AbstractProductB { return ProductB2 () } } /// <summary> /// Abstrakt produktklass A /// </summary> protokoll AbstractProductA {} // /// <summary> /// Abstrakt produktklass B /// </summary> protokoll AbstractProductB { func interagera ( a : AbstractProductA ) } /// <summary> /// Första produktklassen av typ A /// </summary> klass ProductA1 : AbstractProductA {} /// <summary> /// Första produktklassen av typ B /// </summary> class ProductB1 : AbstractProductB { public func interact ( a : AbstractProductA ) { print ( " \( type ( of : self )) interacts with \ ( typ ( av : a . själv )) " ) } } /// <summary> /// Andra produktklassen av typ A /// </summary> klass ProductA2 : AbstractProductA {} /// <summary> /// Andra produktklassen av typ B /// </summary> class ProductB2 : AbstractProductB { public func interact ( a : AbstractProductA ) { print ( " \( type ( of : self )) interacts with \ ( typ ( av : a . själv )) " ) } } /// <summary> /// Klientklassen där interaktionen mellan objekt sker /// </summary> class Client { private let _abstractProductA : AbstractProductA private let _abstractProductB : AbstractProductB // Konstruktör public init ( fabrik : AbstractFactory ) { _abstractProductB = fabrik . createProductB (); _abstractProductA = fabrik . createProductA (); } public func run () { _abstractProductB . interagera ( a : _abstractProductA ) } } /// <sammanfattning> /// Applikationsstartpunkt /// </summary> // Anropar abstrakt fabrik #1 let factory1 = ConcreteFactory1 () let client1 = Client ( factory : factory1 ) client1 . springa () // Ring abstrakt fabrik #2 låt fabrik2 = ConcreteFactory2 () låt klient2 = Klient ( fabrik : fabrik2 ) klient2 . springa ()

Exempel i C# [3]

Källkod i C Sharp använder System ; namnutrymme DoFactory.GangOfFour.Abstract.Structural { class MainApp { /// <summary> /// Applikationsstartpunkt /// </summary> public static void Main () { // Abstrakt fabriksanrop #1 AbstractFactory factory1 = new ConcreteFactory1 (); Klient klient1 = ny klient ( fabrik1 ); klient1 . köra (); // Ring abstrakt fabrik #2 AbstractFactory factory2 = new ConcreteFactory2 (); Klient klient2 = ny klient ( fabriks2 ); klient2 . köra (); // Väntar på input Console . ReadKey (); } } /// <summary> /// Abstrakt fabriksklass /// </summary> abstrakt klass AbstractFactory { public abstract AbstractProductA CreateProductA (); public abstract AbstractProductB CreateProductB (); } /// <summary> /// Fabriksklass #1 /// </summary> class ConcreteFactory1 : AbstractFactory { public override AbstractProductA CreateProductA () { return new ProductA1 (); } public override AbstractProductB CreateProductB () { returnera ny produktB1 (); } } /// <summary> /// Fabriksklass #2 /// </summary> class ConcreteFactory2 : AbstractFactory { public override AbstractProductA CreateProductA () { return new ProductA2 (); } public override AbstractProductB CreateProductB () { returnera ny produktB2 (); } } /// <summary> /// Abstrakt produktklass A /// </summary> abstrakt klass AbstractProductA { } /// <sammanfattning> /// Abstrakt produktklass B /// </summary> abstrakt klass AbstractProductB { public abstract void Interact ( AbstractProductA a ); } /// <summary> /// Första produktklassen av typ A /// </summary> klass ProductA1 : AbstractProductA { } /// <summary> /// Första produktklassen av typ B /// </summary> klass ProductB1 : AbstractProductB { public override void Interact ( AbstractProductA a ) { Console . WriteLine ( denna . GetType (). Name + " interagerar med " + a . GetType (). Name ); } } /// <summary> /// Andra produktklassen av typ A /// </summary> klass ProductA2 : AbstractProductA { } /// <summary> /// Andra produktklassen av typ B /// </summary> class ProductB2 : AbstractProductB { public override void Interact ( AbstractProductA a ) { Console . WriteLine ( denna . GetType (). Name + " interagerar med " + a . GetType (). Name ); } } /// <summary> /// Klientklassen där interaktionen mellan objekt sker /// </summary> class Client { private AbstractProductA _abstractProductA ; privat AbstractProductB _abstractProductB ; // Konstruktör offentlig klient ( AbstractFactory factory ) { _abstractProductB = factory . CreateProductB (); _abstractProductA = fabrik . CreateProductA (); } public void Kör () { _abstractProductB . Interagera ( _abstractProductA ); } } }

Java-exempel

Java -källa public class AbstractFactoryExample { public static void main ( String [] args ) { AbstractFactory factory1 = new ConcreteFactory1 (); Klient klient1 = ny klient ( fabrik1 ); klient1 . exekvera (); AbstractFactory factory2 = new ConcreteFactory2 (); Klient klient2 = ny klient ( fabriks2 ); klient2 . exekvera (); } } class Client { private AbstractProductA productA ; privat Sammanfattning ProduktB produktB ; Klient ( AbstractFactory factory ) { productA = factory . createProductA (); produktB = fabrik . createProductB (); } void execute () { produktB . interagera ( produktA ); } } gränssnitt AbstractFactory { AbstractProductA createProductA (); AbstractProductB createProductB (); } gränssnitt AbstractProductA { void interact ( AbstractProductB b ); } gränssnitt AbstractProductB { void interact ( AbstractProductA a ); } klass ConcreteFactory1 implementerar AbstractFactory { @Override public AbstractProductA createProductA () { returnera ny ProductA1 (); } @Override public AbstractProductB createProductB () { return new ProductB1 (); } } klass ConcreteFactory2 implementerar AbstractFactory { @Override public AbstractProductA createProductA () { returnera ny ProductA2 (); } @Override public AbstractProductB createProductB () { returnera ny produktB2 (); } } klass ProductA1 implementerar AbstractProductA { @Override public void interact ( AbstractProductB b ) { System . ut . println ( denna . getClass (). getName () + " interagerar med " + b . getClass (). getName ()); } } klass ProductB1 implementerar AbstractProductB { @Override public void interact ( AbstractProductA a ) { System . ut . println ( denna . getClass (). getName () + " interagerar med " + en . getClass (). getName ()); } } klass ProductA2 implementerar AbstractProductA { @Override public void interact ( AbstractProductB b ) { System . ut . println ( denna . getClass (). getName () + " interagerar med " + b . getClass (). getName ()); } } class ProductB2 implementerar AbstractProductB { @Override public void interact ( AbstractProductA a ) { System . ut . println ( denna . getClass (). getName () + " interagerar med " + en . getClass (). getName ()); } }

PHP5 exempel

PHP5 källkod gränssnitt IHead { public function drawHead ( $x , $y ); } class RedHead implementerar IHead { public function drawHead ( $x , $y ) { echo 'Ditt röda huvud i axeln x = ' . $x . ' och axeln y = ' . $y . '</br>' . PHP_EOL ; } } klass WhiteHead implementerar IHead { public function drawHead ( $x , $y ) { echo 'Ditt vita huvud i axeln x = ' . $x . ' och axeln y = ' . $y . '</br>' . PHP_EOL ; } } gränssnitt IBody { public function drawBody ( $x , $y ); } class RedBody implementerar IBody { public function drawBody ( $x , $y ) { echo 'Din röda kropp i axeln x = ' . $x . ' och axeln y = ' . $y . '</br>' . PHP_EOL ; } } class WhiteBody implementerar IBody { public function drawBody ( $x , $y ) { echo 'Din vita kropp i axeln x = ' . $x . ' och axeln y = ' . $y . '</br>' . PHP_EOL ; } } /** * Interface ISnowman - detta är abstrakt fabrik */ interface ISnowman { public function drawHead ( $x , $y ); public function drawBody ( $x , $y ); } /** * Klass WhiteSnowman - betongfabrik */ klass WhiteSnowman implementerar ISnowman { protected $head ; skyddad $kropp ; public function __construct () { $this -> head = new WhiteHead (); $this -> body = new WhiteBody (); } public function drawHead ( $x , $y ) { $this -> head -> drawHead ( $x , $y ); } public function drawBody ( $x , $y ) { $this -> body -> drawBody ( $x , $y ); } } /** * Klass RedSnowman - betongfabrik */ klass RedSnowman implementerar ISnowman { protected $head ; skyddad $kropp ; public function __construct () { $this -> head = new RedHead (); $this -> body = new RedBody (); } public function drawHead ( $x , $y ) { $this -> head -> drawHead ( $x , $y ); } public function drawBody ( $x , $y ) { $this -> body -> drawBody ( $x , $y ); } } function snowman ( ISnowman $ snowman ) { $snowman -> drawHead ( 1 , 1 ); $snögubbe -> drawBody ( 1 , 2 ); } $typeSnowman = 'röd' ; // vi väljer familjetypen i början av koden om ( $typeSnowman == 'red' ) $snowman = new RedSnowman (); else $snögubbe = ny WhiteSnowman (); snögubbe ( $snögubbe );

Python-exempel

Källkod i Python från abc import ABCMeta , abstraktmetod klass Öl ( metaklass = ABCMeta ): godkänt klass Snack ( metaklass = ABCMeta ): @abstractmethod def interagera ( själv , öl : Öl ) -> Inga : godkänt klass AbstractShop ( metaklass = ABCMeta ): @abstractmethod def buy_beer ( self ) -> Beer : pass @abstractmethod def buy_snack ( self ) -> Snack : pass klass Tuborg ( Öl ): pass klass Staropramen ( Öl ): pass klass jordnötter ( mellanmål ): def interagera ( själv , öl : Öl ) -> Inget : print ( 'Vi drack en flaska öl {} och åt den med jordnötter' . format ( öl . __klass__ . __namn__ )) klass Chips ( Snack ): def interagera ( själv , öl : Öl ) -> Inget : print ( 'Vi drack några öl {} och åt en påse chips' . format ( öl . __klass__ . __namn__ )) klass ExpensiveShop ( AbstractShop ): def buy_beer ( self ) -> Beer : return Tuborg () def buy_snack ( self ) -> Snack : return Peanuts () klass CheapShop ( AbstractShop ): def buy_beer ( self ) -> Beer : return Staropramen () def buy_snack ( self ) -> Snack : returnera chips () if __name__ == '__main__' : dyr_butik = Dyr Butik ( ) cheap_shop = Billig Butik () skriv ut ( 'OUTPUT:' ) öl = dyr_butik . köpa_öl () mellanmål = billig_butik . köpa_mellanmål () mellanmål . interagera ( öl ) öl = billig_butik . köpa_öl () mellanmål = dyr_butik . köpa_mellanmål () mellanmål . interagera ( öl ) ''' UTGÅNG: Vi drack några burkar Tuborg öl och åt en påse chips Vi drack en flaska Staropramen öl och bet den med jordnötter '''

Scala exempel

Scala källkod abstrakt klass AbstraktTerrestrialAnimal { def walk : String } abstrakt klass _ _ def simma : String _ abstrakt klass _ _ def getCity : String def getTerrestrialAnimal : AbstractTerrestrialAnimal def getWaterAnimal : AbstractWaterAnimal } klass Wolverine förlänger AbstractTerrestrialAnimal { override def walk : String = "Wolverine går" } klass HoneyBadger utökar AbstractTerrestrialAnimal { override def walk : String = "Honey grävling går" } klass Walrus utökar AbstractWaterAnimal { override def sim : String = "Valross simmar" } klass SeaLion utökar AbstractWaterAnimal { åsidosätta def simma : String = "Sjölejon simmar" } klass MunichZoo utökar AbstractZoo { åsidosätt def getCity : String = "München" åsidosätt def getTerrestrialAnimal : AbstractTerrestrialAnimal = ny Wolverine override def getWaterAnimal : AbstractWaterAnimal = new Walrus } klass CapeTownZoo utökar AbstractZoo { åsidosätt def getCity : String = "CapeTown" åsidosätt def getTerrestrialAnimal : AbstractTerrestrialAnimal = ny HoneyBadger override def getWaterAnimal : AbstractWaterAnimal = new SeaLion } objekt AbstractFactoryTest { privat def testZoo ( zoo : AbstractZoo ): Enhet = { println ( s"Zoo of ${ zoo . getCity } :" ) println ( zoo . getTerrestrialAnimal . walk ) println ( zoo . getWaterAnimal . swim ) } def main ( args : Array [ String ]) Unit = { testZoo ( new CapeTownZoo ) testZoo ( new MunichZoo ) } }

Gå exempel

Källkod i Go huvudpaket _ importera "fmt" typ Unit interface { What () string } typ Action interface { What () string } typ Placera gränssnitt { Vad () sträng } typ TransportFactory -gränssnitt { MakeUnit () Unit MakeAction () Action MakePlace () Place } typ Car struct {} func ( self Car ) Vad () string { return "car" } typ Ride struct {} func ( self Ride ) What () string { return "ride" } skriv vägstruktur { } func ( self Road ) Vad () sträng { return "road" } typ LandTransportFactory struct {} func ( self LandTransportFactory ) MakeUnit () Enhet { retur & bil {} } func ( self LandTransportFactory ) MakeAction () Action { return & Ride {} } func ( self LandTransportFactory ) MakePlace () Plats { retur & väg {} } typ Båtstruktur { } func ( self Boat ) Vad () string { return "boat" } typ Sail struct {} func ( self Sail ) Vad () string { return "sail" } typ Sea struct {} func ( self Sea ) Vad () string { returnera "hav" } typ SeaTransportFactory struct {} func ( self SeaTransportFactory ) MakeUnit ( ) Enhet { retur & båt {} } func ( self SeaTransportFactory ) MakeAction () Action { return & Sail {} } func ( self SeaTransportFactory ) MakePlace () Placera { return & Sea {} } func action ( fabrik TransportFactory ) { enhet := fabrik . MakeUnit () unit_action := fabrik . MakeAction () plats := fabrik . MakePlace () fmt . Printf ( "%s %ss över %s.\n" , enhet . What (), unit_action . What (), place . What ()) } func main () { action ( & LandTransportFactory {}) action ( & SeaTransportFactory {}) }

Slutsats

Bilen åker över vägen. Båten seglar över havet.

Ruby exempel

Ruby källkod modul AbstractFactoryPattern # Tillhandahålla ett gränssnitt för att skapa familjer av relaterade eller objekt utan att specificera deras konkreta klasser # Abstrakt Factory class WarriorFactory def create_knight raise NotImplementedError end def create_archer höj NotImplementedError end end # Betongfabriksklass OrcWarriorFactory < WarriorFactory def create_knight OrcKnight . nytt slut def create_archer OrcArcher . nytt slutslut _ # Betongfabriksklass ElfWarriorFactory < WarriorFactory def create_knight ElfKnight . nytt slut def create_archer ElfArcher . nytt slutslut _ # Abstrakt produktklass Knight def inspect self . klass . namn . dela ( '::' ) . sista slutet _ # Abstrakt produktklass Archer def inspect self . klass . namn . dela ( '::' ) . sista slutet _ # Produktklass OrcKnight < Knight end # Produktklass ElfKnight < Knight end # Produktklass OrcArcher < Archer end # Produktklass ElfArcher < Archer end # Klientklass Army def initialisera ( fabrik ) @knights = [ ] 3 . gånger { @knights << fabrik . create_knight } @bågskyttar = [] 3 . gånger { @archers << fabrik . create_archer } slut def inspect "Knights #{ @knights . map ( & :inspect ) } Archers #{ @archers . map ( & :inspect ) } " end end def själv . kör orcher = Armé . new ( OrcWarriorFactory . new ) sätter "Orcs army: #{ orcs . inspect } " tomtar = armé . new ( ElfWarriorFactory . new ) sätter "Elves army: #{ elves . inspect } " end end AbstractFactoryPattern . springa # Orcs armé: Knights ["OrcKnight", "OrcKnight", "OrcKnight"] Archers ["OrcArcher", "OrcArcher", "OrcArcher"] # Alverarmé: Knights ["ElfKnight", "ElfKnight", "ElfKnight"] Archers ["ElfArcher", "ElfArcher", "ElfArcher"]

Litteratur

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Tekniker för objektorienterad design. Designmönster = Designmönster: Element av återanvändbar objektorienterad programvara. - St Petersburg. : "Peter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (även ISBN 5-272-00355-1 )

Länkar

Anteckningar

  1. Abstrakt fabriksmönster . Hämtad 14 juni 2013. Arkiverad från originalet 14 juni 2013.
  2. Generera mönster: Abstrakt fabrik . Hämtad 14 juni 2013. Arkiverad från originalet 14 juni 2013.
  3. Abstrakt Factory .NET-designmönster i C# och VB - dofactory.com . www.dofactory.com Datum för åtkomst: 3 mars 2016. Arkiverad från originalet 3 mars 2016.