Delegaatiomalli

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 15. tammikuuta 2015 tarkistetusta versiosta . tarkastukset vaativat 14 muokkausta .
Valtuuskunta
valtuuskunta
Kuvattu suunnittelukuvioissa Ei

Delegointi on perussuunnittelumalli ,  jossa objekti ilmaisee ulkoisesti jonkinlaista käyttäytymistä , mutta todellisuudessa siirtää vastuun tämän käyttäytymisen suorittamisesta siihen liittyvälle objektille . Delegointimalli on perustavanlaatuinen abstraktio , jonka pohjalta muut mallit - koostumus (kutsutaan myös aggregaatioksi), sekoitukset ja aspektit - toteutetaan .

Plussat

Mahdollisuus muuttaa objektin tietyn ilmentymän käyttäytymistä sen sijaan, että luotaisiin uusi luokka perinnön kautta.

Miinukset

Tämä malli tekee yleensä nopeuden optimoinnin vaikeaksi paremman abstraktion puhtauden hyväksi.

Soveltuvuus

Java

Vaikka Java-kieli ei tue delegointia, monet kehitysympäristöt tukevat sitä [1] .

Esimerkkejä

Java

Yksinkertainen esimerkki

Tässä Java - esimerkissä luokassa Bon tynkämenetelmä , joka välittää menetelmät . Luokka teeskentelee omaavansa luokkaattribuutteja . foo()bar()ABA

