Abstrakti tehdas (suunnittelukuvio)

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 2. maaliskuuta 2018 tarkistetusta versiosta . tarkastukset vaativat 25 muokkausta .
Abstrakti tehdas
abstrakti tehdas
Tyyppi tuottaa
Tarkoitus Tarjoaa käyttöliittymän toisiinsa liittyvien tai toisistaan ​​riippuvaisten objektien perheiden luomiseen määrittelemättä niiden konkreettisia luokkia.
Rakenne
Pätee tapauksissa
  • Kun ohjelman on oltava riippumaton luotujen uusien objektien prosessista ja tyypeistä.
  • Kun on tarpeen luoda toisiinsa liittyvien objektien perheitä tai ryhmiä, suljetaan pois mahdollisuus käyttää samanaikaisesti kohteita näistä eri joukoista samassa yhteydessä [1] .
Plussat
  • eristää tietyt luokat;
  • yksinkertaistaa tuoteperheiden vaihtamista;
  • takaa tuotteen yhteensopivuuden.
Miinukset
  • uudenlaiselle tuotteelle on vaikea lisätä tukea.
Kuvattu suunnittelukuvioissa Joo

Abstrakti  tehdas on generatiivinen suunnittelumalli, joka tarjoaa käyttöliittymän toisiinsa liittyvien tai toisiinsa liittyvien objektien perheiden luomiseen määrittelemättä niiden konkreettisia luokkia. Malli toteutetaan luomalla abstrakti luokka Factory, joka on käyttöliittymä järjestelmäkomponenttien luomiseen (esimerkiksi ikkunaliittymälle se voi luoda ikkunoita ja painikkeita). Sitten kirjoitetaan luokat , jotka toteuttavat tämän rajapinnan [2] .

Tapaaminen

Tarjoaa käyttöliittymän toisiinsa liittyvien tai toisistaan ​​riippuvaisten objektien perheiden luomiseen määrittelemättä niiden konkreettisia luokkia.

Toteutus

Plussat

Miinukset

Sovellus

Esimerkkejä

Nopea esimerkki

Nopea lähdekoodi //: Leikkikenttä - substantiivi: paikka, jossa ihmiset voivat leikkiä /// <summary> /// Tiivistelmä tehdasluokka /// </summary> protokolla AbstractFactory { func createProductA () -> AbstractProductA func createProductB () -> AbstractProductB } /// <summary> /// Tehdasluokka #1 /// </summary> class ConcreteFactory1 : AbstractFactory { public func createProductA () -> AbstractProductA { return ProductA1 () } public func createProductB () -> AbstractProductB { return ProductB1 () } } /// <summary> /// Tehdasluokka #2 /// </summary> class ConcreteFactory2 : AbstractFactory { public func createProductA () -> AbstractProductA { return ProductA2 () } public func createProductB () -> AbstractProductB { return ProductB2 () } } /// <summary> /// Abstrakti tuoteluokka A /// </summary> protokolla AbstractProductA {} // /// <summary> /// Abstrakti tuoteluokka B /// </summary> protokolla AbstractProductB { func vuorovaikutuksessa ( a : AbstractProductA ) } /// <summary> /// Ensimmäinen tyypin A tuoteluokka /// </summary> luokka ProductA1 : AbstractProductA {} /// <summary> /// Tyypin B ensimmäinen tuoteluokka /// </summary> luokka TuoteB1 : AbstractProductB { public func interact ( a : AbstractProductA ) { print ( " \( type ( of : self )) interacts with \ ( tyyppi ( of : a . itse )) " ) } } /// <summary> /// Tyypin A toinen tuoteluokka /// </summary> luokka ProductA2 : AbstractProductA {} /// <summary> /// Tyypin B toinen tuoteluokka /// </summary> luokka TuoteB2 : AbstractProductB { public func interact ( a : AbstractProductA ) { print ( " \( type ( of : self )) interacts with \ ( tyyppi ( of : a . itse )) " ) } } /// <summary> /// Asiakasluokka, jossa objektien välinen vuorovaikutus tapahtuu /// </summary> class Client { yksityinen anna _abstractProductA : AbstractProductA private let _abstractProductB : AbstractProductB // Rakentajan julkinen aloitus ( tehdas : AbstractFactory ) { _abstractProductB = tehdas . luoTuoteB (); _abstractProductA = tehdas . luoTuoteA (); } public func run () { _abstractProductB . vuorovaikutuksessa ( a : _abstractProductA ) } } /// <summary> /// Sovelluksen sisääntulopiste /// </summary> // Abstraktin tehdasnumeron kutsuminen let factory1 = ConcreteFactory1 () let client1 = Asiakas ( tehdas : tehdas1 ) asiakas1 . juosta () // Kutsu abstrakti tehdas #2 let factory2 = ConcreteFactory2 () let client2 = Asiakas ( tehdas : tehdas2 ) asiakas2 . juosta ()

