Delegationsmønster

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 15. januar 2015; checks kræver 14 redigeringer .
Delegation
delegation
Beskrevet i Design Patterns Ikke

Delegering er et  grundlæggende designmønster, hvor et objekt eksternt udtrykker en vis adfærd , men i virkeligheden overfører ansvaret for at udføre denne adfærd til et relateret objekt. Delegationsmønsteret er den grundlæggende abstraktion , hvorpå de andre mønstre - sammensætning (også kaldet aggregering), mixins og aspekter - er implementeret .

Fordele

Evnen til at ændre adfærden for en bestemt forekomst af et objekt i stedet for at skabe en ny klasse gennem arv.

Ulemper

Dette mønster gør det generelt vanskeligt at optimere for hastighed til fordel for forbedret abstraktionsrenhed.

Anvendelse

Java

Selvom delegering ikke understøttes af Java-sproget, understøttes det af mange udviklingsmiljøer [1] .

Eksempler

Java

Et simpelt eksempel

I dette Java - eksempel Bhar klassen en stubmetode , der sender metoder til . Klassen foregiver at have klasseattributter . foo()bar()ABA

Kildetekst i java klasse A { void foo () { System . ud . println ( "A: metode foo() kaldet" ); } void bar () { System . ud . println ( "A: metode bar() kaldet" ); } } klasse B { // Opret et objekt, hvis metoder vil uddelegere adfærd. A a = nyt A (); void foo () { en . foo (); } void bar () { a . bar (); } } public class Main { public static void main ( String [] args ) { B b = new B (); b . foo (); b . bar (); } } Kompleks eksempel

Ved at bruge grænseflader kan delegering ske på en mere fleksibel og typesikker måde. I dette eksempel kan klassen Cuddelegere til Aenten B. Klassen Char metoder til at skifte mellem klasser Aog B. Inkludering af redskabsudvidelsen forbedrer typesikkerheden, fordi hver klasse skal implementere metoderne i grænsefladen. Den største ulempe er mere kode.

Lad os tage et eksempel. Antag, at du skal implementere en timer på en sådan måde, at en funktion kaldes efter et vist tidsrum. Timer-programmøren ønsker at give en funktionstildeling til brugerne af sin klasse (andre programmører).

Kildetekst i java /** * Grænsefladen beskriver den handling, der vil blive kaldt, når * timerhændelsen indtræffer. */ interface TimerAction { void onTime (); } klasse WakeUpAction implementerer TimerAction { @Override public void onTime () { System . ud . println ( "Tid til at stå op!" ); } } class ChickenIsReadyAction implementerer TimerAction { @Override public void onTime () { System . ud . println ( "Kyllingen er klar!" ); } } /** * Timer klasse. Under visse forhold kaldes TimerAction. */ class Timer { TimerAction handling ; /** * En funktion, som programmøren kalder for at indstille tiden. */ void run () { if ( isTime ()) { handling . OnTime (); } } /** * Nogen funktion, der tager sig af hele tiden arbejde. Dens * implementering er ikke interessant i denne sammenhæng. * * @return */ private boolean isTime () { return true ; } public static void main ( String [] args ) { System . ud . println ( "Indtast handlingstype:" ); Scanner scanner = ny Scanner ( System . in ); String actionType = scanner . næste linje (); Timer timer = ny Timer (); if ( actionType . equalsIgnoreCase ( "indstil wake up timer" )) { timer . action = ny WakeUpAction (); } else if ( actionType . equalsIgnoreCase ( "indstil kyllingetimeren" )) { timer . action = new ChickenIsReadyAction (); } timer . køre (); }

C++

Kompleks eksempel

Dette eksempel er en C++- version af det komplekse Java-eksempel ovenfor. Da C++ ikke har en grænsefladekonstruktion, spiller den fuldt abstrakte klasse den samme rolle . Fordelene og ulemperne er grundlæggende de samme som i Java-eksemplet.

Kildetekst i c++ #include <iostream> klasse I { offentligt : virtuelt tomrum f () = 0 ; virtuelt tomrum g () = 0 ; }; klasse A : offentlig I { offentligt : void f () { std :: cout << "A: kalder metode f()" << std :: endl ; } void g () { std :: cout << "A: kaldemetode g()" << std :: endl ; } }; klasse B : offentlig I { offentligt : void f () { std :: cout << "B: kaldemetode f()" << std :: endl ; } void g () { std :: cout << "B: kaldemetode g()" << std :: endl ; } }; klasse C : offentlig I { offentligt : // Konstruktør C () : m_i ( ny A () ) { } // Destructor virtual ~ C () { slet m_i ; } void f () { m_i -> f (); } void g () { m_i -> g (); } // Med disse metoder ændrer vi feltobjektet , hvis metoder vi uddelegerer void til A () { slet m_i ; m_i = newA ( ); } void toB () { slet m_i ; m_i = nyt B (); } privat : // Vi erklærer et objekt, hvis metoder vi vil uddelegere I * m_i ; }; int main () { Cc ; _ c . f (); c . g (); c . toB (); c . f (); c . g (); returnere 0 ; } /* Output: A: kald f()-metoden A: kald g()- metoden B: kald f()-metoden B: kald g()-metoden */

C#

Kildetekst i C# navneområde Patterns { interface I { void f (); voidg ( ); } klasse A : I { public void f () { System . Konsol . WriteLine ( "A: kalder f()-metoden" ); } public void g () { System . Konsol . WriteLine ( "A: kalder g()-metoden" ); } } klasse B : I { public void f () { System . Konsol . WriteLine ( "B: kalder f()-metoden" ); } public void g () { System . Konsol . WriteLine ( "B: kalder g()" ); } } klasse C : I { // Opret et objekt, hvis metoder vi vil uddelegere I i = nyt A (); offentlig void f () { i . f (); } offentlig void g () { i . g (); } // Med disse metoder ændrer vi feltobjektet, hvis metoder vi vil delegere public void tilA () { i = new A (); } public void toB () { i = new B (); } } klasse DelegatePattern { static void Main ( string [] args ) { C c = new C (); c . f (); c . g (); c . toB (); c . f (); c . g (); System . Konsol . ReadKey (); } } } Ikke-trivielt eksempel

Dette er et eksempel på en sag, man ofte støder på i praksis. Der er en opgave at oprette en klasse til opbevaring af listen over medarbejdere. Hver medarbejders data gemmes i et objekt af klassen Medarbejder. Der er en færdiglavet og standardklasse til lagring af en liste over medarbejderobjekter. Den har allerede implementeret mekanismer til at arbejde med listen (for eksempel hukommelsesallokering, tilføjelse og fjernelse fra listen). At arve medarbejderlisteklassen fra objektlisteklassen er ikke acceptabel her, fordi vi får alle metoderne (også dem, vi ikke er interesserede i). Derudover vil vi i nogle tilfælde skulle udføre typestøbning. Den mest elegante vej ud af denne sag er at uddelegere nogle af metoderne i objektlisteklassen til medarbejderlisteklassen. I OOP-regler er det bedst at repræsentere listen over objekter med en privat (privat) metode af listen over medarbejdere. I dette tilfælde kan listen tilgås via en indeksering.

Kildetekst i C# bruger System ; ved hjælp af System.Collections.Generic ; ved hjælp af System.Linq ; ved hjælp af System.Text ; navneområde Medarbejdere { /// <resumé> /// Klasse til lagring af medarbejderdata. /// </summary> class Employee { private string name ; privat strengeafdeling ; _ offentlig Medarbejder ( strengnavn , strengafdeling ) { dette . _ _ navn = navn ; dette . afdeling = afdeling ; } /// <resumé> /// Medarbejdernavn. /// </summary> offentlig streng Navn { get { return this . navn ; } } /// <resumé> /// Arbejdsafdeling. /// </summary> public string Department { get { return this . afdeling ; } } } /// <resumé> /// Klasse til lagring af en liste over medarbejdere. /// </summary> class EmployeesList { private List < Employee > employee = new List < Employee >(); /// <resumé> /// Ejendom til at få og skrive en medarbejder efter indeks. /// </summary> /// <param name="index">Medarbejderindeks.</param> /// <returns>Medarbejder.</returns> public Employee this [ int index ] { get { return medarbejdere [ indeks ]; } sæt { medarbejdere [ indeks ] = værdi ; } } /// <resumé> /// Tilføjelse af en ny medarbejder. /// </summary> /// <param name="employee">Ny medarbejder.</param> public void Tilføj ( Medarbejder medarbejder ) { medarbejdere . Tilføj ( medarbejder ); } /// <resumé> /// Sletning af en eksisterende medarbejder. /// </summary> /// <param name="employee">Medarbejderen, der skal fjernes.</param> public void Fjern ( Medarbejder medarbejder ) { ansatte . Fjern ( medarbejder ); } /// <resumé> /// Sekventiel søgning efter en medarbejder ved navn. /// </summary> /// <param name="name">Medarbejdernavn.</param> /// <param name="offset">Position at begynde at søge fra.</param> // / < returns>Medarbejderindeks.</returns> public int GetIndexOfEmployeeByName ( strengnavn , int offset = 0 ) { for ( int i = offset ; i < ansatte . Antal ; i ++ ) { if ( ansatte [ i ] . Navn == navn ) { return i ; } } retur - 1 ; } } klasse Program { static void Main ( string [] args ) { //Opret en liste over medarbejdere og tilføj poster til den EmployeesList empList = new EmployeesList (); empList . Tilføj ( ny medarbejder ( "Shlensky Dmitry" , "webstudie " )); empList . Tilføj ( ny medarbejder ( "Kusy Nazar" , "webstudie " )); empList . Tilføj ( ny medarbejder ( "Magpie Orest" , "webstudie" )); //Søg efter medarbejder Kusyi Nazar og vis resultatet, når du søger fra begyndelsen og fra 2. positionskonsollen . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); Konsol . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()); //Søg og slet medarbejder Soroka Orestes empList . Fjern ( empList [ empList . GetIndexOfEmployeeByName ( "Magpie Orestes" )]); } } } Kildetekst i C# 2 bruger System ; ved hjælp af System.Collections.Generic ; ved hjælp af System.Linq ; ved hjælp af System.Text ; navneområde Medarbejdere { /// <resumé> /// Klasse til lagring af medarbejderdata. /// </summary> class Employee { private string name ; privat strengeafdeling ; _ offentlig Medarbejder ( strengnavn , strengafdeling ) { dette . _ _ navn = navn ; dette . afdeling = afdeling ; } /// <resumé> /// Medarbejdernavn. /// </summary> offentlig streng Navn { get { return this . navn ; } } /// <resumé> /// Arbejdsafdeling. /// </summary> public string Department { get { return this . afdeling ; } } } /// <resumé> /// Klasse til lagring af en liste over medarbejdere. /// </summary> class EmployeesList { private List < Employee > employee = new List < Employee >(); /// <resumé> /// Ejendom til at få og skrive en medarbejder efter indeks. /// </summary> /// <param name="index">Medarbejderindeks.</param> /// <returns>Medarbejder.</returns> public Employee this [ int index ] { get { return medarbejdere [ indeks ]; } sæt { medarbejdere [ indeks ] = værdi ; } } /// <resumé> /// Ejendom til at få og skrive en medarbejder ved navn. /// </summary> /// <param name="name">Medarbejdernavn.</param> /// <returns>Den første medarbejder, hvis navn matchede eller null</returns> offentlige Medarbejder denne [ strengnavn ] { get { foreach ( Medarbejder vare i medarbejdere ) { if ( item . Navn == navn ) returnere vare ; } returner null ; } } /// <resumé> /// Tilføjelse af en ny medarbejder. /// </summary> /// <param name="employee">Ny medarbejder.</param> public void Tilføj ( Medarbejder medarbejder ) { medarbejdere . Tilføj ( medarbejder ); } /// <resumé> /// Sletning af en eksisterende medarbejder. /// </summary> /// <param name="employee">Medarbejderen, der skal fjernes.</param> public void Fjern ( Medarbejder medarbejder ) { ansatte . Fjern ( medarbejder ); } /// <resumé> /// Sekventiel søgning efter en medarbejder ved navn. /// </summary> /// <param name="name">Medarbejdernavn.</param> /// <param name="offset">Position at begynde at søge fra.</param> // / < returns>Medarbejderindeks.</returns> public int GetIndexOfEmployeeByName ( string name , int offset ) { int index = - 1 ; for ( int i = offset ; i < ansatte . Antal ; i ++) { if ( ansatte [ i ]. Navn == navn ) { index = i ; bryde ; } } returner indeks ; } /// <resumé> /// Sekventiel søgning efter en medarbejder ved navn. /// </summary> /// <param name ="name">Medarbejdernavn.</param> /// <returns>Medarbejderindeks.</returns> public int GetIndexOfEmployeeByName ( strengnavn ) { return GetIndexOfEmployeeByName ( navn 0 ) ; } } klasse Program { static void Main ( string [] args ) { //Opret en liste over medarbejdere og tilføj poster til den EmployeesList empList = new EmployeesList (); empList . Tilføj ( ny medarbejder ( "Shlensky Dmitry" , "webstudie " )); empList . Tilføj ( ny medarbejder ( "Kusy Nazar" , "webstudie " )); empList . Tilføj ( ny medarbejder ( "Magpie Orest" , "webstudie" )); //Søg efter medarbejder Kusyi Nazar og vis resultatet, når du søger fra begyndelsen og fra 2. positionskonsollen . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); Konsol . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()); //Søg og slet medarbejder Soroka Orestes empList . Remove ( empList [ "Magpie Orestes" ]); } } }

Objective-C 2.0

Et simpelt eksempel Objective-C kildekode enum { GLEngineChangeView }; @interface GLEngine  : NSObject { id _delegate ; BOOL_event [ NUM ] ; } - ( id ) delegeret ; - ( void ) setDelegate: ( id ) delegate ; - ( void ) changeView: ( GLView * ) view ; @ende @protocol GLEngineDelegate < NSObject > @valgfri - ( BOOL ) motor : ( GLEngine * ) motor changeView : ( GLView * ) view ; @ende @interface GLEngine (intern) - ( ugyldig ) registerDelegate ; @ende @implementationGLEngine _ - ( id ) delegeret { returnere _delegate ; } - ( void ) setDelegate: ( id ) delegate { _delegate = delegeret ; [ selv registrer Delegat ]; } - ( void ) changeView: ( GLView * ) view { if ( _event [ GLEngineChangeView ]) { // delegeret anmodning if ([ _delegate engine : self changeView : view ]) { // brug modificeret visning } andet // anmodning blev ikke behandlet } // eller brug standardmåden } - ( ugyldig ) registerDelegate { if ([ _delegate responseToSelector : @selector ( motor : changeView :)]) { _event [ GLEngineChangeView ] = JA ; } } @ende @interface MyGLEngineDelegate  : NSObject < GLEngineDelegate > { // } @ende @implementationMyGLEngineDelegate _ - ( BOOL ) motor: ( Engine * ) Engine changeView: ( GLView * ) view { // skift visning } @ende

ObjectPascal

Et simpelt eksempel Kildetekst i Object Pascal type IDelegateInterface = grænsefladeprocedure Metode1 ; _ procedure Metode2 ; ende ; TClassA = klasse ( TInterfacedObject , IDelegateInterface ) offentlig procedure Metode1 ; procedure Metode2 ; ende ; TClassB = klasse ( TInterfacedObject , IDelegateInterface ) offentlig procedure Metode1 ; procedure Metode2 ; ende ; TClassDel = klasse ( TInterfacedObject , IDelegateInterface ) privat FInterface : IDelegateInterface ; offentlig procedure Metode1 ; procedure Metode2 ; procedure ToClassA ; procedure ToClassB ; ende ; implementering {TClassA} procedure TClassA . metode1 ; start Writeln ( 'TClassA.Method1' ) ; ende ; procedure TClassA . metode2 ; start Writeln ( 'TClassA.Method2' ) ; ende ; {TClassB} procedure TClassB . metode1 ; start Writeln ( 'TClassB.Method1' ) ; ende ; procedure TClassB . metode2 ; start Writeln ( 'TClassB.Method2' ) ; ende ; {TClassDel} procedure TClassDel . metode1 ; start FInterface . metode1 ; ende ; procedure TClassDel . metode2 ; start FInterface . metode2 ; ende ; procedure TClassDel . ToClassA ; start FInterface := TClassA . skabe ; ende ; procedure TClassDel . ToClassB ; start FGrænseflade := TKlasseB . skabe ; ende ; Ikke-trivielt eksempel

Dette eksempel er en Object Pascal -version af det ikke-trivielle eksempel ovenfor.

Kildetekst i Object Pascal enhed UnitEmployers ; interface bruger Contnrs ; type // Klasse til lagring af medarbejderdata TEmployee = klasse privat FName : string ; FAfdeling : streng ; offentlig konstruktør Opret ( navn , afdeling : streng ) ; publiceret egenskab Navn : streng læst FName ; egenskab Departament : streng læst FDepartament ; ende ; // Klasse til lagring af listen over medarbejdere TEmployeersList = klasse privat // Objekt af "list of objects" -klassen FEmployeersList : TObjectList ; funktion GetEmployee ( Indeks : Heltal ) : TEmployee ; procedure SetEmployee ( Indeks : Heltal ; const Værdi : TEmployee ) ; offentlig konstruktør Opret ; destructor Destroy ; tilsidesætte ; funktion Tilføj ( Medarbejder : TEmployee ) : Heltal ; procedure Fjern ( medarbejder : TEmployee ) ; function IndexEmployeeByName ( Navn : streng ; Offset : Heltal = 0 ) : Heltal ; ejendom Medarbejdere [ Indeks : Heltal ] : TEmployee læser GetEmployee skriv SetEmployee ; standard ; ende ; implementering {medarbejder} konstruktør TE-medarbejder . Opret ( navn , afdeling : streng ) ; start FName := Navn ; FDepartament := Afdeling ; ende ; { Temployeers List } konstruktør TEmployeersList . skabe ; start // Opret et objekt, hvis metoder vi vil uddelegere FEmployeersList := TObjectList . skabe ; ende ; destructor TEmployeersList . Ødelæg ; start FEemployersList . Gratis ; nedarvet ; ende ; funktion Vikarliste . GetEmployee ( indeks : heltal ) : TEmployee ; start Resultat := FEmployeersList [ Indeks ] som TEmployee ; ende ; procedure TEmployeersList . SetEmployee ( Indeks : Heltal ; const Værdi : TEmployee ) ; start FEmployeersList [ Indeks ] := Værdi ; ende ; funktion Vikarliste . IndexEmployeeByName ( Navn : streng ; Offset : Heltal = 0 ) : Heltal ; // Sekventiel søgning efter en medarbejder ved navn // Gennem argumentet Offset kan du indstille den position, hvorfra der skal søges. // Hvis medarbejderen ikke findes, vil den returnere en værdi mindre end nul (-1) var Index : Integer ; begynde Resultat := - 1 ; // Forudsat at det ikke er på listen for Index := FEmployeersList . Tæl 1 ned til Offset gør hvis ( FEmployeersList [ Indeks ] som TEmployee ) . Navn = Navn og derefter begynde Resultat := Indeks ; udgang ; ende ; ende ; funktion Vikarliste . Tilføj ( medarbejder : TEmployee ) : Heltal ; start Resultat := FEemployeersList . Tilføj ( medarbejder ) ; ende ; procedure TEmployeersList . Fjern ( medarbejder : TEmployee ) ; start FEemployersList . Fjern ( medarbejder ) ; ende ; ende .

Desværre er det ikke alle programmører, der bruger delegationsmønsteret. For eksempel arvede Borland (udvikleren af ​​Delphi - programmeringsmiljøet ) i dets standardklassebibliotek den førnævnte TObjectList-objektlisteklasse fra TList - markørlisteklassen . Dette forårsagede utilfredshed blandt nogle erfarne programmører.

PHP5

Et simpelt eksempel

Dette eksempel er en PHP- version af det simple Java- eksempel ovenfor.

PHP5 kildekode <?php klasse A { public function f () { print "A: Kald metoden f()<br />" ; } public function g () { print "A: Vi kalder metoden g()<br />" ; } } klasse C { privat $_a ; offentlig funktion __construct () { $this -> _a = nyt A ; } offentlig funktion f () { $this -> _a -> f (); } offentlig funktion g () { $this -> _a -> g (); } public function y () { print "C: kalde metode y()<br />" ; } } $obj = nyt C ; $obj -> f (); $obj -> g (); $obj -> y (); ?> Kompleks eksempel

Dette eksempel er en PHP- version af det komplekse Java- eksempel ovenfor.

PHP5 kildekode <?php // brug grænseflade til type sikkerhedsgrænseflade I { offentlig funktion f ( ); offentlig funktion g (); } klasse A implementerer I { public function f () { print "A: Kald f()<br />" ; } public function g () { print "A: Vi kalder metoden g()<br />" ; } } klasse B implementerer I { public function f () { print "B: Kald f()<br />" ; } public function g () { print "B: Kaldmetode g()<br />" ; } } klasse C implementerer I { private $_i ; // opret et objekt, hvis metoder vil blive uddelegeret offentlig funktion __construct () { $this -> _i = new A ; } // med disse metoder ændrer vi feltobjektet , hvis metoder vi vil delegere offentlig funktion til A () { $this -> _i = new A ; } public function toB () { $this -> _i = new B ; } // delegerede metoder offentlig funktion f () { $this -> _i -> f (); } offentlig funktion g () { $this -> _i -> g (); } } $obj = nyt C ; $obj -> f (); $obj -> g (); $obj -> toB (); $obj -> f (); $obj -> g (); ?> Ikke-trivielt eksempel

Dette eksempel er en PHP -version af det ikke-trivielle eksempel ovenfor.

PHP5 kildekode <?php // klasse til lagring af medarbejderdata klasse Medarbejder { privat $_name ; privat $_afdeling ; offentlig funktion __construct ( $navn , $afdeling ) { $this -> _name = $navn ; $this -> _departament = $departament ; } public function getName () { return $this -> _name ; } public function getDepartament () { return $this -> _departament ; } } // klasse til lagring af en liste over objekter klasse ObjectList { privat $_objList ; public function __construct () { $this -> free (); } /** *ikke at kede sig! */ public function free () { $this -> _objList = array (); } public function count () { return count ( $this -> _objList ); } public function add ( $obj ) { array_push ( $this -> _objList , $obj ); } public function remove ( $obj ) { $k = array_search ( $obj , $this -> _objList , true ); if ( $k !== false ) { unset ( $this -> _objList [ $k ] ); } } public function get ( $index ) { return $this -> _objList [ $index ]; } offentlig funktionssæt ( $index , $obj ) { $ this - > _objList [ $index ] = $obj ; } } // klasse til opbevaring af medarbejdere klasse EmployeeList { // objekt i klassen "liste over objekter" privat $_employeersList ; public function __construct (){ // opret et objekt, hvis metoder vi vil uddelegere $this -> _employeersList = new ObjectList ; } public function getEmployer ( $index ) { return $this -> _employeersList -> get ( $index ); } public function setEmployer ( $index , Employee $objEmployer ) { $this -> _employeersList -> set ( $index , $objEmployer ); } offentlig funktion __destruct () { $this -> _employeersList -> gratis (); } public function add ( Medarbejder $objEmployer ) { $this -> _employeersList -> add ( $objEmployer ); } public function remove ( Medarbejder $objEmployer ) { $this -> _employeersList -> remove ( $objEmployer ); } // sekventiel søgning efter en medarbejder ved navn // gennem $offset-argumentet kan du indstille den position, hvorfra der skal søges. // hvis medarbejderen ikke findes, vil den returnere en værdi mindre end nul (-1) public function getIndexByName ( $navn , $offset = 0 ) { $result = - 1 ; // antag at det ikke er på listen $cnt = $this -> _employeersList -> count (); for ( $i = $offset ; $i < $cnt ; $i ++ ) { if ( ! strcmp ( $navn , $this -> _employeersList -> get ( $i ) -> getName () ) ) { $result = $i ; bryde ; } } returner $resultat ; } } $obj1 = ny medarbejder ( "Tanasiychuk Stepan" , "webstudie " ); $obj2 = ny medarbejder ( "Kusy Nazar" , "webstudie " ); $obj3 = ny medarbejder ( "Magpie Orest" , "webstudie" ); $objList = ny medarbejderliste (); $objList -> tilføje ( $obj1 ); $objList -> tilføje ( $obj2 ); $objList -> tilføje ( $obj3 ); echo "<præ>" ; print_r ( $objList ); echo "<hr>" ; $index = $objList -> getIndexByName ( "Kusy Nazar" ); $obj4 = $objList -> getEmployer ( $indeks ); print_r ( $obj4 ); echo "<hr>" ; $objList -> setEmployer ( 2 , $obj4 ); print_r ( $objList ); echo "</pre>" ; ?>

Python

Et simpelt eksempel

Kildekode i Python

#coding: utf-8 #python 3 klasse A : def f ( self ): print ( 'A : kalder metode f' ) def g ( self ): print ( 'A : kalder metode g' ) klasse C : def __init__ ( selv ): selv . A = A () def f ( selv ): returnere selv . A. _ f () def g ( selv ): returnere selv . A. _ g () c = C () c . f () #A: kaldemetode f c . g () #A: kaldemetode g

JavaScript

Et simpelt eksempel JavaScript kildekode funktion A () { denne . f = funktion () { advarsel ( "A: kalder f()-metoden" ); }; dette . g = funktion () { advarsel ( "A: opkaldsmetode g()" ); }; } funktion C () { var a = nyt A (); dette . f = funktion () { a . f (); }; dette . g = funktion () { a . g (); }; } var c = nyt C (); c . f (); // "A: kalder f()-metoden" c . g (); // "A: Kald g()-metoden" Kompleks eksempel JavaScript kildekode funktion A () { denne . f = funktion () { advarsel ( "A: kalder f()-metoden" ); }; dette . g = funktion () { advarsel ( "A: opkaldsmetode g()" ); }; } funktion B () { denne . f = funktion () { advarsel ( "B: kald metode f()" ); }; dette . g = funktion () { advarsel ( "B: kald metode g()" ); }; } funktion C () { // instansierer A og B én gang var a = nyt A (); varb = ny B ( ); var cur = a ; // reference til det aktuelle objekt med implementering af metoder; standard - A dette . toA = funktion () { cur = a ; }; dette . toB = funktion () { cur = b ; }; dette . f = funktion () { cur . f (); }; dette . g = funktion () { cur . g (); }; } var c = nyt C (); c . f (); // "A: kalder f()-metoden" c . g (); // "A: kalder g()-metoden" c . toB (); c . f (); // "B: kalder f()-metoden" c . g (); // "B: kalder g()-metoden" Ikke-trivielt eksempel JavaScript kildekode funktion Medarbejder ( navn , afdeling ) { denne . getName = function () { return name ; }; dette . getDepartament = function () { return departament ; }; dette . toString = function () { // konverter til streng for nem fejlfinding returner "Medarbejder " + navn + ", " + afdeling ; }; } function EmployeesList () { var ansatte = []; dette . add = function () { // function tager et vilkårligt antal argumenter for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) { if ( arguments [ i ]. constructor == Medarbejder ) { medarbejdere . push ( argumenter [ i ]); } } }; dette . set = function ( obj , index ) { // type check if ( obj . constructor == Medarbejder ) { delete medarbejdere [ indeks ]; ansatte [ indeks ] = obj ; } }; dette . remove = function ( obj ) { for ( var i = 0 , l = ansatte . længde ; i < l ; i ++ ) { if ( ansatte [ i ] == obj ) { ansatte . splejsning ( i , 1 ); i- ; _ l - ; } } }; dette . getByIndex = funktion ( antal ) { returner medarbejdere [ antal ]; }; dette . getIndexByName = function ( navn , offset ) { // sekventiel søgning efter en medarbejder ved navn // gennem offset-argumentet kan du indstille den position, hvorfra der skal søges. (standard 0) // hvis medarbejder ikke findes, returner -1 for ( var i = offset || 0 , l = ansatte . længde ; i < l ; i ++ ) { if ( medarbejdere [ i ]. getName () = = navn ) returner i ; } retur - 1 ; }; dette . toString = function () { // konverter til streng for nem fejlfinding var ret = "" ; for ( var i = 0 , l = ansatte . længde ; i < l ; i ++ ) { ret += i + ": " + ansatte [ i ] + "\n" ; } returnere ret ; }; } var o1 = ny medarbejder ( "Tanasiychuk Stepan" , "webstudie " ); var o2 = ny medarbejder ( "Kusy Nazar" , "webstudie " ); var o3 = ny medarbejder ( "Magpie Orest" , "webstudie" ); var emps = new EmployeesList (); emps . tilsæt ( o1 , o2 , o3 ); // du kan tilføje en advarsel ( emps ); // "0: Medarbejder Tanasiychuk Stepan, webstudie // 1: Medarbejder Kusyi Nazar, webstudie // 2: Medarbejder Soroka Orest, webstudie" var obj4 = emps . getByIndex ( emps . getIndexByName ( "Kusy Nazar" ) ); // få et link til medarbejderadvarslen ( obj4 ) ; // "Medarbejder Kusyi Nazar, webstudie" emps . sæt ( obj4 , 2 ); // i stedet for den 2. (fra nul) medarbejder, indsæt obj4- advarsel ( emps ); // "0: Medarbejder Tanasiychuk Stepan, webstudie // 1: Medarbejder Kusyi Nazar, webstudie // 2: Medarbejder Kusyi Nazar, webstudie" emps . fjerne ( obj4 ); // fjern medarbejder obj4 alert ( emps ); // "0: Medarbejder Tanasiychuk Stepan, webstudie"

VB.NET

Kompleks eksempel Kildekode i VB.NET Navnerumsmønstre _ Interface I Sub f () Sub g () End Interface Klasse A - redskaber I Offentlige under f () Implementer I . f System . Konsol . WriteLine ( "A: kalder f()-metoden" ) End Sub Offentlig under g () Implementerer I . g System . Konsol . WriteLine ( "A: kalder g()-metoden" ) End Sub End Class Klasse B redskaber I Offentlige under f () Implementer I . f System . Konsol . WriteLine ( "B: kalder f()-metoden" ) End Sub Offentlig under g () Implementerer I . g System . Konsol . WriteLine ( "B: kalder g()-metoden" ) End Sub End Class Klasse C redskaber I ' Opret et objekt, hvis metoder vi vil uddelegere Private i As I = New A () Offentlige under f () Implementer i . fi . _ f () End Sub Offentlige under g () Implementerer i . g i . g () End Sub ' Med disse metoder ændrer vi feltobjektet, hvis metoder vi vil delegere Public Sub tilA () i = New A () End Sub Public Sub toB () i = New B () End Sub End Class Klassedelegatmønster _ Shared Sub Main () Dim c Som ny C () c . f () c . g () c . tilB () c . f () c . g () System . Konsol . ReadKey () End Sub End Class End Namespace Ikke-trivielt eksempel Kildekode i VB.NET Importer System.Collections.Generisk Import System.Linq Importer System.Text Namespace Employees ''' <resumé> ''' Klasse til lagring af medarbejderdata. ''' </summary> Klasse Medarbejder Privat m_navn Som streng Privat m_afdeling Som streng Public Sub New ( ByVal name As String , ByVal departament As String ) Me . m_name = navngiv mig . m_department = afdeling End Sub ''' <resumé> ''' Medarbejdernavn. ''' </summary> Offentlig skrivebeskyttet ejendomsnavn ( ) Som streng Get Return Me . m_name End Get End Property ''' <resumé> ''' Arbejdsafdeling. ''' </summary> Offentlig skrivebeskyttet ejendomsafdeling ( ) Som streng Get Return Me . m_department End Hent End Property End Class ''' <resumé> ''' Klasse til lagring af en liste over medarbejdere. ''' </summary> Klasse Employees List Private medarbejdere Som Ny Liste ( Over Medarbejder )() ''' <resumé> ''' Egenskab til at få og skrive en medarbejder efter indeks. ''' </summary> ''' <param name="index">Medarbejderindeks.</param> ''' < returns >Medarbejder.</returns> Standard offentlig ejendomselement ( ByVal indeks som heltal ) Som medarbejder Hent Returner medarbejdere ( indeks ) End Get Set ( ByVal value As Employee ) medarbejdere ( indeks ) = værdi End Set End Property ''' <resumé> ''' Tilføjelse af en ny medarbejder. ''' </summary> ''' <param name="employee">Ny medarbejder.</param> Offentlig Sub Add ( ByVal- medarbejder som medarbejder ) medarbejdere . Tilføj ( medarbejder ) End Sub ''' <resumé> ''' Slet en eksisterende medarbejder. ''' </summary> ''' <param name="employee">Medarbejder der skal fjernes.</param> Offentlig underfjernelse ( ByVal - medarbejder som ansat ) medarbejdere . Fjern ( medarbejder ) End Sub ''' <resumé> ''' Sekventiel søgning efter en medarbejder ved navn. ''' </summary> ''' <param name="name">Medarbejdernavn.</param> ''' <returns>Medarbejderindeks.</returns> Offentlig funktion GetIndexOfEmployeeByName ( ByVal name As String ) As Integer Dim indeks Som heltal = - 1 For i Som heltal = 0 til medarbejdere . Tæl - 1 Hvis ansatte ( i ). Navn = navn indeks = i Afslut For Slut Hvis Næste Returner indeks Afslut Funktion ''' <resumé> ''' Sekventiel søgning efter en medarbejder ved navn. ''' </summary> ''' <param name="name">Medarbejdernavn.</param> ''' <param name="offset">Position at begynde at søge fra.</param> '' ' < returns>Medarbejderindeks.</returns> Offentlig funktion GetIndexOfEmployeeByName ( ByVal name As String , ByVal offset As Integer ) As Integer Dim index As Integer = - 1 For i Som heltal = offset Til medarbejdere . Tæl - 1 Hvis ansatte ( i ). Navn = navn indeks = i Exit For End If Next Return indeks End Funktion Slut Klasse Class Program Shared Sub Main () 'Opret en liste over medarbejdere og tilføj poster til den . Dim empList As New EmployeesList () empList . Tilføj ( ny medarbejder ( "Shlensky Dmitry" , "webstudie" )) empList . Tilføj ( Ny medarbejder ( "Kusy Nazar" , "webstudie" )) empList . Tilføj ( ny medarbejder ( "Magpie Orest" , "webstudie" ))) 'Søger efter medarbejder Kusyi Nazar og viser resultatet, når du søger fra begyndelsen og fra 2. positionskonsollen . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()) Konsol . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()) 'Søg og slet medarbejder Soroka Orestes empList . Fjern ( empList ( empList . GetIndexOfEmployeeByName ( "Magpie Orestes" ))) Console . Læs () End Sub End Class End Namespace

Se også

Noter

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

Litteratur

  • Julian Bucknell "Fundamentelle algoritmer og datastrukturer i Delphi". Ed. Diasoft 2003
  • Grand M. Designmønstre i Java. 2004
  • Bruce Eckel "Java Philosophy". Ed. "Peter" 2016