Clever Geek Handbook
πŸ“œ ⬆️ ⬇️

Delegation Template

Delegation is the basic design pattern in which an object externally expresses some behavior , but in reality transfers responsibility for the implementation of this behavior to the associated object. The delegation template is a fundamental abstraction , on the basis of which other templates are implemented - composition (also called aggregation), impurities (mixins) and aspects (aspects).

Delegation
Delegation
Described in Design PatternsNot

Pros

The ability to change the behavior of a specific instance of an object instead of creating a new class by inheritance.

Cons

This pattern usually makes speed optimization more difficult in favor of improved clarity of abstraction.

Applicability

Java

Although delegation is not supported by the Java language, its support is present in many development environments. [one]

Examples

Java

A simple example

In this Java example, class B has a method stub that passes methods foo() and bar() class A Class B pretends to have class A attributes.

Java source code
  class A {
     void foo () {
         System  out .  println ( "A: foo () method called" );
     }
     void bar () {
         System  out .  println ( "A: method bar ()" called ); 
     }
 }

 class B {
     // Create an object whose methods will be delegated behavior.
     A a = new 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 ();
     }
 }

Complicated Example

Using interfaces , delegation can be implemented more flexibly and with type protection (typesafe). In this example, class C can delegate to either class A or class B Class C has methods for switching between classes A and B Enabling the implements extension improves type safety because each class must execute methods in an interface. The main disadvantage is the large amount of code.

We give an example. Suppose you want to implement a timer so that after a certain amount of time some function is called. The timer programmer wants to provide the task of the function to users of his class (other programmers).

