Model de delegare

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 15 ianuarie 2015; verificările necesită 14 modificări .
Delegație
delegație
Descris în Design Patterns Nu

Delegarea este un  model de proiectare de bază în care un obiect exprimă în exterior un anumit comportament , dar în realitate transferă responsabilitatea de a efectua acest comportament unui obiect înrudit. Modelul de delegare este abstractizarea fundamentală pe baza căreia sunt implementate celelalte modele - compoziție (numită și agregare), mixuri și aspecte .

Pro

Abilitatea de a schimba comportamentul unei anumite instanțe a unui obiect în loc de a crea o nouă clasă prin moștenire.

Contra

În general, acest tipar face dificilă optimizarea vitezei în favoarea purității abstracției îmbunătățite.

Aplicabilitate

Java

Deși delegarea nu este acceptată de limbajul Java, este suportată de multe medii de dezvoltare [1] .

Exemple

Java

Un exemplu simplu

În acest exemplu Java , clasa Bare o metodă stub care transmite metode către . Clasa pretinde că are atribute de clasă . foo()bar()ABA

Text sursă în java clasa A { void foo () { Sistem . afară . println ( "A: metoda foo() numită" ); } void bar () { System . afară . println ( "A: metoda bar() numită" ); } } class B { // Creați un obiect ale cărui metode vor delega comportamentul. A a = nou A (); void foo () { a . foo (); } void bar () { a . bar (); } } public class Main { public static void main ( String [] args ) { B b = new B (); b . foo (); b . bar (); } } Exemplu complex

Folosind interfețe , delegarea se poate face într-un mod mai flexibil și mai sigur de tip . În acest exemplu, clasa Cpoate delega Afie către B. Clasa Care metode de comutare între clase Ași B. Includerea extensiei de implementare îmbunătățește siguranța tipului, deoarece fiecare clasă trebuie să implementeze metodele din interfață. Principalul dezavantaj este mai mult cod.

Să luăm un exemplu. Să presupunem că trebuie să implementați un cronometru în așa fel încât o anumită funcție să fie apelată după o anumită perioadă de timp. Programatorul temporizatorului dorește să ofere o atribuire de funcție utilizatorilor clasei sale (alți programatori).

Text sursă în java /** * Interfața descrie acțiunea care va fi apelată când apare evenimentul * timer. */ interfață TimerAction { void onTime (); } clasa WakeUpAction implementează TimerAction { @Override public void onTime () { System . afară . println ( "E timpul să te trezești!" ); } } clasa ChickenIsReadyAction implementează TimerAction { @Override public void onTime () { System . afară . println ( "Puiul este gata!" ); } } /** * Clasa de cronometru. În anumite condiții, TimerAction este apelat. */ class Timer { TimerAction action ; /** * O funcție pe care programatorul o apelează pentru a seta ora. */ void run () { if ( isTime ()) { action . onTime (); } } /** * O anumită funcție care are grijă de lucrul permanent. Implementarea sa * nu este interesantă în acest context. * * @return */ private boolean isTime () { return true ; } public static void main ( String [] args ) { Sistem . afară . println ( "Introduceți tipul de acțiune:" ); Scanner scanner = scaner nou ( System . in ); String actionType = scaner . nextLine (); Timer timer = timer nou (); if ( actionType . equalsIgnoreCase ( „setează cronometrul de trezire” )) { timer . action = new WakeUpAction (); } else if ( actionType . equalsIgnoreCase ( „setează cronometrul de pui” )) { timer . action = new ChickenIsReadyAction (); } cronometru . alerga (); }

C++

Exemplu complex

Acest exemplu este o versiune C++ a exemplului Java complex de mai sus. Deoarece C++ nu are un construct de interfață, clasa complet abstractă joacă același rol . Avantajele și dezavantajele sunt practic aceleași ca în exemplul Java.

Text sursă în c++ #include <iostream> clasa I { public : vid virtual f () = 0 ; gol virtual g () = 0 ; }; clasa A : public I { public : void f () { std :: cout << "A: apelarea metodei f()" << std :: endl ; } void g () { std :: cout << "A: apel metoda g()" << std :: endl ; } }; clasa B : public I { public : void f () { std :: cout << "B: apel metoda f()" << std :: endl ; } void g () { std :: cout << "B: apel metoda g()" << std :: endl ; } }; clasa C : public I { public : // Constructor C () : m_i ( nou A () ) { } // Destructor virtual ~ C () { șterge m_i ; } void f () { m_i -> f (); } void g () { m_i -> g (); } // Cu aceste metode schimbam obiectul-camp, ale carui metode le vom delega void lui A () { șterge m_i ; m_i = nouA ( ); } void toB () { șterge m_i ; m_i = nou B (); } privat : // Declaram un obiect ale carui metode le vom delega I * m_i ; }; int main () { C c ; c . f (); c . g (); c . toB (); c . f (); c . g (); returnează 0 ; } /* Ieșire: A: apelați metoda f() A: apelați metoda g() B: apelați metoda f() B: apelați metoda g() */

C#

Text sursă în C# namespace Patterns { interfață I { void f (); voidg ( ); } clasa A : I { public void f () { System . Consola . WriteLine ( "A: apelarea metodei f()" ); } public void g () { Sistem . Consola . WriteLine ( "A: apelarea metodei g()" ); } } clasa B : I { public void f () { System . Consola . WriteLine ( "B: apelarea metodei f()" ); } public void g () { Sistem . Consola . WriteLine ( "B: apelarea g()" ); } } clasa C : I { // Creați un obiect ale cărui metode le vom delega I i = new A (); public void f () { i . f (); } public void g () { i . g (); } // Cu aceste metode schimbăm câmpul-obiect, ale cărui metode le vom delega public void lui A () { i = new A (); } public void toB () { i = new B (); } } class DelegatePattern { static void Main ( string [] args ) { C c = new C (); c . f (); c . g (); c . toB (); c . f (); c . g (); Sistem . Consola . ReadKey (); } } } Exemplu non-trivial

Acesta este un exemplu de caz des întâlnit în practică. Există o sarcină de a crea o clasă pentru stocarea listei de angajați. Datele fiecărui angajat sunt stocate într-un obiect din clasa Employee. Există o clasă gata făcută și standard pentru stocarea unei liste de obiecte Employee. A implementat deja mecanisme de lucru cu lista (de exemplu, alocarea memoriei, adăugarea și eliminarea din listă). Moștenirea clasei liste de angajați din clasa listă de obiecte nu este acceptabilă aici, deoarece vom obține toate metodele (chiar și cele care nu ne interesează). În plus, va trebui să efectuăm turnarea tip în unele cazuri. Cea mai elegantă cale de ieșire din acest caz este de a delega unele dintre metodele clasei listă de obiecte către clasa listă de angajați. În regulile POO, cel mai bine este să reprezentați lista de obiecte cu o metodă privată (privată) a listei de angajați. În acest caz, lista poate fi accesată printr-un indexator.

Text sursă în C# folosind System ; folosind System.Collections.Generic ; folosind System.Linq ; folosind System.Text ; namespace Angajații { /// <rezumat> /// Clasă pentru stocarea datelor angajaților. /// </summary> class Employee { private string name ; departament privat string ; Angajat public ( nume șir , departament șir ) { this . nume = nume ; aceasta . departament = departament ; } /// <rezumat> /// Numele angajatului. /// </summary> șir public Nume { get { return this . nume ; } } /// <rezumat> /// Departamentul de lucru. /// </summary> public șir Departament { get { return this . departament ; } } } /// <rezumat> /// Clasă pentru stocarea unei liste de angajați. /// </summary> class EmployeesList { private List < Employee > employees = new List < Employee >(); /// <rezumat> /// Proprietate pentru obținerea și scrierea unui angajat după index. /// </summary> /// <param name="index">Indexul angajaților.</param> /// <returns>Angajat.</returns> public Angajat this [ int index ] { get { return employees [ index ]; } set { angajati [ index ] = valoare ; } } /// <rezumat> /// Adăugarea unui nou angajat. /// </summary> /// <param name="employee">Angajat nou.</param> public void Adaugă ( Angajat angajat ) { angajați . Adaugă ( angajat ); } /// <rezumat> /// Ștergerea unui angajat existent. /// </summary> /// <param name="employee">Angajatul de eliminat.</param> public void Remove ( Angajat angajat ) { angajați . Eliminați ( angajat ); } /// <rezumat> /// Căutare secvenţială a unui angajat după nume. /// </summary> /// <param name="name">Numele angajatului.</param> /// <param name="offset">Poziție din care începeți căutarea.</param> // / < returnează>Indexul angajaților.</returns> public int GetIndexOfEmployeeByName ( nume șir , int offset = 0 ) { for ( int i = offset ; i < angajați . Număr ; i ++) { if ( angajați [ i ]. Nume == nume ) { return i ; } } return - 1 ; } } class Program { static void Main ( string [] args ) { //Creează o listă de angajați și adaugă intrări la ea EmployeesList empList = new EmployeesList (); empList . Adăugați ( angajat nou ( "Shlensky Dmitry" , "studio web" )); empList . Adăugați ( angajat nou ( „Kusy Nazar” , „studio web” )); empList . Adăugați ( angajat nou ( „Magpie Orest” , „studio web” )); //Căutați angajatul Kusyi Nazar și afișați rezultatul când căutați de la început și din poziția a 2-a Consolă . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); Consola . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()); //Căutați și ștergeți angajatul Soroka Orestes empList . Eliminați ( empList [ empList . GetIndexOfEmployeeByName ( „Magpie Orestes” )]); } } } Text sursă în C# 2 folosind System ; folosind System.Collections.Generic ; folosind System.Linq ; folosind System.Text ; namespace Angajații { /// <rezumat> /// Clasă pentru stocarea datelor angajaților. /// </summary> class Employee { private string name ; departament privat string ; Angajat public ( nume șir , departament șir ) { this . nume = nume ; aceasta . departament = departament ; } /// <rezumat> /// Numele angajatului. /// </summary> șir public Nume { get { return this . nume ; } } /// <rezumat> /// Departamentul de lucru. /// </summary> public șir Departament { get { return this . departament ; } } } /// <rezumat> /// Clasă pentru stocarea unei liste de angajați. /// </summary> class EmployeesList { private List < Employee > employees = new List < Employee >(); /// <rezumat> /// Proprietate pentru obținerea și scrierea unui angajat după index. /// </summary> /// <param name="index">Indexul angajaților.</param> /// <returns>Angajat.</returns> public Angajat this [ int index ] { get { return employees [ index ]; } set { angajati [ index ] = valoare ; } } /// <rezumat> /// Proprietate pentru obținerea și scrierea unui angajat după nume. /// </summary> /// <param name="name">Numele angajatului.</param> /// <returns>Primul angajat al cărui nume se potrivește sau nul</returns> public Angajat acest [ string name ] { get { foreach ( element de angajat în angajați ) { if ( item . Nume == nume ) return item ; } return null ; } } /// <rezumat> /// Adăugarea unui nou angajat. /// </summary> /// <param name="employee">Angajat nou.</param> public void Adaugă ( Angajat angajat ) { angajați . Adaugă ( angajat ); } /// <rezumat> /// Ștergerea unui angajat existent. /// </summary> /// <param name="employee">Angajatul de eliminat.</param> public void Remove ( Angajat angajat ) { angajați . Eliminați ( angajat ); } /// <rezumat> /// Căutare secvenţială a unui angajat după nume. /// </summary> /// <param name="name">Numele angajatului.</param> /// <param name="offset">Poziție din care începeți căutarea.</param> // / < returnează>Indexul angajaților.</returns> public int GetIndexOfEmployeeByName ( nume șir , int offset ) { int index = - 1 ; for ( int i = offset ; i < angajați . Număr ; i ++) { if ( angajați [ i ]. Nume == nume ) { index = i ; rupe ; } } return index ; } /// <rezumat> /// Căutare secvenţială a unui angajat după nume. /// </summary> /// <param name="name">Numele angajatului.</param> /// <returns>Indexul angajaților.</returns> public int GetIndexOfEmployeeByName ( string name ) { return GetIndexOfEmployeeByName ( nume , 0 ); } } class Program { static void Main ( string [] args ) { //Creează o listă de angajați și adaugă intrări la ea EmployeesList empList = new EmployeesList (); empList . Adăugați ( angajat nou ( "Shlensky Dmitry" , "studio web" )); empList . Adăugați ( angajat nou ( „Kusy Nazar” , „studio web” )); empList . Adăugați ( angajat nou ( „Magpie Orest” , „studio web” )); //Căutați angajatul Kusyi Nazar și afișați rezultatul când căutați de la început și din poziția a 2-a Consolă . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); Consola . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()); //Căutați și ștergeți angajatul Soroka Orestes empList . Remove ( empList [ "Magpie Orestes" ]); } } }

Objective-C 2.0

Un exemplu simplu Cod sursă Objective-C enumerare { GLEngineChangeView }; @interface GLEngine  : NSObject { id _delegat ; BOOL_eveniment [ NUM ] ; } - ( id ) delegat ; - ( void ) setDelegate: ( id ) delegat ; - ( void ) changeView: ( GLView * ) vizualizare ; @Sfârşit @protocol GLEngineDelegate < NSObject > @optional - ( BOOL ) motor : ( GLEngine * ) schimbare motorView : ( GLView * ) vizualizare ; @Sfârşit @interfață GLEngine ( internă) - ( nul ) registerDelegate ; @Sfârşit @implementationGLEngine _ - ( id ) delegat { return _delegat ; } - ( void ) setDelegate: ( id ) delegat { _delegat = delegat ; [ self registerDelegate ]; } - ( void ) changeView: ( GLView * ) vizualizare { if ( _event [ GLEngineChangeView ]) { // cere delegat dacă ([ _delegate engine : self changeView : view ]) { // folosiți vizualizarea modificată } altfel // cererea nu a fost procesată } // sau folosiți modul standard } - ( void ) registerDelegate { if ([ _delegate responseToSelector : @selector ( motor : changeView :)]) { _event [ GLEngineChangeView ] = DA ; } } @Sfârşit @interface MyGLEngineDelegate  : NSObject < GLEngineDelegate > { // } @Sfârşit @implementationMyGLEngineDelegate _ - ( BOOL ) motor: ( Motor * ) schimbare motorView : ( GLView * ) vizualizare { // schimba vizualizarea } @Sfârşit

ObjectPascal

Un exemplu simplu Textul sursă în Object Pascal tip IDelegateInterface = procedura de interfata Metoda1 ; procedura Metoda2 ; sfârşitul ; TClassA = clasă ( TInterfacedObject , IDelegateInterface ) procedură publică Method1 ; procedura Metoda2 ; sfârşitul ; TClassB = clasă ( TInterfacedObject , IDelegateInterface ) procedură publică Method1 ; procedura Metoda2 ; sfârşitul ; TClassDel = clasa ( TInterfacedObject , IDelegateInterface ) private FInterface : IDelegateInterface ; procedura publică Metoda1 ; procedura Metoda2 ; procedura ToClassA ; procedura ToClassB ; sfârşitul ; implementare {TClassA} procedura TClassA . metoda 1 ; începe Writeln ( 'TClassA.Method1' ) ; sfârşitul ; procedura TClassA . metoda 2 ; începe Writeln ( 'TClassA.Method2' ) ; sfârşitul ; {TClassB} procedura TClassB . metoda 1 ; începe Writeln ( 'TClassB.Method1' ) ; sfârşitul ; procedura TClassB . metoda 2 ; începe Writeln ( 'TClassB.Method2' ) ; sfârşitul ; {TClassDel} procedura TClassDel . metoda 1 ; începe FInterface . metoda 1 ; sfârşitul ; procedura TClassDel . metoda 2 ; începe FInterface . metoda 2 ; sfârşitul ; procedura TClassDel . ToClassA ; începe FInterface := TClassA . a crea ; sfârşitul ; procedura TClassDel . ToClassB ; începe FInterface := TClassB . a crea ; sfârşitul ; Exemplu non-trivial

Acest exemplu este o versiune Object Pascal a exemplului non-trivial de mai sus.

Textul sursă în Object Pascal unitate UnitEmployers ; interfata folosește Contnrs ; tip // Clasa pentru stocarea datelor angajatului TEmployee = class private FName : string ; FDepartament : string ; constructor public Creare ( Nume , Departament : şir ) ; proprietate publicată Nume : șir de caractere citit FName ; proprietate Departament : șir citit FDepartament ; sfârşitul ; // Clasa de stocare a listei de angajați TEmployeersList = class private // Obiect al clasei „liste de obiecte” FEmployeersList : TObjectList ; function GetEmployee ( Index : Integer ) : TEmployee ; procedura SetEmployee ( Index : Integer ; const Value : TEmployee ) ; constructor public Creare ; destructor Distruge ; suprascrie ; function Add ( Angajat : TEmployee ) : Integer ; procedura Eliminare ( Angajat : TEmployee ) ; funcția IndexEmployeeByName ( Nume : șir ; Offset : Integer = 0 ) : Integer ; proprietate Angajati [ Index : Integer ] : TEmployee citeste GetEmployee scrie SetEmployee ; implicit ; sfârşitul ; implementare {angajat} constructor TEmployee . Creare ( Nume , Departament : şir ) ; începe FName := Nume ; FDepartament := Departament ; sfârşitul ; { Lista angajatilor } constructor TEmployeersList . a crea ; begin // Creați un obiect ale cărui metode le vom delega FEmployeersList := TObjectList . a crea ; sfârşitul ; destructor TEmployeersList . Distruge ; începe FEmployersList . Gratuit ; moștenit ; sfârşitul ; funcția TemployeersList . GetEmployee ( Index : Integer ) : TEmployee ; începe Rezultatul := FEmployeersList [ Index ] ca TEmployee ; sfârşitul ; procedura TEmployeersList . SetEmployee ( Index : Integer ; const Value : TEmployee ) ; începe FEmployeersList [ Index ] := Valoare ; sfârşitul ; funcția TemployeersList . IndexEmployeeByName ( Nume : șir ; Offset : Integer = 0 ) : Integer ; // Căutare secvenţială a unui angajat după nume // Prin argumentul Offset, puteţi seta poziţia din care să căutaţi. // Dacă angajatul nu este găsit, va returna o valoare mai mică decât zero (-1) var Index : Integer ; începe Rezultatul := - 1 ; // Presupunând că nu este în lista pentru Index := FEmployeersList . Numărătoarea inversă până la Offset do if ( FEmployeersList [ Index ] ca TEmployee ) . Nume = Nume apoi începe Rezultat := Index ; ieșire ; sfârşitul ; sfârşitul ; funcția TemployeersList . Adăugați ( Angajat : TEmployee ) : Întregul ; începe Rezultatul := FEmployeersList . Adaugă ( Angajat ) ; sfârşitul ; procedura TEmployeersList . Eliminare ( Angajat : TEmployee ) ; începe FEmployersList . Eliminare ( angajat ) ; sfârşitul ; sfârşitul .

Din păcate, nu toți programatorii folosesc modelul de delegare. De exemplu, Borland (dezvoltatorul mediului de programare Delphi ) în biblioteca sa standard de clasă a moștenit clasa de listă de obiecte TObjectList menționată mai sus din clasa de listă de pointer TList . Acest lucru a provocat nemulțumiri în rândul unor programatori experimentați.

PHP5

Un exemplu simplu

Acest exemplu este o versiune PHP a exemplului Java simplu de mai sus.

Cod sursă PHP5 <?php clasa A { public function f () { print "A: Apeleaza metoda f()<br />" ; } public function g () { print "A: Apelam metoda g()<br />" ; } } clasa C { privat $_a ; function public __construct () { $this -> _a = new A ; } function public f () { $this -> _a -> f (); } function public g () { $this -> _a -> g (); } public function y () { print "C: apel metoda y()<br />" ; } } $obj = nou C ; $obj -> f (); $obj -> g (); $obj -> y (); ?> Exemplu complex

Acest exemplu este o versiune PHP a exemplului Java complex de mai sus.

Cod sursă PHP5 <?php // folosește interfața pentru tipul interfață de siguranță I { public function f (); funcţie publică g (); } clasa A implementează I { public function f () { print "A: Call f()<br />" ; } public function g () { print "A: Apelam metoda g()<br />" ; } } clasa B implementează I { public function f () { print "B: Call f()<br />" ; } public function g () { print "B: Apeleaza metoda g()<br />" ; } } implementează clasa C I { private $_i ; // creăm un obiect ale cărui metode vor fi delegate public function __construct () { $this -> _i = new A ; } // cu aceste metode schimbăm câmpul-obiect, ale cărui metode le vom delega funcția publică luiA () { $this -> _i = new A ; } function public toB () { $this -> _i = new B ; } // metode delegate public function f () { $this -> _i -> f (); } function public g () { $this -> _i -> g (); } } $obj = nou C ; $obj -> f (); $obj -> g (); $obj -> toB (); $obj -> f (); $obj -> g (); ?> Exemplu non-trivial

Acest exemplu este o versiune PHP a exemplului non-trivial de mai sus.

Cod sursă PHP5 <?php // clasă pentru stocarea datelor angajaților clasa Employee { private $_name ; private $_department ; function public __construct ( $nume , $departament ) { $this -> _name = $nume ; $this -> _departament = $departament ; } public function getName () { return $this -> _name ; } public function getDepartament () { return $this -> _departament ; } } // clasa pentru stocarea unei liste de obiecte clasa ObjectList { private $_objList ; function public __construct () { $this -> free (); } /** *sa nu te plictisesti! */ 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 ] ); } } function public get ( $index ) { return $this -> _objList [ $index ]; } set de funcții publice ( $index , $obj ) { $this -> _objList [ $index ] = $obj ; } } // clasa pentru stocarea angajaților clasa EmployeeList { // obiect al clasei "lista de obiecte" private $_employeersList ; funcția publică __construct (){ // creăm un obiect ale cărui metode le vom delega $this -> _employeersList = new ObjectList ; } public function getEmployer ( $index ) { return $this -> _employeersList -> get ( $index ); } public function setAngajator ( $index , Angajat $objAngajator ) { $this -> _employeersList -> set ( $index , $objAngajator ); } public function __destruct () { $this -> _employeersList -> free (); } public function add ( Angajat $objAngajator ) { $this -> _employeersList -> add ( $objAngajator ); } public function remove ( Angajat $objAngajator ) { $this -> _employeersList -> remove ( $objAngajator ); } // căutare secvențială a unui angajat după nume // prin argumentul $offset, puteți seta poziția din care să căutați. // dacă angajatul nu este găsit, va returna o valoare mai mică decât zero (-1) funcția publică getIndexByName ( $nume , $offset = 0 ) { $rezultat = - 1 ; // presupunem că nu este în listă $cnt = $this -> _employeersList -> count (); pentru ( $i = $offset ; $i < $cnt ; $i ++ ) { if ( ! strcmp ( $nume , $acest -> _employeersList -> get ( $i ) -> getName () ) ) { $rezultat = $i ; rupe ; } } returnează $rezultat ; } } $obj1 = nou angajat ( „Tanasiychuk Stepan” , „studio web” ); $obj2 = nou angajat ( "Kusy Nazar" , "studio web" ); $obj3 = nou angajat ( "Magpie Orest" , "web studio" ); $objList = new EmployeeList (); $objList -> add ( $obj1 ); $objList -> add ( $obj2 ); $objList -> add ( $obj3 ); echo "<pre>" ; print_r ( $objList ); ecou „<hr>” ; $index = $objList -> getIndexByName ( "Kusy Nazar" ); $obj4 = $objList -> getEmployer ( $index ); print_r ( $obj4 ); ecou „<hr>” ; $objList -> setEmployer ( 2 , $obj4 ); print_r ( $objList ); ecou „</pre>” ; ?>

Python

Un exemplu simplu

Cod sursă în Python

#coding: utf-8 #python 3 clasa A : def f ( self ): print ( 'A: metoda de apelare f' ) def g ( self ): print ( 'A: metoda de apelare g' ) clasa C : def __init__ ( sine ): sine . A = A () def f ( self ): return self . A. _ f () def g ( self ): return self . A. _ g () c = C () c . f () #A: apel metoda f c . g () #A: metoda apelului g

JavaScript

Un exemplu simplu Cod sursă JavaScript function A () { this . f = function () { alert ( "A: apelarea metodei f()" ); }; aceasta . g = function () { alert ( "A: apel metoda g()" ); }; } function C () { var a = new A (); aceasta . f = function () { a . f (); }; aceasta . g = function () { a . g (); }; } var c = nou C (); c . f (); // "A: apelarea metodei f()" c . g (); // "A: apelați metoda g()" Exemplu complex Cod sursă JavaScript function A () { this . f = function () { alert ( "A: apelarea metodei f()" ); }; aceasta . g = function () { alert ( "A: apel metoda g()" ); }; } funcția B () { aceasta . f = function () { alert ( "B: apel metoda f()" ); }; aceasta . g = function () { alert ( "B: apel metoda g()" ); }; } funcția C () { // instantează A și B o dată var a = new A (); varb = nou B ( ); var cur = a ; // referire la obiectul curent cu implementarea metodelor; implicit - A aceasta . toA = function () { cur = a ; }; aceasta . toB = function () { cur = b ; }; aceasta . f = function () { cur . f (); }; aceasta . g = function () { cur . g (); }; } var c = nou C (); c . f (); // "A: apelarea metodei f()" c . g (); // "A: apelarea metodei g()" c . toB (); c . f (); // "B: apelarea metodei f()" c . g (); // "B: apelarea metodei g()" Exemplu non-trivial Cod sursă JavaScript function Angajat ( nume , departament ) { this . getName = function () { return name ; }; aceasta . getDepartament = function () { return departament ; }; aceasta . toString = function () { // converti in sir pentru depanare usoara return "Angajat" + nume + ", " + departament ; }; } function EmployeesList () { var angajati = []; aceasta . add = function () { // functia ia un numar arbitrar de argumente pentru ( var i = 0 , l = argumente . length ; i < l ; i ++ ) { if ( arguments [ i ]. constructor == Angajat ) { angajati . push ( argumente [ i ]); } } }; aceasta . set = function ( obj , index ) { // tip verifica daca ( obj . constructor == Angajat ) { delete angajati [ index ]; angajati [ index ] = obj ; } }; aceasta . elimina = function ( obj ) { for ( var i = 0 , l = angajati . lungime ; i < l ; i ++ ) { if ( angajati [ i ] == obj ) { angajati . îmbinare ( i , 1 ); eu -; _ l - ; } } }; aceasta . getByIndex = function ( num ) { return angajati [ num ]; }; aceasta . getIndexByName = function ( name , offset ) { // căutare secvențială a unui angajat după nume // prin argumentul offset, puteți seta poziția din care să căutați. (implicit 0) // dacă angajatul nu a fost găsit, returnați -1 pentru ( var i = offset || 0 , l = angajați . lungime ; i < l ; i ++ ) { dacă ( angajați [ i ]. getName () = = nume ) return i ; } return - 1 ; }; aceasta . toString = function () { // converti in sir pentru o depanare usoara var ret = "" ; pentru ( var i = 0 , l = angajați . lungime ; i < l ; i ++ ) { ret += i + ": " + angajați [ i ] + "\n" ; } return ret ; }; } var o1 = nou angajat ( „Tanasiychuk Stepan” , „studio web” ); var o2 = nou angajat ( "Kusy Nazar" , "web studio" ); var o3 = nou angajat ( "Magpie Orest" , "web studio" ); var emps = new EmployeesList (); emps . adaugă ( o1 , o2 , o3 ); // puteți adăuga una câte una alertă ( emps ); // „0: Angajat Tanasiychuk Stepan, studio web // 1: Angajat Kusyi Nazar, studio web // 2: Angajat Soroka Orest, studio web” var obj4 = emps . getByIndex ( emps . getIndexByName ( "Kusy Nazar" ) ); // obține un link către alerta angajatului ( obj4 ); // „Angajat Kusyi Nazar, studio web” emps . set ( obj4 , 2 ); // în locul celui de-al 2-lea angajat (de la zero), introduceți alertă obj4 ( emps ); // „0: Angajat Tanasiychuk Stepan, studio web // 1: Angajat Kusyi Nazar, studio web // 2: Angajat Kusyi Nazar, studio web” emps . eliminați ( obj4 ); // elimină alertă obj4 angajat ( emps ); // „0: Angajat Tanasiychuk Stepan, studio web”

VB.NET

Exemplu complex Cod sursă în VB.NET Modele de spații de nume Interfață I Sub f () Sub g () End Interfață Clasa A Instrumente I Public Sub f () Implementări I . f Sistem . Consola . WriteLine ( "A: apelarea metodei f()" ) End Sub Public Sub g () Implementări I . g Sistem . Consola . WriteLine ( "A: apelarea metodei g()" ) End Sub End Class Clasa B Implementări I Public Sub f () Implementări I . f Sistem . Consola . WriteLine ( "B: apelarea metodei f()" ) End Sub Public Sub g () Implementări I . g Sistem . Consola . WriteLine ( "B: apelarea metodei g()" ) End Sub End Class Clasa C Implementări I ' Creați un obiect ale cărui metode le vom delega Private i As I = New A () Public Sub f () Implementări i . fi _ _ f () End Sub Public Sub g () Implementări i . g i . g () End Sub ' Cu aceste metode schimbăm câmpul-obiect, ale cărui metode le vom delega Public Sub la A () i = New A () End Sub Public Sub toB () i = New B () End Sub End Class Clasa DelegatePattern Sub principal partajat () Dim c As New C () c . f () c . g () c . toB () c . f () c . g () Sistem . Consola . ReadKey () End Sub End Class End Namespace Exemplu non-trivial Cod sursă în VB.NET Imports System.Colelections.Generic Imports System.Linq Imports System.Text Namespace Employees ''' <summary> ''' Clasa pentru stocarea datelor angajaților. ''' </summary> Class Angajat Privat m_name As String Private m_department As String Public Sub Nou ( numele ByVal ca șir , departamentul ByVal ca șir ) Eu . m_name = Numele Me . m_department = departament End Sub ''' <rezumat> ''' Numele angajatului. ''' </summary> Public ReadOnly Property Name () As String Get Return Me . m_name End Obține proprietatea End ''' <rezumat> ''' Departamentul de lucru. ''' </summary> Public ReadOnly Property Department () As String Get Return Me . m_department End Obține End Property End Class ''' <rezumat> ''' Clasă pentru stocarea unei liste de angajați. ''' </summary> Class EmployeesList Angajații privați ca listă nouă ( de angajați ) () ''' <rezumat> ''' Proprietate pentru obținerea și scrierea unui angajat după index. ''' </summary> ''' <param name="index">Indexul angajaților.</param> ''' <returns>Angajat.</returns> Element de proprietate publică implicit ( index ByVal ca întreg ) Ca și angajat Obținere Returnare angajați ( index ) End Get Set ( valoarea ByVal ca angajat ) angajați ( index ) = valoare End Set End Property ''' <rezumat> ''' Adăugarea unui nou angajat. ''' </summary> ''' <param name="employee">Angajat nou.</param> Public Sub Adaugă ( Angajat ByVal ca angajat ) angajați . Adaugă ( angajat ) End Sub ''' <rezumat> ''' Ștergeți un angajat existent. ''' </summary> ''' <param name="employee">Angajat de eliminat.</param> Public Sub Eliminați ( Angajat ByVal ca angajat ) angajați . Eliminați ( angajat ) End Sub ''' <rezumat> ''' Căutare secvenţială a unui angajat după nume. ''' </summary> ''' <param name="name">Numele angajatului.</param> ''' <returns>Indexul angajaților.</returns> Funcția publică GetIndexOfEmployeeByName ( ByVal name As String ) As Integer Dim index Ca întreg = - 1 Pentru i Ca întreg = 0 Pentru angajați . Număr - 1 Dacă angajați ( i ). Nume = nume Apoi index = i Ieșire pentru Sfârșit Dacă Următorul Întoarce index Funcția Sfârșit ''' <rezumat> ''' Căutare secvenţială a unui angajat după nume. ''' </summary> ''' <param name="name">Numele angajatului.</param> ''' <param name="offset">Poziție din care începeți căutarea.</param> '' ' < returnează>Indexul angajaților.</returns> Funcția publică GetIndexOfEmployeeByName ( Numele ByVal As String , ByVal offset As Integer ) As Integer Dim index As Integer = - 1 Pentru i As Integer = offset Pentru angajați . Număr - 1 Dacă angajați ( i ). Nume = nume Apoi index = i Ieșire pentru End If Next Returnează index End Function End Class Class Program Shared Sub Main () „Creați o listă de angajați și adăugați-i intrări Dim empList As New EmployeesList () empList . Adăugați ( Angajat nou ( „Shlensky Dmitry” , „studio web” )) empList . Adăugați ( Angajat nou ( „Kusy Nazar” , „studio web” )) empList . Adăugați ( Angajat nou ( „Magpie Orest” , „studio web” ))) „Se caută angajatul Kusyi Nazar și se afișează rezultatul la căutare de la început și din poziția a 2-a Consolă . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()) Console . WriteLine ( empList . GetIndexOfEmployeeByName ( „Kusy Nazar” , 2 ). ToString ()) 'Căutați și ștergeți angajatul Soroka Orestes empList . Eliminați ( empList ( empList . GetIndexOfEmployeeByName ( „Magpie Orestes” ))) Consolă . Citiți () End Sub End Class End Namespace

Vezi și

Note

  1. Bruce Eckel. Filosofia Java. - editia a 4-a. - SRL Editura „Peter”, 2016. - S. 215. - 1165 p.

Literatură

  • Julian Bucknell „Algoritmi fundamentale și structuri de date în Delphi”. Ed. Diasoft 2003
  • Grand M. Modele de proiectare în Java. 2004
  • Bruce Eckel „Filosofia Java”. Ed. „Petru” 2016