Esimerkki C# [3]

Lähdekoodi C Sharpissa käyttäen System ; nimitila DoFactory.GangOfFour.Abstract.Structural { class MainApp { /// <summary> /// Sovelluksen aloituspiste /// </summary> public static void Main () { // Abstrakti tehdaskutsu #1 AbstractFactory factory1 = new ConcreteFactory1 (); Asiakas asiakas1 = uusi asiakas ( tehdas1 ); asiakas1 . juosta (); // Kutsu abstrakti tehdas #2 AbstractFactory factory2 = new ConcreteFactory2 (); Asiakas asiakas2 = uusi asiakas ( tehdas2 ); asiakas2 . juosta (); // Odotetaan syöttöä Konsoli . ReadKey (); } } /// <summary> /// Abstract factory class /// </summary> abstrakti class AbstractFactory { public abstract AbstractProductA CreateProductA (); julkinen abstrakti AbstractProductB CreateProductB (); } /// <summary> /// Tehdasluokka #1 /// </summary> class ConcreteFactory1 : AbstractFactory { public override AbstractProductA CreateProductA () { return new ProductA1 (); } julkinen ohitus AbstractProductB CreateProductB () { return new ProductB1 (); } } /// <summary> /// Tehdasluokka #2 /// </summary> class ConcreteFactory2 : AbstractFactory { public override AbstractProductA CreateProductA () { return new ProductA2 (); } public override AbstractProductB CreateProductB () { return new ProductB2 (); } } /// <summary> /// Abstrakti tuoteluokka A /// </summary> abstrakti luokka AbstractProductA { } /// <summary> /// Abstrakti tuoteluokka B /// </summary> abstrakti luokka AbstractProductB { public abstract void Interact ( AbstractProductA a ); } /// <summary> /// Ensimmäinen tyypin A tuoteluokka /// </summary> luokka ProductA1 : AbstractProductA { } /// <summary> /// Ensimmäinen tyypin B tuoteluokka /// </summary> luokka TuoteB1 : AbstractProductB { public override void Interact ( AbstractProductA a ) { Console . WriteLine ( tämä . GetType (). Nimi + " on vuorovaikutuksessa " + a . GetType (). Nimi ); } } /// <summary> /// Tyypin A toinen tuoteluokka /// </summary> luokka ProductA2 : AbstractProductA { } /// <summary> /// Tyypin B toinen tuoteluokka /// </summary> luokka TuoteB2 : AbstractProductB { public override void Interact ( AbstractProductA a ) { Console . WriteLine ( tämä . GetType (). Nimi + " on vuorovaikutuksessa " + a . GetType (). Nimi ); } } /// <summary> /// Asiakasluokka, jossa objektien välinen vuorovaikutus tapahtuu /// </summary> class Client { private AbstractProductA _abstractProductA ; yksityinen AbstractProductB _abstractProductB ; // Constructor public Client ( AbstractFactory factory ) { _abstractProductB = tehdas . LuoTuoteB (); _abstractProductA = tehdas . LuoTuoteA (); } public void Suorita () { _abstractProductB . Interact ( _abstractProductA ); } } }

Java-esimerkki

Java lähde public class AbstractFactoryExample { public static void main ( String [ ] args ) { AbstractFactory tehdas1 = uusi ConcreteFactory1 (); Asiakas asiakas1 = uusi asiakas ( tehdas1 ); asiakas1 . suorittaa (); AbstractFactory factory2 = uusi ConcreteFactory2 (); Asiakas asiakas2 = uusi asiakas ( tehdas2 ); asiakas2 . suorittaa (); } } class Client { yksityinen AbstractProductA productA ; yksityinen AbstraktiTuoteB tuoteB ; Asiakas ( AbstractFactory tehdas ) { productA = tehdas . luoTuoteA (); tuoteB = tehdas . luoTuoteB (); } void execute () { tuoteB . olla vuorovaikutuksessa ( tuoteA ); } } käyttöliittymä AbstractFactory { AbstractProductA createProductA (); AbstractProductB createProductB (); } käyttöliittymä AbstractProductA { void interact ( AbstractProductB b ); } käyttöliittymä AbstractProductB { void interact ( AbstractProductA a ); } luokka ConcreteFactory1 toteuttaa AbstractFactory { @Override public AbstractProductA createProductA () { return new ProductA1 (); } @Ohita julkinen AbstractProductB createProductB () { return new ProductB1 (); } } luokka ConcreteFactory2 toteuttaa AbstractFactory { @Override public AbstractProductA createProductA () { return new ProductA2 (); } @Override public AbstractProductB createProductB () { return new ProductB2 (); } } luokan TuoteA1 toteuttaa AbstractProductA { @Override public void interact ( AbstractProductB b ) { System . ulos . println ( tämä . getClass (). getName () + " vuorovaikutuksessa " + b . getClass (). getName ()); } } luokan tuoteB1 toteuttaa AbstractProductB { @Override public void interact ( AbstractProductA a ) { Järjestelmä . ulos . println ( tämä . getClass (). getName () + " vuorovaikutuksessa " + a . getClass (). getName ()); } } luokan TuoteA2 toteuttaa AbstractProductA { @Override public void interact ( AbstractProductB b ) { System . ulos . println ( tämä . getClass (). getName () + " vuorovaikutuksessa " + b . getClass (). getName ()); } } luokan tuoteB2 toteuttaa AbstractProductB { @Override public void interact ( AbstractProductA a ) { Järjestelmä . ulos . println ( tämä . getClass (). getName () + " vuorovaikutuksessa " + a . getClass (). getName ()); } }

PHP5 esimerkki

PHP5 lähdekoodi käyttöliittymä IHead { julkinen funktio piirtopää ( $x , $y ); } class RedHead toteuttaa IHead { public function drawHead ( $x , $y ) { echo 'Punainen pää akselilla x =' . $x . ' ja akseli y = ' . $y . '</br>' . PHP_EOL ; } } class WhiteHead toteuttaa IHead { julkinen funktio piirtopää ( $x , $y ) { echo 'Valkoinen pääsi akselilla x =' . $x . ' ja akseli y = ' . $y . '</br>' . PHP_EOL ; } } käyttöliittymä IBody { julkinen toiminto drawBody ( $x , $y ); } class RedBody toteuttaa IBody { public function drawBody ( $x , $y ) { echo 'Punainen kehosi akselilla x =' . $x . ' ja akseli y = ' . $y . '</br>' . PHP_EOL ; } } class WhiteBody toteuttaa IBody { julkinen toiminto drawBody ( $x , $y ) { echo 'Valkoinen kehosi akselilla x =' . $x . ' ja akseli y = ' . $y . '</br>' . PHP_EOL ; } } /** * Käyttöliittymä ISnowman - tämä on abstrakti tehdas */ käyttöliittymä ISnowman { julkinen funktio piirrospää ( $x , $y ); julkinen funktio drawBody ( $x , $y ); } /** * Luokka WhiteSnowman - betonitehdas */ luokka WhiteSnowman työstää ISnowman { suojattu $ pää ; suojattu $body ; public function __construct () { $this -> head = new WhiteHead (); $this -> body = uusi WhiteBody (); } julkinen funktio piirtopää ( $x , $y ) { $this -> head -> drawHead ( $x , $y ); } julkinen funktio drawBody ( $x , $y ) { $this -> body -> drawBody ( $x , $y ); } } /** * Luokka RedSnowman - betonitehdas */ luokka RedSnowman toteuttaa ISnowman { suojattu $pää ; suojattu $body ; julkinen funktio __construct () { $this -> head = new RedHead (); $this -> body = uusi RedBody (); } julkinen funktio piirtopää ( $x , $y ) { $this -> head -> drawHead ( $x , $y ); } julkinen funktio drawBody ( $x , $y ) { $this -> body -> drawBody ( $x , $y ); } } funktio lumiukko ( ISnowman $lumiukko ) { $lumiukko -> piirtopää ( 1 , 1 ); $lumiukko -> drawBody ( 1 , 2 ); } $typeSnowman = 'punainen' ; // valitsemme perhetyypin koodin alussa if ( $typeSnowman == 'red' ) $lumiukko = new RedLumiukko (); else $lumiukko = uusi WhiteLumiukko (); lumiukko ( $lumiukko );

Python-esimerkki

Lähdekoodi Pythonissa abc importista ABCMeta , abstrakti menetelmä luokka Olut ( metaluokka = ABCMeta ): pass luokan välipala ( metaluokka = ABCMeta ): @abstractmethod def interact ( itse , olut : Olut ) -> Ei mitään : pass class AbstractShop ( metaluokka = ABCMeta ): @abstractmethod def buy_beer ( self ) -> Beer : pass @abstractmethod def buy_snack ( itse ) -> Välipala : pass luokka Tuborg ( Olut ): pass luokka Staropramen ( Olut ): pass luokan maapähkinät ( välipala ): def interact ( itse , olut : Olut ) -> Ei mitään : print ( 'Joimme pullon olutta {} ja söimme sen maapähkinöiden kanssa' . muodossa ( olut . __class__ . __name__ )) luokan sirut ( välipala ): def interact ( self , olut : Beer ) -> None : print ( 'Joimme muutaman oluen {} ja söimme pussin chipsejä' . muodossa ( olut . __class__ . __name__ )) luokka ExpensiveShop ( AbstractShop ): def buy_beer ( itse ) -> Olut : paluu Tuborg ( ) def buy_snack ( itse ) -> Välipala : paluu Maapähkinät ( ) luokan CheapShop ( AbstractShop ): def buy_beer ( itse ) -> Olut : paluu Staropramen ( ) def buy_snack ( itse ) -> Välipala : palauta pelimerkit () if __name__ == '__main__' : kallis_kauppa = KallisShop ( ) cheap_shop = HalpaShop () print ( 'OUTPUT:' ) olut = kallis_kauppa . osta_olutta () välipala = halpa_kauppa . buy_snack () välipala . vuorovaikutuksessa ( olut ) olut = halpa_kauppa . osta_olutta () välipala = kallis_kauppa . buy_snack () välipala . olla vuorovaikutuksessa ( olut ) ''' TULOS: Joimme muutaman tölkin Tuborgin olutta ja söimme pussin sipsejä Joimme pullon Staropramen-olutta ja puresimme sitä maapähkinöillä '''

Scala esimerkki

Scala lähdekoodi abstrakti luokka AbstractTerrestrialAnimal { def walk : merkkijono } abstrakti luokka _ _ def swim : String _ abstrakti luokka _ _ def getCity : merkkijono def getTerrestrialAnimal : AbstractTerrestrialAnimal def getWaterAnimal : AbstractWaterAnimal } luokka Wolverine extends AbstractTerrestrialAnimal { ohita def walk : String = "Ahma kävelee" } class HoneyBadger extends AbstractTerrestrialAnimal { ohita def walk : String = "Kunamäyrä kävelee" } luokka Walrus laajentaa AbstractWaterAnimal { ohittaa def swim : String = "Mursu ui" } class SeaLion laajentaa AbstractWaterAnimal { override def swim : String = "Merileijona ui" } class MunichZoo laajentaa AbstractZoo { ohita def getCity : String = "München" ohita def getTerrestrialAnimal : AbstractTerrestrialAnimal = uusi Wolverine ohita def getWaterAnimal : AbstractWaterAnimal = uusi mursu } class CapeTownZoo laajentaa AbstractZoo { ohita def getCity : String = "Kapkaupunki" ohita def getTerrestrialAnimal : AbstractTerrestrialAnimal = uusi HoneyBadger ohita def getWaterAnimal : AbstractWaterAnimal = uusi SeaLion } object AbstractFactoryTest { yksityinen def testZoo ( eläintarha : AbstractZoo ): Yksikkö = { println ( s"Zoo of ${ zoo . getCity } :" ) println ( eläintarha . getTerrestrialAnimal . walk ) println ( eläintarha . getWaterAnimal . uida ) } def main ( args : Array [ String ]) Unit = { testZoo ( new CapeTownZoo ) testZoo ( new MunichZoo ) } }

Siirry esimerkkiin

Lähdekoodi Gossa paketin pääasiallinen tuo "fmt" kirjoita Unit interface { Mikä () merkkijono } kirjoita Action interface { Mikä () merkkijono } kirjoita Aseta käyttöliittymä { Mikä () merkkijono } tyyppi TransportFactory - liitäntä { MakeUnit () Unit MakeAction () Action MakePlace () Paikka } tyyppi auton rakenne {} func ( itse auto ) Mikä () merkkijono { return "auto" } kirjoita Ride struct {} func ( self Ride ) Mikä () merkkijono { return "ride" } tyyppi tierakenne { } func ( itse tie ) Mikä () merkkijono { return "tie" } tyyppi LandTransportFactory struct {} func ( itse LandTransportFactory ) Merkkiyksikkö ( ) Yksikkö { paluu & auto {} } Func ( itse LandTransportFactory ) MakeAction ( ) Action { return & Ride {} } Func ( itse LandTransportFactory ) MakePlace ( ) Paikka { paluu & tie {} } tyyppi Venerakenne { } func ( itse Vene ) Mikä () merkkijono { return "boat" } tyyppi Purjerakenne { } func ( self Sail ) Mikä () merkkijono { return "purje" } tyyppi Sea struct {} func ( itse Meri ) Mikä () merkkijono { return "meri" } tyyppi SeaTransportFactory struct {} func ( itse SeaTransportFactory ) MakeUnit ( ) Yksikkö { paluu & vene {} } Func ( itse SeaTransportFactory ) MakeAction ( ) Action { paluu & purjehtii {} } Func ( itse SeaTransportFactory ) MakePlace ( ) Paikka { paluu & meri {} } func action ( tehdas TransportFactory ) { yksikkö := tehdas . MakeUnit () unit_action := tehdas . MakeAction () paikka := tehdas . MakePlace () fmt . Printf ( "%s %ss %s:n päällä.\n" , yksikkö . Mikä (), yksikkötoiminto . Mikä (), paikka . Mikä ()) } func main () { action ( & LandTransportFactory {}) action ( & SeaTransportFactory {}) }

Johtopäätös

Auto ajaa tien yli. Vene purjehtii meren yli.

Rubiiniesimerkki

Rubyn lähdekoodi moduuli AbstractFactoryPattern # Tarjoa käyttöliittymä toisiinsa liittyvien tai objektien perheiden luomiseen ilman niiden konkreettisia luokkia # Abstract Factory -luokka WarriorFactory def create_knight raise NotImplementedError end def create_archer raise NotImplementedError end end # Betonitehdasluokka OrcWarriorFactory < WarriorFactory def create_knight OrcKnight . uusi loppu def create_archer OrcArcher . uusi loppu loppu # Betonitehdasluokka ElfWarriorFactory < WarriorFactory def create_knight ElfKnight . uusi loppu def create_archer ElfArcher . uusi loppu loppu # Abstrakti Tuoteluokka Knight def tarkastaa itsensä . luokkaa . nimi . split ( '::' ) . viimeinen loppu loppu # Abstrakti Tuoteluokka Archer def tarkastaa itsensä . luokkaa . nimi . split ( '::' ) . viimeinen loppu loppu # Tuoteluokka OrcKnight < Knight end # Tuoteluokka ElfKnight < Knight end # Tuoteluokka OrcArcher < Archer end # Tuoteluokka ElfArcher < Archer end # Asiakasluokka Army def alustus ( tehdas ) @knights = [ ] 3 . kertaa { @knights << tehdas . luo_ritari } @archers = [] 3 . kertaa { @archers << tehdas . create_archer } loppu def inspect "Knights #{ @knights . map ( & :inspect ) } Archers #{ @archers . map ( & :inspect ) } " end end itsevarmasti . _ juokse örkkejä = armeija . new ( OrcWarriorFactory . new ) laittaa "Orcs army: #{ orcs . inspect } " tontut = armeija . uusi ( ElfWarriorFactory . new ) laittaa "Tontut armeija: #{ elves . inspect } " end end AbstractFactoryPattern . juosta # Orkkiarmeija: Knights ["OrcKnight", "OrcKnight", "OrcKnight"] Jousimiehet ["OrcArcher", "OrcArcher", "OrcArcher"] # Haltiaarmeija: Knights ["ElfKnight", "ElfKnight", "ElfKnight"] Jousimiehet ["ElfArcher", "ElfArcher", "ElfArcher"]

Kirjallisuus

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Olio-suunnittelun tekniikat. Suunnittelumallit = Suunnittelumallit: Uudelleenkäytettävän olio-ohjelmiston elementit. - Pietari. : "Peter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (myös ISBN 5-272-00355-1 )

Linkit

Muistiinpanot

  1. Abstrakti tehdaskuvio . Haettu 14. kesäkuuta 2013. Arkistoitu alkuperäisestä 14. kesäkuuta 2013.
  2. Kuvioiden luominen: Abstrakti tehdas . Haettu 14. kesäkuuta 2013. Arkistoitu alkuperäisestä 14. kesäkuuta 2013.
  3. Abstract Factory .NET Design Pattern C#:ssa ja VB:ssä - dofactory.com . www.dofactory.com Käyttöpäivä: 3. maaliskuuta 2016. Arkistoitu alkuperäisestä 3. maaliskuuta 2016.