Java source code
  / **
 * The interface describes the action that will be called upon occurrence
 * timer events.
 * /
 interface TimerAction {
     void onTime ();
 }

 class WakeUpAction implements TimerAction {
     @Override
     public void onTime () {
         System  out .  println ( "Time to get up!" );
     }
 }

 class ChickenIsReadyAction implements TimerAction {
     @Override
     public void onTime () {
         System  out .  println ( "Chicken is ready!" );
     }
 }

 / **
 * Timer class.  Under certain conditions, the TimerAction action is called.
 * /
 class Timer {
     TimerAction action ;

     / **
 * The function that the programmer calls to set the time.
 * /
     void run () {
         if ( isTime ()) {
             action .  onTime ();
         }
     }

     / **
 * Some function that takes on all the work over time.  Her
 * implementation is not interesting in this context.
 *
 * @return
 * /
     private boolean isTime () {
         return true ;
     }

     public static void main ( String [] args ) {

         System  out .  println ( "Enter the type of action:" );
         Scanner scanner = new Scanner ( System . In );
         String actionType = scanner .  nextLine ();
         Timer timer = new Timer ();
        
         if ( actionType . equalsIgnoreCase ( "set wake up timer" )) {
             timer .  action = new WakeUpAction ();
         } else if ( actionType . equalsIgnoreCase ( "set chicken timer" )) {
             timer .  action = new ChickenIsReadyAction ();
         }
        
         timer .  run ();
     }

C ++

Complicated Example

This example is the C ++ version of the sophisticated Java example above. Since C ++ does not have an interface construct, the fully abstract class plays the same role. The advantages and disadvantages are basically the same as in the Java example.

C ++ source code
  #include <iostream> 

 class I {
    public :
       virtual void f () = 0 ;
       virtual void g () = 0 ;
 };

 class A : public I {
    public :
       void f () { std :: cout << "A: call the f () method << std :: endl ;  }
       void g () { std :: cout << "A: call the g () method << std :: endl ;  }
 };

 class B : public I {
    public :
       void f () { std :: cout << "B: we call the f () method << std :: endl ;  }
       void g () { std :: cout << "B: call the g () method << std :: endl ;  }
 };

 class C : public I {
    public :
      // Constructor
       C () : m_i ( new A () ) { }
      // Destructor
       virtual ~ C () {
          delete m_i ;
       }
       void f () { m_i -> f ();  }
       void g () { m_i -> g ();  }
      // Using these methods, we change the object field whose methods we will delegate
       void toA () {
          delete m_i ;
          m_i = new A ();
       }
       void toB () {
          delete m_i ;
          m_i = new B ();
       }
    private :
      // Declare an object whose methods we will delegate
       I * m_i ;
 };

 int main () {
    C c ;

    c .  f ();
    c .  g ();
    c .  toB ();
    c .  f ();
    c .  g ();

    return 0 ;
 }

 / * Output:
 A: we call the f () method
 A: we call the g () method
 B: we call the f () method
 B: we call the g () method
 * /

C #

C # source code
  namespace Patterns
 {
     interface I
     {
         void f ();
         void g ();
     }

     class A 
       : I
     {
         public void f ()
         {
             System  Console  WriteLine ( "A: call the f () method" );
         }
         public void g ()
         {
             System  Console  WriteLine ( "A: we call the g () method" );
         }
     }

     class B 
       : I
     {
         public void f ()
         {
             System  Console  WriteLine ( "B: we call the f () method" );
         }
         public void g ()
         {
             System  Console  WriteLine ( "B: we call the g () method" );
         }
     }

     class C 
       : I
     {
         // Create an object whose methods we will delegate
         I i = new A ();

         public void f ()
         {
             i .  f ();
         }
         public void g ()
         {
             i .  g ();
         }

         // Using these methods, we change the object field whose methods we will delegate
         public void toA ()
         {
             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 ();
             System  Console  ReadKey ();
         }
     }
 }

Nontrivial Example

This is an example of a case often encountered in practice. The task is to create a class for storing a list of employees. Each employee data is stored in an object of the Employee class. There is a ready-made and standard class for storing a list of Employee objects. It already implements mechanisms for working with the list (for example, memory allocation, adding and removing from the list). Inheriting the employee list class from the object list class is not acceptable here, because we will get all the methods (even those that are not of interest to us). In addition, in some cases we will have to typecast. The most elegant way out of this case is to delegate to the employee list class part of the methods of the object list class. In the OOP rules, it is best to present the list of objects using the private (private) method of list of employees. In this case, access to the list is possible through the indexer.

C # source code
  using System ;
 using System.Collections.Generic ;
 using System.Linq ;
 using System.Text ;

 namespace Employees
 {
     /// <summary>
     /// Class for storing employee data.
     /// </summary>
     class Employee
     {
         private string name ;
         private string department ;
        
         public Employee ( string name , string departament )
         {
             this .  name = name ;
             this .  department = departament ;
         }

         /// <summary>
         /// Name of employee.
         /// </summary>
         public string Name
         {
             get { return this .  name ;  }
         }

         /// <summary>
         /// Department of work.
         /// </summary>
         public string Department
         {
             get { return this .  department ;  }
         }
     }

     /// <summary>
     /// Class for storing a list of employees.
     /// </summary>
     class EmployeesList
     {
         private List < Employee > employees = new List < Employee > ();
        
         /// <summary>
         /// Property for getting and writing employee by index.
         /// </summary>
         /// <param name = "index"> Employee index. </param>
         /// <returns> Employee. </returns>
         public Employee this [ int index ]
         {
             get
             {
                 return employees [ index ];
             }
             set
             {
                 employees [ index ] = value ;
             }
         }

         /// <summary>
         /// Add a new employee.
         /// </summary>
         /// <param name = "employee"> New employee. </param>
         public void Add ( Employee employee )
         {
             employees .  Add ( employee );
         }
        
         /// <summary>
         /// Delete existing employee.
         /// </summary>
         /// <param name = "employee"> The employee to delete. </param>
         public void Remove ( Employee employee )
         {
             employees .  Remove ( employee );
         }
        
         /// <summary>
         /// Sequential search for an employee by name.
         /// </summary>
         /// <param name = "name"> Employee name. </param>
         /// <param name = "offset"> The position from which to start the search. </param>
         /// <returns> Employee Index. </returns>
         public int GetIndexOfEmployeeByName ( string name , int offset = 0 )
         {
             for ( int i = offset ; i < employees . Count ; i ++)
             {
                 if ( employees [ i ]. Name == name )
                 {
                     return i ;
                 }
             }
             return - 1 ;
         }
     }
    
     class program
     {
         static void Main ( string [] args )
         {
             // Create a list of employees and add entries to it
             EmployeesList empList = new EmployeesList ();
             empList .  Add ( new Employee ( "Shlyonsky Dmitry" , "web studio" ));
             empList .  Add ( new Employee ( "Kusyy Nazar" , "web studio" ));
             empList .  Add ( new Employee ( "Magpie Orest" , "web studio" ));

             // Search for an employee Kusyy Nazar and display the result when searching from the beginning and from the 2nd position
             Console  WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ());
             Console  WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ());

             // Search and delete an employee of Magpie Orest
             empList .  Remove ( empList [ empList . GetIndexOfEmployeeByName ( "Forty Orest" )]);
         }
     }
 }
C # 2 source code
  using System ;
 using System.Collections.Generic ;
 using System.Linq ;
 using System.Text ;

 namespace Employees
 {
     /// <summary>
     /// Class for storing employee data.
     /// </summary>
     class Employee
     {
         private string name ;
         private string department ;
        
         public Employee ( string name , string departament )
         {
             this .  name = name ;
             this .  department = departament ;
         }

         /// <summary>
         /// Name of employee.
         /// </summary>
         public string Name
         {
             get { return this .  name ;  }
         }

         /// <summary>
         /// Department of work.
         /// </summary>
         public string Department
         {
             get { return this .  department ;  }
         }
     }

     /// <summary>
     /// Class for storing a list of employees.
     /// </summary>
     class EmployeesList
     {
         private List < Employee > employees = new List < Employee > ();
        
         /// <summary>
         /// Property for getting and writing employee by index.
         /// </summary>
         /// <param name = "index"> Employee index. </param>
         /// <returns> Employee. </returns>
         public Employee this [ int index ]
         {
             get
             {
                 return employees [ index ];
             }
             set
             {
                 employees [ index ] = value ;
             }
         }

         /// <summary>
         /// Property for receiving and recording an employee by name.
         /// </summary>
         /// <param name = "name"> Employee name. </param>
         /// <returns> The first employee to have the same name or null </returns>
         public Employee this [ string name ]
         {
             get
             {
                 foreach ( Employee item in employees ) {
		     if ( item . Name == name )
			 return item ;
		 }
		 return null ;
             }
         }

         /// <summary>
         /// Add a new employee.
         /// </summary>
         /// <param name = "employee"> New employee. </param>
         public void Add ( Employee employee )
         {
             employees .  Add ( employee );
         }
        
         /// <summary>
         /// Delete existing employee.
         /// </summary>
         /// <param name = "employee"> The employee to delete. </param>
         public void Remove ( Employee employee )
         {
             employees .  Remove ( employee );
         }

         /// <summary>
         /// Sequential search for an employee by name.
         /// </summary>
         /// <param name = "name"> Employee name. </param>
         /// <param name = "offset"> The position from which to start the search. </param>
         /// <returns> Employee Index. </returns>
         public int GetIndexOfEmployeeByName ( string name , int offset )
         {
             int index = - 1 ;

             for ( int i = offset ; i < employees . Count ; i ++)
             {
                 if ( employees [ i ]. Name == name )
                 {
                     index = i ;
                     break ;
                 }
             }
             return index ;
         }

         /// <summary>
         /// Sequential search for an employee by name.
         /// </summary>
         /// <param name = "name"> Employee name. </param>
         /// <returns> Employee Index. </returns>
         public int GetIndexOfEmployeeByName ( string name )
         {            
             return GetIndexOfEmployeeByName ( name , 0 );
         }        
     }
    
     class program
     {
         static void Main ( string [] args )
         {
             // Create a list of employees and add entries to it
             EmployeesList empList = new EmployeesList ();
             empList .  Add ( new Employee ( "Shlyonsky Dmitry" , "web studio" ));
             empList .  Add ( new Employee ( "Kusyy Nazar" , "web studio" ));
             empList .  Add ( new Employee ( "Magpie Orest" , "web studio" ));

             // Search for an employee Kusy Nazar and display the result when searching from the beginning and from the 2nd position
             Console  WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ());
             Console  WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ());

             // Search and delete an employee of Magpie Orest
             empList .  Remove ( empList [ "Magpie Orest" ]);
         }
     }
 }

Objective-C 2.0

A simple example

Objective-C source code
  enum {
	 GLEngineChangeView
 };

 @interface GLEngine : NSObject {
	
	 id _delegate ;
	 BOOL _event [ NUM ]; 
 }
 - ( id ) delegate ;
 - ( void ) setDelegate: ( id ) delegate ;
 - ( void ) changeView: ( GLView * ) view ;
 @end

 @protocol GLEngineDelegate < NSObject >

 @optional
 - ( BOOL ) engine : ( GLEngine * ) engine changeView : ( GLView * ) view ;

 @end
  @interface GLEngine (Internal)

 - ( void ) registerDelegate ;

 @end

 @implementation GLEngine

 - ( id ) delegate {
	
	 return _delegate ;
 }

 - ( void ) setDelegate: ( id ) delegate {
	
	 _delegate = delegate ;
	 [ self registerDelegate ];
 }

 - ( void ) changeView: ( GLView * ) view {
	
	 if ( _event [ GLEngineChangeView ]) {
		 // delegate the request
		 if ([ _delegate engine : self changeView : view ]) {
			 // use the changed view
			 }
                 else
		        // request was not processed
	 }
	 // or use the standard method
 }

 - ( void ) registerDelegate {
	
	 if ([ _delegate responseToSelector : @selector ( engine : changeView :)]) {
		 _event [ GLEngineChangeView ] = YES ;
	 }
 }

 @end
  @interface MyGLEngineDelegate : NSObject < GLEngineDelegate > {
	
	 //
 }
 @end
  @implementation MyGLEngineDelegate

 - ( BOOL ) engine: ( Engine * ) engine changeView: ( GLView * ) view {

	 // change the view
 }

 @end

Object Pascal

A simple example

Object Pascal source code
  
   type

     IDelegateInterface = interface
       procedure Method1 ;
       procedure Method2 ;
     end ;

     TClassA = class ( TInterfacedObject , IDelegateInterface )
     public
       procedure Method1 ;
       procedure Method2 ;
     end ;

     TClassB = class ( TInterfacedObject , IDelegateInterface )
     public
       procedure Method1 ;
       procedure Method2 ;
     end ;

     TClassDel = class ( TInterfacedObject , IDelegateInterface )
     private
       FInterface : IDelegateInterface ;
     public
       procedure Method1 ;
       procedure Method2 ;
       procedure ToClassA ;
       procedure ToClassB ;
     end ;

   implementation

   {TClassA}

   procedure TClassA .  Method1 ;
   begin
     Writeln ( 'TClassA.Method1' ) ;
   end ;

   procedure TClassA .  Method2 ;
   begin
     Writeln ( 'TClassA.Method2' ) ;
   end ;

   {TClassB}

   procedure TClassB .  Method1 ;
   begin
     Writeln ( 'TClassB.Method1' ) ;
   end ;

   procedure TClassB .  Method2 ;
   begin
     Writeln ( 'TClassB.Method2' ) ;
   end ;

   {TClassDel}

   procedure TClassDel .  Method1 ;
   begin
     FInterface .  Method1 ;
   end ;

   procedure TClassDel .  Method2 ;
   begin
     FInterface .  Method2 ;
   end ;

   procedure TClassDel .  ToClassA ;
   begin
     FInterface : = TClassA .  Create ;
   end ;

   procedure TClassDel .  ToClassB ;
   begin
     FInterface : = TClassB .  Create ;
   end ;

Nontrivial Example

This example is the Object Pascal version of the non-trivial example above.

Object Pascal source code
  unit UnitEmployeers ;

  interface

  uses
    Contnrs

  type
    // Class for storing employee data
    TEmployee = class
    private
      FName : string ;
      FDepartament : string ;
    public
      constructor Create ( Name , Departament : string ) ;
    published
      property Name : string read FName ;
      property Departament : string read FDepartament ;
    end ;

    // Class for storing the list of employees
    TEmployeersList = class
    private
      // Object of class "list of objects"
      FEmployeersList : TObjectList ;
      function GetEmployee ( Index : Integer ) : TEmployee ;
      procedure SetEmployee ( Index : Integer ; const Value : TEmployee ) ;
    public
      constructor Create ;
      destructor Destroy ;  override ;
      function Add ( Employee : TEmployee ) : Integer ;
      procedure Remove ( Employee : TEmployee ) ;
      function IndexEmployeeByName ( Name : string ; Offset : Integer = 0 ) : Integer ;
      property Employeers [ Index : Integer ] : TEmployee read GetEmployee write SetEmployee ;  default ;
    end ;

  implementation

  {TEmployee}

  constructor TEmployee .  Create ( Name , Departament : string ) ;
  begin
    FName : = Name ;
    FDepartament : = Departament ;
  end ;

  {TEmployeersList}

  constructor TEmployeersList .  Create ;
  begin
    // Create an object whose methods we will delegate
    FEmployeersList : = TObjectList .  Create ;
  end ;

  destructor TEmployeersList .  Destroy
  begin
    FEmployeersList .  Free
    inherited ;
  end ;

  function TEmployeersList .  GetEmployee ( Index : Integer ) : TEmployee ;
  begin
    Result : = FEmployeersList [ Index ] as TEmployee ;
  end ;

  procedure TEmployeersList .  SetEmployee ( Index : Integer ; const Value : TEmployee ) ;
  begin
    FEmployeersList [ Index ] : = Value ;
  end ;

  function TEmployeersList .  IndexEmployeeByName ( Name : string ; Offset : Integer = 0 ) : Integer ;
  // Sequential search for an employee by name
  // Through the Offset argument, you can specify the position from which to search.
  // If the employee is not found, it will return a value less than zero (-1)
  var
    Index : Integer ;
  begin
    Result : = - 1 ;  // Assume It Is Not On The List
    for Index : = FEmployeersList .  Count - 1 downto Offset do
      if ( FEmployeersList [ Index ] as TEmployee ) .  Name = Name then
      begin
        Result : = Index ;
        Exit
      end ;
  end ;

  function TEmployeersList .  Add ( Employee : TEmployee ) : Integer ;
  begin
    Result : = FEmployeersList .  Add ( Employee ) ;
  end ;

  procedure TEmployeersList .  Remove ( Employee : TEmployee ) ;
  begin
    FEmployeersList .  Remove ( Employee ) ;
  end ;

  end .

Unfortunately, not all programmers use the delegation pattern. For example, Borland (the developer of the Delphi programming environment) in its standard class library inherited the aforementioned TObjectList object list class from the TList pointer list class . This caused discontent among some experienced programmers.

PHP5

A simple example

This example is a PHP version of the simple Java example above.

PHP5 source code
  <? php

 class A {
	
	 public function f () {
		 print "A: Call the f () method <br />" ;
	 }

	 public function g () {
		 print "A: Call the g () method <br />" ;
	 }
 }

 class C {
	
	 private $ _a ;
	
	 public function __construct () {
		 $ this -> _a = new A ;
	 }
	
	 public function f () {
		 $ this -> _a -> f ();
	 }

	 public function g () {
		 $ this -> _a -> g ();
	 }

	 public function y () {
		 print "C: call the y () method <br />" ;
	 }
 }

 $ obj = new C ;
 $ obj -> f ();
 $ obj -> g ();
 $ obj -> y ();

 ?> 

Complicated Example

This example is the PHP version of the sophisticated Java example above.

PHP5 source code
  <? php

 // use the interface for security type
 interface I {
	 public function f ();
	 public function g ();
 }

 class A implements I {
	 public function f () {
		 print "A: Call the f () method <br />" ;
	 }

	 public function g () {
		 print "A: Call the g () method <br />" ;
	 }
 }

 class B implements I {
	 public function f () {
		 print "B: Call the f () method <br />" ;
	 }

	 public function g () {
		 print "B: Call the g () method <br />" ;
	 }
 }

 class C implements I {
	 private $ _i ;
	
	 // create an object whose methods we will delegate
	 public function __construct () {
		 $ this -> _i = new A ;
	 }
	
	 // with these methods we change the object field whose methods we will delegate
	 public function toA () {
		 $ this -> _i = new A ;
	 }

	 public function toB () {
		 $ this -> _i = new B ;
	 }
	
	
	 // delegated methods
	 public function f () {
		 $ this -> _i -> f ();
	 }

	 public function g () {
		 $ this -> _i -> g ();
	 }
 }

 $ obj = new C ;
 $ obj -> f ();
 $ obj -> g ();
 $ obj -> toB ();
 $ obj -> f ();
 $ obj -> g ();

 ?> 

Nontrivial Example

This example is a PHP version of the non-trivial example above.

PHP5 source code
  <? php

 // class for storing employee data
 class Employee {
	
	 private $ _name ;
	 private $ _departament ;
	
	 public function __construct ( $ name , $ departament ) {
		 $ this -> _name = $ name ;
		 $ this -> _departament = $ departament ;
	 }
	
	 public function getName () {
		 return $ this -> _name ;
	 }

	 public function getDepartament () {
		 return $ this -> _departament ;
	 }
 }

 // class to store the list of objects
 class ObjectList {
	
	 private $ _objList ;
	
	 public function __construct () {
		 $ this -> free ();
	 }
	 / **
 * not to be bored!
 * /
	 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 ];
	 }

	 public function set ( $ index , $ obj ) {
		 $ this -> _objList [ $ index ] = $ obj ;
	 }
 }

 // class for storing employees
 class EmployeeList {

	 // object of class "list of objects"
	 private $ _employeersList ;
	
	 public function __construct () {
		 // create an object whose methods we will delegate
		 $ this -> _employeersList = new ObjectList ;
	 }

	 public function getEmployer ( $ index ) {
		 return $ this -> _employeersList -> get ( $ index );
	 }
	
	 public function setEmployer ( $ index , Employee $ objEmployer ) {
		 $ this -> _employeersList -> set ( $ index , $ objEmployer );
	 }
	
	 public function __destruct () {
		 $ this -> _employeersList -> free ();
	 }
	
	 public function add ( Employee $ objEmployer ) {
		 $ this -> _employeersList -> add ( $ objEmployer );
	 }
	
	 public function remove ( Employee $ objEmployer ) {
		 $ this -> _employeersList -> remove ( $ objEmployer );
	 }
	
	 // sequential search for an employee by name
	 // through the argument $ offset, you can specify the position from which to search.
	 // if the employee is not found, will return a value less than zero (-1)
	 public function getIndexByName ( $ name , $ offset = 0 ) {
		 $ result = - 1 ;  // assume it is not in the list
		 $ cnt = $ this -> _employeersList -> count ();
		 for ( $ i = $ offset ; $ i < $ cnt ; $ i ++ ) {
			 if ( ! strcmp ( $ name , $ this -> _employeersList -> get ( $ i ) -> getName () ) ) {
				 $ result = $ i ;
				 break ;
			 }
		 }
		 return $ result ;
	 }
 }

 $ obj1 = new Employee ( "Tanasiychuk Stepan" , "web studio" );
 $ obj2 = new Employee ( "Kusyy Nazar" , "web studio" );
 $ obj3 = new Employee ( "Forty Orest" , "web studio" );

 $ objList = new EmployeeList ();
 $ objList -> add ( $ obj1 );
 $ objList -> add ( $ obj2 );
 $ objList -> add ( $ obj3 );

 echo "<pre>" ;
 print_r ( $ objList );

 echo "<hr>" ;

 $ index = $ objList -> getIndexByName ( "Kusy Nazar" );
 $ obj4 = $ objList -> getEmployer ( $ index );
 print_r ( $ obj4 );

 echo "<hr>" ;

 $ objList -> setEmployer ( 2 , $ obj4 );
 print_r ( $ objList );
 echo "</pre>" ;
 ?> 