Lähdeteksti javassa luokka A { void foo () { Järjestelmä . ulos . println ( "A: menetelmä foo() kutsutaan" ); } void bar () { Järjestelmä . ulos . println ( "A: method bar() kutsutaan" ); } } luokka B { // Luo objekti, jonka menetelmät delegoivat käyttäytymistä. A a = uusi A (); void foo () { a . foo (); } void bar () { a . baari (); } } public class Main { public static void main ( String [] args ) { B b = new B (); b . foo (); b . baari (); } } Monimutkainen esimerkki

Käyttöliittymien avulla delegointi voidaan tehdä joustavammin ja tyyppiturvallisemmin . Tässä esimerkissä luokka Cvoi delegoida Ajoko B. Luokassa Con menetelmiä vaihtaa luokkien välillä Aja B. Laitelaajennuksen sisällyttäminen parantaa tyyppiturvallisuutta, koska jokaisen luokan tulee toteuttaa menetelmät rajapinnassa. Suurin haittapuoli on enemmän koodia.

Otetaan esimerkki. Oletetaan, että sinun täytyy toteuttaa ajastin siten, että jokin toiminto kutsutaan tietyn ajan kuluttua. Ajastinohjelmoija haluaa antaa toimintomäärityksen luokkansa käyttäjille (muille ohjelmoijille).

Lähdeteksti javassa /** * Käyttöliittymä kuvaa toiminnon, jota kutsutaan, kun * ajastintapahtuma tapahtuu. */ käyttöliittymä TimerAction { void onTime (); } class WakeUpAction toteuttaa TimerActionin { @Override public void onTime () { Järjestelmä . ulos . println ( "Aika nousta ylös!" ); } } class ChickenIsReadyAction toteuttaa TimerActionin { @Override public void onTime () { System . ulos . println ( "Kana on valmis!" ); } } /** * Ajastinluokka. Tietyissä olosuhteissa TimerAction kutsutaan. */ class Ajastin { TimerAction action ; /** * Toiminto, jota ohjelmoija kutsuu asettaakseen ajan. */ void run () { if ( isTime ()) { action . ajoissa (); } } /** * Jokin toiminto, joka huolehtii koko ajan työstä. Sen * toteutus ei ole kiinnostava tässä yhteydessä. * * @return */ yksityinen boolean isTime () { return true ; } public static void main ( String [ ] args ) { Järjestelmä . ulos . println ( "Anna toimintotyyppi:" ); Skanneriskanneri = uusi Skanneri ( System . in ) ; Merkkijono actionType = skanneri . nextLine (); Ajastinajastin = uusi Ajastin ( ); if ( actionType . equalsIgnoreCase ( "set wake up timer" )) { ajastin . toiminta = uusi WakeUpAction (); } else if ( actionType . equalsIgnoreCase ( "aseta kanaajastin" )) { ajastin . toiminta = uusi ChickenIsReadyAction (); } ajastin . juosta (); }

C++

Monimutkainen esimerkki

Tämä esimerkki on C++- versio yllä olevasta monimutkaisesta Java-esimerkistä. Koska C++:lla ei ole rajapintarakennetta, täysin abstraktilla luokalla on sama rooli . Edut ja haitat ovat periaatteessa samat kuin Java-esimerkissä.

Lähdeteksti c++:ssa #include <iostream> luokka I { julkinen : virtuaalinen tyhjä f () = 0 ; virtuaalinen tyhjä g () = 0 ; }; luokka A : julkinen I { julkinen : void f () { std :: cout << "A: kutsumenetelmä f()" << std :: endl ; } void g () { std :: cout << "A: kutsu menetelmä g()" << std :: endl ; } }; luokka B : julkinen I { julkinen : void f () { std :: cout << "B: kutsu menetelmä f()" << std :: endl ; } void g () { std :: cout << "B: kutsu menetelmä g()" << std :: endl ; } }; luokka C : julkinen I { julkinen : // Konstruktori C () : m_i ( uusi A () ) { } // Tuhoaja virtuaalinen ~ C () { poista m_i ; } void f () { m_i -> f (); } void g () { m_i -> g (); } // Näillä menetelmillä muutamme kenttäobjektin, jonka menetelmät delegoimme void toA:lle () { poista m_i ; m_i = uusiA ( ); } void toB () { poista m_i ; m_i = uusi B (); } yksityinen : // Ilmoitamme objektin, jonka menetelmät delegoimme I * m_i ; }; int main () { Cc ; _ c . f (); c . g (); c . toB (); c . f (); c . g (); paluu 0 ; } /* Tulos: A: kutsu f()-metodia A: kutsu g() -metodia B: kutsu f()-metodia B: kutsu g()-metodia */

C#

Lähdeteksti C# nimiavaruus Patterns { käyttöliittymä I { void f (); voidg ( ); } luokka A : I { public void f () { Järjestelmä . konsoli . WriteLine ( "A: f()-metodin kutsuminen" ); } public void g () { Järjestelmä . konsoli . WriteLine ( "A: g()-metodin kutsuminen" ); } } luokka B : I { public void f () { Järjestelmä . konsoli . WriteLine ( "B: f()-metodin kutsuminen" ); } public void g () { Järjestelmä . konsoli . WriteLine ( "B: kutsuu g()" ); } } luokka C : I { // Luo objekti, jonka menetelmät delegoimme I i = new A (); public void f () { i . f (); } public void g () { i . g (); } // Näillä menetelmillä muutetaan kenttäobjektia , jonka menetelmiä delegoimme public void :lle A () { i = new A (); } public void toB () { i = uusi B (); } } class DelegatePattern { staattinen void Main ( merkkijono [] args ) { C c = new C (); c . f (); c . g (); c . toB (); c . f (); c . g (); Järjestelmä . konsoli . ReadKey (); } } } Ei-triviaali esimerkki

Tämä on esimerkki tapauksesta, jota käytännössä kohdataan usein. Tehtävänä on luoda luokka työntekijäluettelon tallentamista varten. Jokaisen työntekijän tiedot tallennetaan Työntekijä-luokan objektiin. Työntekijä-objektien luettelon tallentamiseen on valmis ja vakioluokka. Se on jo ottanut käyttöön mekanismeja luettelon kanssa työskentelyä varten (esimerkiksi muistin varaaminen, luettelon lisääminen ja poistaminen). Työntekijälista-luokan periminen objektilistaluokasta ei ole tässä hyväksyttävää, koska saamme kaikki menetelmät (myös ne, joista emme ole kiinnostuneita). Lisäksi meidän on joissakin tapauksissa suoritettava tyyppivalua. Tyylikkäin tapa päästä tästä tilanteesta on delegoida jotkin objektiluetteloluokan menetelmistä työntekijäluetteloluokkaan. OOP-säännöissä on parasta esittää objektiluettelo työntekijäluettelon yksityisellä (yksityisellä) menetelmällä. Tässä tapauksessa luetteloon pääsee indeksoijan kautta.

Lähdeteksti C# käyttäen System ; käyttäen System.Collections.Generic ; käyttäen System.Linq ; käyttäen System.Text ; nimiavaruus Työntekijät { /// <summary> /// Luokka työntekijätietojen tallentamiseen. /// </summary> class Työntekijä { yksityinen merkkijono nimi ; yksityinen merkkijonoosasto ; _ public Työntekijä ( merkkijonon nimi , merkkijono osasto ) { this . nimi = nimi ; tämä . osasto = osasto ; } /// <yhteenveto> /// Työntekijän nimi. /// </summary> public string Nimi { get { return this . nimi ; } } /// <yhteenveto> /// Työosasto. /// </summary> public string Osasto { get { return this . osasto ; } } } /// <yhteenveto> /// Luokka työntekijöiden luettelon tallentamiseen. /// </summary> class Työntekijäluettelo { yksityinen luettelo < Työntekijä > työntekijät = new List < Työntekijä >(); /// <yhteenveto> /// Ominaisuus työntekijän saamiseen ja kirjoittamiseen indeksin mukaan. /// </summary> /// <param name="index">Työntekijäindeksi.</param> /// <returns>Työntekijä.</returns> public Työntekijä tämä [ int index ] { get { return työntekijät [ indeksi ]; } set { työntekijät [ indeksi ] = arvo ; } } /// <yhteenveto> /// Uuden työntekijän lisääminen. /// </summary> /// <param name="employee">Uusi työntekijä.</param > public void Lisää ( Työntekijä ) { työntekijää . Lisää ( työntekijä ); } /// <yhteenveto> /// Olemassa olevan työntekijän poistaminen. /// </summary> /// <param name="employee">Poistettava työntekijä.</param> public void Poista ( Työntekijän työntekijä ) { työntekijät . Poista ( työntekijä ); } /// <yhteenveto> /// Työntekijän peräkkäinen haku nimellä. /// </summary> /// <param name="name">Työntekijän nimi.</param> /// <param name="offset">Asema, josta haku aloitetaan.</param> // / < returns>Työntekijäindeksi.</returns> public int GetIndexOfEmployeeByName ( merkkijonon nimi , int offset = 0 ) { for ( int i = offset ; i < työntekijät . Count ; i ++) { if ( työntekijät [ i ]. Nimi == nimi ) { return i ; } } paluu - 1 ; } } class Ohjelma { static void Main ( string [] args ) { //Luo luettelo työntekijöistä ja lisää siihen merkintöjä EmployeesList empList = new EmployeesList (); empList . Lisää ( uusi työntekijä ( "Shlensky Dmitry" , "web-studio" )); empList . Lisää ( uusi työntekijä ( "Kusy Nazar" , "verkkostudio" )); empList . Lisää ( uusi työntekijä ( "Magpie Orest" , "verkkostudio" )); //Hae työntekijä Kusyi Nazar ja näytä tulos, kun haet alusta ja 2. aseman konsolista . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); konsoli . WriteLine ( empList . GetIndexOfEmployeeByName ( " Kusy Nazar " , 2 ). ToString ()); //Etsi ja poista työntekijä Soroka Orestes empList . Poista ( empList [ empList . GetIndexOfEmployeeByName ( " Harakka Orestes " )]); } } } Lähdeteksti kielellä C#2 käyttäen System ; käyttäen System.Collections.Generic ; käyttäen System.Linq ; käyttäen System.Text ; nimiavaruus Työntekijät { /// <summary> /// Luokka työntekijätietojen tallentamiseen. /// </summary> class Työntekijä { yksityinen merkkijono nimi ; yksityinen merkkijonoosasto ; _ public Työntekijä ( merkkijonon nimi , merkkijono osasto ) { this . nimi = nimi ; tämä . osasto = osasto ; } /// <yhteenveto> /// Työntekijän nimi. /// </summary> public string Nimi { get { return this . nimi ; } } /// <yhteenveto> /// Työosasto. /// </summary> public string Osasto { get { return this . osasto ; } } } /// <yhteenveto> /// Luokka työntekijöiden luettelon tallentamiseen. /// </summary> class Työntekijäluettelo { yksityinen luettelo < Työntekijä > työntekijät = new List < Työntekijä >(); /// <yhteenveto> /// Ominaisuus työntekijän saamiseen ja kirjoittamiseen indeksin mukaan. /// </summary> /// <param name="index">Työntekijäindeksi.</param> /// <returns>Työntekijä.</returns> public Työntekijä tämä [ int index ] { get { return työntekijät [ indeksi ]; } set { työntekijät [ indeksi ] = arvo ; } } /// <yhteenveto> /// Omaisuus työntekijän hankkimiseen ja kirjoittamiseen nimellä. /// </summary> /// <param name="name">Työntekijän nimi.</param> /// <returns>Ensimmäinen työntekijä, jonka nimi vastasi tai null</returns> julkinen Työntekijä tämä [ merkkijonon nimi ] { get { foreach ( Työntekijänimike työntekijöissä ) { if ( nimike . Nimi == nimi ) return item ; _ _ } return null ; } } /// <yhteenveto> /// Uuden työntekijän lisääminen. /// </summary> /// <param name="employee">Uusi työntekijä.</param > public void Lisää ( Työntekijä ) { työntekijää . Lisää ( työntekijä ); } /// <yhteenveto> /// Olemassa olevan työntekijän poistaminen. /// </summary> /// <param name="employee">Poistettava työntekijä.</param> public void Poista ( Työntekijän työntekijä ) { työntekijät . Poista ( työntekijä ); } /// <yhteenveto> /// Työntekijän peräkkäinen haku nimellä. /// </summary> /// <param name="name">Työntekijän nimi.</param> /// <param name="offset">Asema, josta haku aloitetaan.</param> // / < returns>Työntekijäindeksi.</returns> public int GetIndexOfEmployeeByName ( merkkijonon nimi , int offset ) { int indeksi = - 1 ; for ( int i = offset ; i < työntekijät . Count ; i ++ ) { if ( työntekijät [ i ]. Nimi == nimi ) { indeksi = i ; tauko ; } } paluuindeksi ; _ } /// <yhteenveto> /// Työntekijän peräkkäinen haku nimellä. /// </summary> /// <param name="name">Työntekijän nimi.</param> /// <returns>Työntekijäindeksi.</returns> public int GetIndexOfEmployeeByName ( merkkijonon nimi ) { return GetIndexOfEmployeeByName ( nimi , 0 ); } } class Ohjelma { static void Main ( string [] args ) { //Luo luettelo työntekijöistä ja lisää siihen merkintöjä EmployeesList empList = new EmployeesList (); empList . Lisää ( uusi työntekijä ( "Shlensky Dmitry" , "web-studio" )); empList . Lisää ( uusi työntekijä ( "Kusy Nazar" , "verkkostudio" )); empList . Lisää ( uusi työntekijä ( "Magpie Orest" , "verkkostudio" )); //Hae työntekijä Kusyi Nazar ja näytä tulos, kun haet alusta ja 2. aseman konsolista . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); konsoli . WriteLine ( empList . GetIndexOfEmployeeByName ( " Kusy Nazar " , 2 ). ToString ()); //Etsi ja poista työntekijä Soroka Orestes empList . Poista ( empList [ "Magpie Orestes" ]); } } }

Objective-C 2.0

Yksinkertainen esimerkki Objective-C lähdekoodi enum { GLEngineChangeView }; @interface GLEngine  : NSObject { id _delegate ; BOOL_tapahtuma [ NUMERO ] ; } - ( id ) edustaja ; - ( void ) setDelegate: ( id ) delegate ; - ( void ) changeView: ( GLView * ) view ; @loppu @protocol GLEngineDelegate < NSObject > @valinnainen - ( BOOL ) engine : ( GLEngine * ) engine changeView : ( GLView * ) näkymä ; @loppu @interface GLEngine (sisäinen) - ( void ) registerDelegate ; @loppu @implementationGLEngine _ - ( id ) edustaja { return _delegate ; } - ( void ) setDelegate: ( id ) delegate { _delegate = edustaja ; [ itserekisteröinninvaltuutettu ] ; } - ( void ) changeView: ( GLView * ) view { if ( _event [ GLEngineChangeView ]) { // delegoi pyyntö if ([ _delegate engine : self changeView : view ]) { // käytä muokattua näkymää } muu // pyyntöä ei käsitelty } // tai käytä tavallista tapaa } - ( void ) registerDelegate { if ([ _delegate responseToSelector : @selector ( moottori : changeView :)]) { _event [ GLEngineChangeView ] = KYLLÄ ; } } @loppu @interface MyGLEngineDelegate  : NSObject < GLEngineDelegate > { // } @loppu @implementationMyGLEngineDelegate _ - ( BOOL ) moottori: ( Engine * ) engine changeView: ( GLView * ) view { // muuta näkymää } @loppu

ObjectPascal

Yksinkertainen esimerkki Lähdeteksti Object Pascalissa tyyppi IDelegateInterface = rajapintamenettely Method1 ; _ menettely Menetelmä 2 ; loppu ; TClassA = luokka ( TInterfacedObject , IDelegateInterface ) julkinen menettely Method1 ; menettely Menetelmä 2 ; loppu ; TClassB = luokka ( TInterfacedObject , IDelegateInterface ) julkinen menettely Method1 ; menettely Menetelmä 2 ; loppu ; TClassDel = luokka ( TInterfacedObject , IDelegateInterface ) yksityinen FInterface : IDelegateInterface ; julkinen menettely Menetelmä1 ; menettely Menetelmä 2 ; menettely ToClassA ; menettely ToClassB ; loppu ; toteutus {TCclassA} menettely TClassA . menetelmä1 ; begin Writeln ( 'TClassA.Method1' ) ; loppu ; menettely TClassA . menetelmä 2 ; begin Writeln ( 'TClassA.Method2' ) ; loppu ; {TC-luokka B} menettely TClassB . menetelmä1 ; begin Writeln ( 'TClassB.Method1' ) ; loppu ; menettely TClassB . menetelmä 2 ; begin Writeln ( 'TClassB.Method2' ) ; loppu ; {TClassDel} menettely TClassDel . menetelmä1 ; aloita FInterface . menetelmä1 ; loppu ; menettely TClassDel . menetelmä 2 ; aloita FInterface . menetelmä 2 ; loppu ; menettely TClassDel . ToClassA ; begin FIInterface := TClassA . luoda ; loppu ; menettely TClassDel . ToClassB ; begin FIInterface := TClassB . luoda ; loppu ; Ei-triviaali esimerkki

Tämä esimerkki on Object Pascal -versio yllä olevasta ei-triviaalista esimerkistä.

Lähdeteksti Object Pascalissa yksikkö Työnantajat ; käyttöliittymä käyttää Contnrs ; type // Luokka työntekijätietojen tallentamiseen TEmployee = class yksityinen FName : string ; FDepartament : string ; public konstruktori Luo ( nimi , osasto : merkkijono ) ; julkaistu ominaisuus Nimi : merkkijono lue FName ; ominaisuus Osasto : merkkijono lue FDepartament ; loppu ; // Luokka työntekijöiden luettelon tallentamiseen TEmployeersList = class yksityinen // Objektiluettelon luokan objekti FEmployeersList : TObjectList ; toiminto GetTemployee ( Indeksi : Kokonaisluku ) : TEmployee ; menettely SetEmployee ( Indeksi : Kokonaisluku ; const Arvo : TEmployee ) ; julkinen rakentaja Luo ; tuhoaja Tuhoa ; ohittaa ; toiminto Lisää ( Työntekijä : TEmployee ) : Kokonaisluku ; menettely Poista ( Työntekijä : TEmployee ) ; toiminto IndexEmployeeByName ( Nimi : merkkijono ; Offset : Kokonaisluku = 0 ) : Kokonaisluku ; ominaisuus Työntekijät [ Hakemisto : Kokonaisluku ] : TEmployee lukea GetTemployee kirjoittaa SetEmployee ; oletusarvo ; loppu ; toteutus {työntekijä} rakentaja TEtyöntekijä . Luo ( nimi , osasto : merkkijono ) ; begin FName := Nimi ; FDepartament := Osasto ; loppu ; { TemployeersList } rakentaja TEmployeersList . luoda ; begin // Luo objekti, jonka menetelmät delegoimme FEmployeersList := TObjectList . luoda ; loppu ; destructor TEmployeersList . Tuhoa ; aloita FEmployersList . Ilmainen ; perinnöllinen ; loppu ; toiminto TemployeersList . GetTemployee ( Indeksi : Kokonaisluku ) : TEmployee ; begin Tulos := FEmployeersList [ Index ] as TEmployee ; loppu ; menettely TEmployeersList . SetEmployee ( Indeksi : Kokonaisluku ; const Arvo : TEmployee ) ; begin FEmployeersList [ Hakemisto ] := Arvo ; loppu ; toiminto TemployeersList . IndexEmployeeByName ( Nimi : merkkijono ; Offset : Kokonaisluku = 0 ) : Kokonaisluku ; // Työntekijän peräkkäinen haku nimen perusteella // Offset-argumentin avulla voit määrittää paikan, josta haetaan. // Jos työntekijää ei löydy, se palauttaa arvon, joka on pienempi kuin nolla (-1) var Index : Integer ; alkaa Tulos := - 1 ; // Olettaen, että se ei ole luettelossa Index : = FEmployeersList . Count - 1 offset do if ( FEmployeersList [ Index ] as TEmployee ) . _ Nimi = Nimi ja aloita sitten Tulos := Hakemisto ; poistua ; loppu ; loppu ; toiminto TemployeersList . Lisää ( Työntekijä : TEmployee ) : Kokonaisluku ; begin Tulos := FEmployeersList . Lisää ( työntekijä ) ; loppu ; menettely TEmployeersList . Poista ( Työntekijä : TEmployee ) ; aloita FEmployersList . Poista ( työntekijä ) ; loppu ; loppua .

Valitettavasti kaikki ohjelmoijat eivät käytä delegointimallia. Esimerkiksi Borland ( Delphi - ohjelmointiympäristön kehittäjä ) perusluokkakirjastossaan peri edellä mainitun TObjectList-objektiluetteloluokan TList - osoitinlistaluokasta . Tämä aiheutti tyytymättömyyttä joidenkin kokeneiden ohjelmoijien keskuudessa.

PHP5

Yksinkertainen esimerkki

Tämä esimerkki on PHP -versio yllä olevasta yksinkertaisesta Java -esimerkistä .

PHP5 lähdekoodi <?php luokka A { public function f () { print "A: Kutsu menetelmä f()<br />" ; } public function g () { print "A: Kutsumme menetelmää g()<br />" ; } } luokka C { yksityinen $_a ; julkinen funktio __construct () { $this -> _a = new A ; } julkinen funktio f () { $this -> _a -> f (); } julkinen funktio g () { $this -> _a -> g (); } public function y () { print "C: kutsu menetelmä y()<br />" ; } } $obj = uusi C ; $obj -> f (); $obj -> g (); $obj -> y (); ?> Monimutkainen esimerkki

Tämä esimerkki on PHP -versio yllä olevasta monimutkaisesta Java -esimerkistä .

PHP5 lähdekoodi <?php // käytä liitäntää tyypin turvarajapinnalle I { public function f (); julkinen tehtävä g (); } luokka A toteuttaa I { public function f () { print "A: Kutsu f()<br />" ; } public function g () { print "A: Kutsumme menetelmää g()<br />" ; } } luokka B toteuttaa I { public function f () { print "B: Kutsu f()<br />" ; } public function g () { print "B: Kutsu menetelmä g()<br />" ; } } luokka C toteuttaa I { yksityinen $_i ; // luo objekti, jonka menetelmille delegoidaan julkinen toiminto __construct () { $this -> _i = new A ; } // näillä menetelmillä muutamme kenttäobjektia , jonka menetelmillä delegoimme julkisen funktion A:lle () { $this -> _i = new A ; } julkinen funktio toB () { $this -> _i = new B ; } // delegoidut menetelmät public function f () { $this -> _i -> f (); } julkinen funktio g () { $this -> _i -> g (); } } $obj = uusi C ; $obj -> f (); $obj -> g (); $obj -> toB (); $obj -> f (); $obj -> g (); ?> Ei-triviaali esimerkki

Tämä esimerkki on PHP -versio yllä olevasta ei-triviaalista esimerkistä.

PHP5 lähdekoodi <?php // luokka työntekijätietojen tallentamiseen class Työntekijä { yksityinen $_nimi ; yksityinen $_osasto ; julkinen funktio __konstrukti ( $nimi , $ osasto ) { $this -> _name = $nimi ; $this -> _departament = $ osasto ; } public function getName () { return $this -> _name ; } public function getDepartament () { return $this -> _departament ; } } // luokka objektiluettelon tallentamiseen class ObjectList { yksityinen $_objList ; julkinen funktio __construct () { $this -> free (); } /** *ei ole tylsää! */ julkinen funktio vapaa () { $this -> _objList = array (); } public function count () { paluumäärä ( $this - > _objList ); } julkinen funktio add ( $obj ) { array_push ( $this -> _objList , $obj ); } julkinen funktio poista ( $obj ) { $k = array_search ( $obj , $this -> _objList , true ); if ( $k !== false ) { unset ( $this -> _objList [ $k ] ); } } julkinen funktio get ( $indeksi ) { return $this -> _objList [ $index ]; } julkinen funktiojoukko ( $index , $obj ) { $this - > _objList [ $index ] = $obj ; } } // luokka työntekijöiden tallentamiseen class EmployeeList { // luokan objekti "objektien luettelo" yksityinen $_employeersList ; public function __construct (){ // luo objekti, jonka menetelmät delegoimme $this -> _employeersList = new ObjectList ; } public function getEmployer ( $indeksi ) { return $this -> _employeersList -> get ( $indeksi ); } julkinen funktio setEmployer ( $indeksi , työntekijä $objEmployer ) { $this -> _employeersList -> set ( $indeksi , $objEmployer ); } public function __destruct () { $this -> _employeersList -> free (); } julkinen funktio add ( Työntekijä $objEmployer ) { $this -> _employeersList -> add ( $objEmployer ); } julkinen toiminto poista ( Työntekijä $objEmployer ) { $this -> _employeersList -> poista ( $objEmployer ); } // peräkkäinen työntekijän haku nimellä // $offset-argumentin avulla voit asettaa paikan, josta haetaan. // jos työntekijää ei löydy, se palauttaa arvon, joka on pienempi kuin nolla (-1) julkinen funktio getIndexByName ( $nimi , $offset = 0 ) { $tulos = - 1 ; // oletetaan, että se ei ole luettelossa $cnt = $this -> _employeersList -> count (); for ( $i = $offset ; $i < $cnt ; $i ++ ) { if ( ! strcmp ( $nimi , $this -> _employeersList -> get ( $i ) -> getName () ) ) { $tulos = $i ; tauko ; } } return $tulos ; } } $obj1 = uusi työntekijä ( "Tanasiychuk Stepan" , "web-studio" ); $obj2 = uusi työntekijä ( "Kusy Nazar" , "verkkostudio" ); $obj3 = uusi työntekijä ( "Magpie Orest" , "web-studio" ); $objList = uusi Työntekijälista (); $objList -> add ( $obj1 ); $objList -> add ( $obj2 ); $objList -> add ( $obj3 ); echo "<pre>" ; print_r ( $objList ); echo "<hr>" ; $index = $objList -> getIndexByName ( "Kusy Nazar" ); $obj4 = $objList -> getEmployer ( $indeksi ); print_r ( $obj4 ); echo "<hr>" ; $objList -> setEmployer ( 2 , $obj4 ); print_r ( $objList ); echo "</pre>" ; ?>

Python

Yksinkertainen esimerkki

Lähdekoodi Pythonissa

#coding: utf-8 #python 3 luokka A : def f ( itse ): print ( 'A : kutsuva menetelmä f' ) def g ( itse ): print ( 'A : kutsuva menetelmä g' ) luokka C : def __init__ ( itse ): itse . A = A () def f ( itse ): palauta itse . A. _ f () def g ( itse ): palauta itse . A. _ g () c = C () c . f () #A: kutsumenetelmä f c . g () #A: kutsumenetelmä g

JavaScript

Yksinkertainen esimerkki JavaScript lähdekoodi funktio A () { tämä . f = function () { hälytys ( "A: f()-menetelmän kutsuminen" ); }; tämä . g = funktio () { hälytys ( "A: kutsumenetelmä g()" ); }; } funktio C () { var a = uusi A (); tämä . f = funktio () { a . f (); }; tämä . g = funktio () { a . g (); }; } var c = uusi C (); c . f (); // "A: f()-metodin kutsuminen" c . g (); // "A: kutsu g()-metodia" Monimutkainen esimerkki JavaScript lähdekoodi funktio A () { tämä . f = function () { hälytys ( "A: f()-menetelmän kutsuminen" ); }; tämä . g = funktio () { hälytys ( "A: kutsumenetelmä g()" ); }; } funktio B () { tämä . f = funktio () { hälytys ( "B: kutsumenetelmä f()" ); }; tämä . g = funktio () { hälytys ( "B: kutsumenetelmä g()" ); }; } funktio C () { // instantoi A ja B kerran var a = uusi A (); varb = uusi B ( ); var cur = a ; // viittaus nykyiseen objektiin menetelmien toteutuksen kanssa; oletusarvo - A tämä . toA = funktio () { cur = a ; }; tämä . toB = funktio () { cur = b ; }; tämä . f = funktio () { cur . f (); }; tämä . g = funktio () { cur . g (); }; } var c = uusi C (); c . f (); // "A: f()-metodin kutsuminen" c . g (); // "A: g()-menetelmän kutsuminen" c . toB (); c . f (); // "B: f()-menetelmän kutsuminen" c . g (); // "B: g()-menetelmän kutsuminen" Ei-triviaali esimerkki JavaScript lähdekoodi toiminto Työntekijä ( nimi , osasto ) { this . getName = function ( ) { paluunimi ; }; tämä . getDepartament = function ( ) { paluuosasto ; }; tämä . toString = function () { // muuntaa merkkijonoksi virheenkorjauksen helpottamiseksi return "Työntekijä " + nimi + ", " + departament ; }; } function EmployeesList () { var työntekijät = []; tämä . add = function ( ) { // funktio ottaa mielivaltaisen määrän argumentteja kohteelle ( var i = 0 , l = argumentit . pituus ; i < l ; i ++ ) { if ( argumentit [ i ]. constructor == Työntekijä ) { työntekijät . push ( argumentit [ i ]); } } }; tämä . set = function ( obj , index ) { // tyypin tarkistus if ( obj . constructor == Työntekijä ) { poista työntekijät [ hakemisto ]; työntekijät [ indeksi ] = obj ; } }; tämä . poista = funktio ( obj ) { for ( var i = 0 , l = työntekijät . pituus ; i < l ; i ++ ) { if ( työntekijät [ i ] == obj ) { työntekijät . liitos ( i , 1 ); minä- ; _ l- ; _ } } }; tämä . getByIndex = funktio ( num ) { palauttaa työntekijät [ määrä ]; }; tämä . getIndexByName = funktio ( nimi , offset ) { // peräkkäinen työntekijän haku nimellä // offset-argumentin avulla voit asettaa paikan, josta haetaan. (oletus 0) // jos työntekijää ei löydy, palautus -1 for ( var i = offset || 0 , l = työntekijät . pituus ; i < l ; i ++ ) { if ( työntekijät [ i ]. getName () = = nimi ) return i ; } paluu - 1 ; }; tämä . toString = function () { // muuntaa merkkijonoksi virheenkorjauksen helpottamiseksi var ret = "" ; for ( var i = 0 , l = työntekijät . pituus ; i < l ; i ++ ) { ret += i + " : " + työntekijää [ i ] + "\n " ; } return ret ; }; } var o1 = uusi työntekijä ( "Tanasiychuk Stepan" , "verkkostudio" ); var o2 = uusi työntekijä ( "Kusy Nazar" , "verkkostudio" ); var o3 = uusi työntekijä ( "Magpie Orest" , "web-studio" ); var emps = new EmployeesList (); emps . lisää ( o1 , o2 , o3 ); // voit lisätä yksitellen hälytyksen ( emps ); // "0: Työntekijä Tanasiychuk Stepan, web-studio // 1: Työntekijä Kusyi Nazar, web-studio // 2: Työntekijä Soroka Orest, web-studio" var obj4 = emps . getByIndex ( emps . getIndexByName ( " Kusy Nazar " ) ); // saada linkki työntekijän varoitukseen ( obj4 ); // "Työntekijä Kusyi Nazar, web-studio" emps . joukko ( obj4 , 2 ); // 2. (nollasta) työntekijän sijaan lisää obj4- hälytys ( emps ); // "0: Työntekijä Tanasiychuk Stepan, web-studio // 1: Työntekijä Kusyi Nazar, web-studio // 2: Työntekijä Kusyi Nazar, web-studio" emps . poista ( obj4 ); // poista työntekijän obj4- hälytys ( emps ); // "0: Työntekijä Tanasiychuk Stepan, web-studio"

VB.NET

Monimutkainen esimerkki Lähdekoodi VB.NET:ssä Nimitilan mallit Liitäntä I Sub f () Sub g ( ) Pääteliitäntä Luokka A toteuttaa I Julkinen Sub f () Toteuttaa I . f Järjestelmä . konsoli . WriteLine ( "A: f()-menetelmän kutsuminen" ) End Sub Julkinen ala g () Toteuttaa I . g Järjestelmä . konsoli . WriteLine ( "A: g()-metodin kutsuminen" ) End Sub End Class Luokan B työkoneet I Julkinen Sub f () Toteuttaa I . f Järjestelmä . konsoli . WriteLine ( "B: f()-menetelmän kutsuminen" ) End Sub Julkinen ala g () Toteuttaa I . g Järjestelmä . konsoli . WriteLine ( "B: g()-metodin kutsuminen" ) End Sub End Class Luokan C työkoneet I ' Luo objekti, jonka menetelmät delegoimme Yksityinen i As I = Uusi A () Julkinen Sub f () Toteuttaa i . fi . _ f () End Sub Julkinen ala g () Toteuttaa i . g i . g () End Sub ' Näillä menetelmillä muutamme kenttäobjektia , jonka menetelmät delegoimme Public Sub :lle () i = Uusi A () End Sub Public Sub toB () i = Uusi B () End Sub End Class Luokan delegaattimalli Jaettu Sub Main () Himmeä c Uutena C ( ) c . f () c . g () c . toB () c . f () c . g () Järjestelmä . konsoli . ReadKey () End Sub End Class End Namespace Ei-triviaali esimerkki Lähdekoodi VB.NET:ssä Tuonti System.Collections.Generic Imports System.Linq Imports System.Text Nimiavaruus Työntekijät ''' <summary> '''' Luokka työntekijätietojen tallentamiseen. ''' ' </summary > Luokka Työntekijä Yksityinen m_nimi Merkkijonona Yksityinen m_osasto Merkkijonona Public Sub New ( ByVal nimi As String , ByVal departament As String ) Me . m_nimi = nimi Minä . m_osasto = osasto End Sub '''' <yhteenveto> '''' Työntekijän nimi. '''' </summary> Julkinen vain luku -ominaisuuden nimi () Merkkijonona Get Return Me . m_name End Hanki loppuominaisuus _ '''' <yhteenveto> '''' Työosasto. '''' </summary> Julkinen vain luku -omaisuusosasto ( ) Merkkijonona Get Return Me . m_department End Get Lopeta omaisuuden loppuluokka _ '''' <yhteenveto> '''' Luokka työntekijöiden luettelon tallentamiseen. '''' </summary> Luokka Työntekijäluettelo Yksityiset työntekijät uutena luettelona ( työntekijöistä ) ( ) '''' <yhteenveto> '''' Ominaisuus työntekijän hakemiseen ja kirjoittamiseen indeksin mukaan. '''' </summary> '''' <param name="index">Työntekijäindeksi.</param> ' '' <returns>Työntekijä.</returns > Julkisen omaisuuden oletuskohde ( ByVal - indeksi Kokonaislukuna ) Työntekijän saajana Paluutyöntekijät ( indeksi ) End Get Set ( ByVal value As Employee ) työntekijät ( indeksi ) = arvo End Set End Property _ '''' <yhteenveto> '''' Uuden työntekijän lisääminen. '''' </summary> ''' <param name="employee">Uusi työntekijä.</ param > Julkinen alalisäys ( ByValin työntekijä Työntekijänä ) työntekijät . Lisää ( työntekijä ) End Sub '''' <yhteenveto> '''' Poista olemassa oleva työntekijä. '''' </summary> ''' <param name="employee"> Poistettava työntekijä .</param> Julkinen alipoisto ( ByValin työntekijä Työntekijänä ) työntekijät . Poista ( työntekijä ) End Sub '''' <yhteenveto> ''' Työntekijän peräkkäinen haku nimellä. '''' </summary> '''' <param name="name">Työntekijän nimi.</param> ''' <returns>Työntekijäindeksi.</ returns > Julkinen funktio GetIndexOfEmployeeByName ( ByValin nimi merkkijonona ) Kokonaislukuna Dim indeksi Kokonaislukuna = - 1 _ i As Integer = 0 Työntekijöille . _ _ Laske - 1 Jos työntekijät ( i ). Nimi = nimi Siis indeksi = i Poistu For End If Next Palaa indeksi End Function '''' <yhteenveto> ''' Työntekijän peräkkäinen haku nimellä. '''' </summary> '''' <param name="name">Työntekijän nimi.</param> ''' <param name="offset">Asema, josta haku aloitetaan.</param> '' ' < palauttaa> Työntekijäindeksi .< / returns > Julkinen funktio GetIndexOfEmployeeByName ( ByVal nimi As String , ByVal offset Kokonaislukuna ) Kokonaislukuna Himmeä indeksi Kokonaislukuna = - 1 i As Integer = offset Työntekijöille . _ _ Laske - 1 Jos työntekijät ( i ). Nimi = nimi Siis indeksi = i Poistu For End If Next Palaa indeksi End Function End Class Luokkaohjelman jaettu alapää ( ) 'Luo luettelo työntekijöistä ja lisää siihen merkintöjä Dim empList As New EmployeesList ( ) empList . Lisää ( Uusi työntekijä ( "Shlensky Dmitry" , "web-studio" )) empList . Lisää ( Uusi työntekijä ( "Kusy Nazar" , "verkkostudio" )) empList . Lisää ( Uusi työntekijä ( "Magpie Orest" , "verkkostudio" ))) "Etsitään työntekijää Kusyi Nazaria ja näytetään tulos, kun haetaan alusta ja 2. aseman konsolista . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()) Konsoli . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()) 'Etsi ja poista työntekijä Soroka Orestes empList . Poista ( empList ( empList . GetIndexOfEmployeeByName ( "Magpie Orestes" ))) Konsoli . Lue () End Sub End Class End Namespace

Katso myös

Muistiinpanot

  1. Bruce Eckel. Java-filosofia. - 4. painos. - LLC Publishing House "Peter", 2016. - S. 215. - 1165 s.

Kirjallisuus

  • Julian Bucknell "Perusalgoritmit ja tietorakenteet Delphissä". Ed. Diasoft 2003
  • Grand M. Design Patterns Javassa. 2004
  • Bruce Eckel "Java-filosofia". Ed. "Petteri" 2016