When should I use "Delegation)?

zhaozj2021-02-08  211

Since category inheritance and object portfolio are two main methods for object-oriented software design; in addition to inheriting inheritance, it is often used in combination of objects. At this time, it is often commonly used.

Item A "Transfer" from the message from the outside to the object B, by B, we call the object A. Particil B. When a group of objects communicate with each other, they often use the concept. Although C has not directly supported the entrustment function, it can be indirectly expressed. Since the class inheritance and object combination are two main methods for the object-oriented software design; in the case of inconvenience inheritance, the combination of objects is often used, and the concept is also commonly used. For example, there is a "rectangular" category:

Then I want to design a "square" category, most people will first think of inheritance:

This is repeatedly used to use this area () function.

This inheritance structure has some universal deficiencies, such as Square inherits the setWidth () () () and setHeight () functions from Rectangle, which is useless and harmful to Square (). In case, you will call Square's setWidth (), then Square's 4 is not waiting! At this time, the object combination can be used instead of inheritance:

When the object of Square is connected to the area () message from the outside, it is delegated to the process of rectangle. Expressed with C as follows:

Rectangle

Class Rectangle {

Double Width, Height;

PUBLIC:

Void setWidth (double w)

{width = W;}

Void setHeight (Double H)

{height = h;}

Double Area ()

{Return Width * Height;}

}

Class Square {

Rectangle * Rectangle;

PUBLIC:

Square () {rectangle = new reccTangle;

Void setLength (double LEN)

{Rectangle-> SetWidth (LEN);

Rectangle-> setHeight (LEN);

}

Double Area ()

{RETURN Rectangle-> area ();

}

Setwidth () and setHeight () do not belong to the Square category, there is no side effects. However, some shortcomings: Rectangle values ​​are determined when executed, that is, the delegate relationship is executed when executed. Once the rectangle value changes, the entrusted object is changed. Therefore, it is very resilient, but it is more complicated. In turn, the inheritance relationship is determined when compiled, which can make the program clearly, but cannot change the inheritance relationship during execution, which is less elastic. Because inheritance and entrustments can reach the purpose of reuse, the director has a short, complement each other is perfect. Simple rules are:

"Priority consideration to use inheritance, if you think it is strong,

Consider the commission

Please see the following example, there is a "round" category and "square" category, together to derive the CR category:

The DRAW () of the CR category will call Square :: DRAW () plot the square, and then call Circle :: DRAW () plot the square of the square. Expressed in C as:

Circle

Class Circle

{

protected:

INT X, Y, R;

PUBLIC:

Circle (int A, int b, int)

: x (a), y (b), z (c) {}

Void Draw () {....}

}

Square

Class Square

{

PUBLIC:

Virtual int getX () = 0;

Virtual int getY () = 0;

Virtual int getLength () = 0;

Void Draw ()

{GetX ()

Gety ()

....

}

}

Class CR

Class CR: Public Circle, Public Square {

PUBLIC:

Virtual int getX ()

{Return X;}

Virtual int game ()

{RETURN Y;}

Virtual int getLength ()

{RETURN R * 2;}

Void Draw () {...}

}

When Square's Draw () function draws, the center point coordinate (X, Y) value of the square is first obtained from the Cr, and the side length of the square is obtained, and then the square is drawn.

In general, multiple inheritances often have some side effects, such as the conflict of the name, and the like. In order to avoid the above double inheritance, the entrust method can be used, as shown below.

Expressed with C as follows:

Square

Class Square

{

Draw (Cr * PCR)

{PCR-> getX ()

PCR-> getY ()

....

}

}

Class CR: Public Circle

{

Square * square;

PUBLIC:

INT getX () {returnix x;}

INT gety () {return y;}

INT getLength {RTURN R * 2;}

Void Draw ()

{Square-> DRAW (this);

........

}

Inheritance and commission are repeatedly used functions in another category or object. For example, when CR inherits Square, Cr uses Square's DRAW () to draw squares; when inheriting is changed to delegate, it is also the same as the Square's DRAW () to work as a square. Therefore, if you think that CR inherits Square is a bit troublesome, you should consider the use of commission. Although the entrustment will make the program complex, it is barely use inheritance, and the sequela will be larger. Because the side effects may continue to the children of CR!

转载请注明原文地址:https://www.9cbs.com/read-2851.html

New Post(0)