Python

A simple example

Python source code

  #coding: utf-8
 #python 3
 class A :
     def f ( self ):
         print ( 'A: call method f' )
     def g ( self ):
         print ( 'A: call the g' method )
 class C :
     def __init__ ( self ):
         self .  A = A ()
     def f ( self ):
         return self .  A.  f ()
     def g ( self ):
         return self .  A.  g ()
 c = C ()
 c .  f () #A: call the f method
 c .  g () #A: call the g method

JavaScript

A simple example

JavaScript source
  function A () {
	 this .  f = function () {
		 alert ( "A: call the f () method" );
	 };
	 this .  g = function () {
		 alert ( "A: call the g () method" );
	 };
 }

 function C () {
	 var a = new A ();
	 this .  f = function () {
		 a .  f ();
	 };
	 this .  g = function () {
		 a .  g ();
	 };
 }

 var c = new C ();
 c .  f ();  // "A: call the f () method"
 c .  g ();  // "A: call the g () method"

Complicated Example

JavaScript source
  function A () {
	 this .  f = function () {
		 alert ( "A: call the f () method" );
	 };
	 this .  g = function () {
		 alert ( "A: call the g () method" );
	 };
 }

 function B () {
	 this .  f = function () {
		 alert ( "B: call the f () method" );
	 };
	 this .  g = function () {
		 alert ( "B: call the g () method" );
	 };
 }

 function C () {
	 // instantiate A and B
	 var a = new A (); 
	 var b = new B ();
	 var cur = a ;  // link to the current object with the implementation of methods;  default is A
	
	 this .  toA = function () {
		 cur = a ;
	 };
	 this .  toB = function () {
		 cur = b ;
	 };
	
	 this .  f = function () {
		 cur .  f ();
	 };
	 this .  g = function () {
		 cur .  g ();
	 };
 }

 var c = new C ();
 c .  f ();  // "A: call the f () method"
 c .  g ();  // "A: call the g () method"
 c .  toB ();
 c .  f ();  // "B: call the f () method"
 c .  g ();  // "B: call the g () method"

Nontrivial Example

JavaScript source
  function Employee ( name , departament ) {
	 this .  getName = function () {
		 return name ;
	 };
	 this .  getDepartament = function () {
		 return departament ;
	 };
	 this .  toString = function () {
		 // convert to string for convenient debugging
		 return "Employee" + name + "," + departament ;
	 };
 }

 function EmployeesList () {
	 var employees = [];
	
	 this .  add = function () {
		 // function takes an arbitrary number of arguments
		 for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
			 if ( arguments [ i ]. constructor == Employee ) {
				 // type check
				 employees .  push ( arguments [ i ]);
			 }
		 }
	 };
	 this .  set = function ( obj , index ) {
		 if ( obj . constructor == Employee ) {
			 delete employees [ index ];
			 employees [ index ] = obj ;
		 }
	 };
	 this .  remove = function ( obj ) {
		 for ( var i = 0 , l = employees . length ; i < l ; i ++ ) {
			 if ( employees [ i ] == obj ) {
				 employees .  splice ( i , 1 );
				 i - ;
				 l - ;
			 }
		 }
	 };
	 this .  getByIndex = function ( num ) {
		 return employees [ num ];
	 };
	 this .  getIndexByName = function ( name , offset ) {
		 // sequential search for an employee by name
		 // through the offset argument, you can specify the position from which to search.  (default 0)
		 // if the employee is not found, will return -1
		 for ( var i = offset || 0 , l = employees . length ; i < l ; i ++ ) {
			 if ( employees [ i ]. getName () == name ) return i ;
		 }
		 return - 1 ;
	 };
	 this .  toString = function () {
		// ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² строку для ΡƒΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ Π΄Π΅Π±Π°Π³Π°
		var ret = "" ;
		for ( var i = 0 , l = employees . length ; i < l ; i ++ ) {
			ret += i + ": " + employees [ i ] + "\n" ;
		 }
		return ret ;
	 };
 }

var o1 = new Employee ( "Ванасийчук Π‘Ρ‚Π΅ΠΏΠ°Π½" , "web студия" );
var o2 = new Employee ( "ΠšΡƒΡΡ‹ΠΉ Назар" , "web студия" );
var o3 = new Employee ( "Π‘ΠΎΡ€ΠΎΠΊΠ° ΠžΡ€Π΅ΡΡ‚" , "web студия" );

var emps = new EmployeesList ();
emps . add ( o1 , o2 , o3 ); // ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈ ΠΏΠΎ-ΠΎΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠ΅
alert ( emps ); // "0: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ Ванасийчук Π‘Ρ‚Π΅ΠΏΠ°Π½, web студия
             // 1: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ ΠšΡƒΡΡ‹ΠΉ Назар, web студия
             // 2: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ Π‘ΠΎΡ€ΠΎΠΊΠ° ΠžΡ€Π΅ΡΡ‚, web студия"

var obj4 = emps . getByIndex ( emps . getIndexByName ( "ΠšΡƒΡΡ‹ΠΉ Назар" ) ); // ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ссылку Π½Π° сотрудника
alert ( obj4 ); // "Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ ΠšΡƒΡΡ‹ΠΉ Назар, web студия"

emps . set ( obj4 , 2 ); // вмСсто 2Π³ΠΎ (ΠΎΡ‚ ноля) сотрудника вставляСм obj4
alert ( emps ); // "0: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ Ванасийчук Π‘Ρ‚Π΅ΠΏΠ°Π½, web студия
             // 1: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ ΠšΡƒΡΡ‹ΠΉ Назар, web студия
             // 2: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ ΠšΡƒΡΡ‹ΠΉ Назар, web студия"

emps . remove ( obj4 ); // удаляСм сотрудника obj4
alert ( emps ); // "0: Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ Ванасийчук Π‘Ρ‚Π΅ΠΏΠ°Π½, web студия"

VB.NET

Π‘Π»ΠΎΠΆΠ½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ тСкст Π½Π° VB.NET
 Namespace Patterns

    Interface I
        Sub f ()
        Sub g ()
    End Interface

    Class A
        Implements I

        Public Sub f () Implements I .  f
            System . Console . WriteLine ( "A: Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ f()" )
        End Sub

        Public Sub g () Implements I . g
            System . Console . WriteLine ( "A: Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ g()" )
        End Sub
    End Class

    Class B
        Implements I

        Public Sub f () Implements I .  f
            System . Console . WriteLine ( "B: Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ f()" )
        End Sub

        Public Sub g () Implements I . g
            System . Console . WriteLine ( "B: Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ g()" )
        End Sub
    End Class

    Class C
        Implements I

        ' Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
        Private i As I = New A ()

        Public Sub f () Implements i .  f
            i . f ()
        End Sub

        Public Sub g () Implements i . g
            i . g ()
        End Sub

        ' Π­Ρ‚ΠΈΠΌΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ мСняСм ΠΏΠΎΠ»Π΅-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ρ‡ΡŒΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Π»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ
        Public Sub toA ()
            i = New A ()
        End Sub

        Public Sub toB ()
            i = New B ()
        End Sub
    End Class

    Class DelegatePattern

        Shared Sub Main ()
            Dim c As New C ()
            c . f ()
            c . g ()

            c . toB ()

            c . f ()
            c . g ()
            System . Console . ReadKey ()
        End Sub

    End Class
End Namespace

ΠΠ΅Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ тСкст Π½Π° VB.NET
 Imports System.Collections.Generic
Imports System.Linq
Imports System.Text

Namespace Employees
    ''' <summary>
    ''' Класс для хранСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ сотрудникС.
    ''' </summary>
    Class Employee
        Private m_name As String
        Private m_department As String

        Public Sub New ( ByVal name As String , ByVal departament As String )
            Me . m_name = name
            Me . m_department = departament
        End Sub

        ''' <summary>
        ''' Имя сотрудника.
        ''' </summary>
        Public ReadOnly Property Name () As String
            Get
                Return Me . m_name
            End Get
        End Property

        ''' <summary>
        ''' ΠžΡ‚Π΄Π΅Π» Ρ€Π°Π±ΠΎΡ‚Ρ‹.
        ''' </summary>
        Public ReadOnly Property Department () As String
            Get
                Return Me . m_department
            End Get
        End Property
    End Class

    ''' <summary>
    ''' Класс для хранСния списка сотрудников.
    ''' </summary>
    Class EmployeesList
        Private employees As New List ( Of Employee )()

        ''' <summary>
        ''' Бвойство для получСния ΠΈ записи сотрудника ΠΏΠΎ индСксу.
        ''' </summary>
        ''' <param name="index">ИндСкс сотрудника.</param>
        ''' <returns>Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ.</returns>
        Default Public Property Item ( ByVal index As Integer ) As Employee
            Get
                Return employees ( index )
            End Get
            Set ( ByVal value As Employee )
                employees ( index ) = value
            End Set
        End Property

        ''' <summary>
        ''' Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ сотрудника.
        ''' </summary>
        ''' <param name="employee">Новый сотрудник.</param>
        Public Sub Add ( ByVal employee As Employee )
            employees . Add ( employee )
        End Sub

        ''' <summary>
        ''' Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ сторудника.
        ''' </summary>
        ''' <param name="employee">Π‘ΠΎΡ‚Ρ€ΡƒΠ΄Π½ΠΈΠΊ для удалСния.</param>
        Public Sub Remove ( ByVal employee As Employee )
            employees . Remove ( employee )
        End Sub

        ''' <summary>
        ''' ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ поиск сотрудника ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ.
        ''' </summary>
        ''' <param name="name">Имя сотрудника.</param>
        ''' <returns>ИндСкс сотрудника.</returns>
        Public Function GetIndexOfEmployeeByName ( ByVal name As String ) As Integer
            Dim index As Integer = - 1

            For i As Integer = 0 To employees . Count - 1
                If employees ( i ). Name = name Then
                    index = i
                    Exit For
                End If
             Next
            Return index
        End Function

        ''' <summary>
        ''' ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ поиск сотрудника ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ.
        ''' </summary>
        ''' <param name="name">Имя сотрудника.</param>
        ''' <param name="offset">ΠŸΠΎΠ·ΠΈΡ†ΠΈΡ, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ слСдуСт Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒ поиск.</param>
        ''' <returns>ИндСкс сотрудника.</returns>
        Public Function GetIndexOfEmployeeByName ( ByVal name As String , ByVal offset As Integer ) As Integer
            Dim index As Integer = - 1

            For i As Integer = offset To employees . Count - 1
                If employees ( i ). Name = name Then
                    index = i
                    Exit For
                End If
             Next
            Return index
        End Function
    End Class

    Class Program
        Shared Sub Main ()
            'Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ списка сотрудников ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ записСй Π² Π½Π΅Π³ΠΎ
            Dim empList As New EmployeesList ()
            empList . Add ( New Employee ( "Шлёнский Π”ΠΌΠΈΡ‚Ρ€ΠΈΠΉ" , "web студия" ))
            empList . Add ( New Employee ( "ΠšΡƒΡΡ‹ΠΉ Назар" , "web студия" ))
            empList . Add ( New Employee ( "Π‘ΠΎΡ€ΠΎΠΊΠ° ΠžΡ€Π΅ΡΡ‚" , "web студия" ))

            'Поиск сотрудника ΠšΡƒΡΡ‹ΠΉ Назар ΠΈ Π²Ρ‹Π²ΠΎΠ΄ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° ΠΏΡ€ΠΈ поискС с Π½Π°Ρ‡Π°Π»Π° ΠΈ со 2-ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ
            Console . WriteLine ( empList . GetIndexOfEmployeeByName ( "ΠšΡƒΡΡ‹ΠΉ Назар" ). ToString ())
            Console . WriteLine ( empList . GetIndexOfEmployeeByName ( "ΠšΡƒΡΡ‹ΠΉ Назар" , 2 ). ToString ())

            'Поиск ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ сотрудника Π‘ΠΎΡ€ΠΎΠΊΠ° ΠžΡ€Π΅ΡΡ‚
            empList . Remove ( empList ( empList . GetIndexOfEmployeeByName ( "Π‘ΠΎΡ€ΠΎΠΊΠ° ΠžΡ€Π΅ΡΡ‚" )))
            Console . Read ()
        End Sub

    End Class
End Namespace

See also

  • Π¨Π°Π±Π»ΠΎΠ½Ρ‹ проСктирования
  • ΠŸΠΎΡΡ‚-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

Notes

  1. ↑ Π‘Ρ€ΡŽΡ ЭккСль. Ѐилософия Java. β€” 4-Π΅ ΠΈΠ·Π΄Π°Π½ΠΈΠ΅. β€” ООО Π˜Π·Π΄Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ "ΠŸΠΈΡ‚Π΅Ρ€", 2016. β€” Π‘. 215. β€” 1165 с.

Literature

  • Π”ΠΆΡƒΠ»ΠΈΠ°Π½ Π‘Π°ΠΊΠ½Π΅Π»Π» Β«Π€ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ ΠΈ структуры Π΄Π°Π½Π½Ρ‹Ρ… Π² DelphiΒ». Ed. DiaSoft 2003 Π³ΠΎΠ΄
  • Π“Ρ€Π°Π½Π΄ М. Β«Π¨Π°Π±Π»ΠΎΠ½Ρ‹ проСктирования Π² JavaΒ». 2004
  • Π‘Ρ€ΡŽΡ ЭккСль "Ѐилософия Java". Ed. "ΠŸΠΈΡ‚Π΅Ρ€" 2016 Π³ΠΎΠ΄
Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ β€” https://ru.wikipedia.org/w/index.php?title=Π¨Π°Π±Π»ΠΎΠ½_дСлСгирования&oldid=100451459


More articles:

  • Ulyanovsk State Pedagogical University named after I. N. Ulyanov
  • Lancaster (California)
  • 38th Separate Streaming Battalion
  • Vesely (Veselovsky District)
  • Freestyle at the 2010 Winter Olympics - Acrobatics (men)
  • Novominskaya
  • CΓ©vennes
  • Dice Game
  • Rhomboid muscle
  • Marcel, Etienne

All articles

Clever Geek | 2019