"Refactoring – Improving the design of existing code" reading notes----self encapsulate Field

Source: Internet
Author: User

If you access a field directly, you will become clumsy with the direct coupling of this field. This means that when the field permission changes, or after the name changes, your client code needs to make a corresponding change, you can set the value and accessor for this field and only access the fields with these functions.

Since ancient times, object-oriented about field access There are two factions, one faction think that if in the class of the field you can freely access him, do not need to through the indirect function to obtain. Another faction thinks that even in this class you should use only the set value and accessor functions to access indirectly.

Of course, the extra benefit of indirect access is that you can override the function by subclasses to change the way you get the data. He also allows you to support flexible data management methods, such as deferred initialization. The benefits of direct access to variables are also, that is, we can read the code of the people to give us more clear and clear thinking, do not chase the function after the general found that this is only a simple value function, thus affecting our judgment.

In the face of this choice, I support the author's point of view, I in this field of the class I would prefer to use direct access to the form, until the form of direct access to bring me trouble, then I will choose to change the way to use indirect access, which is the reconstruction of the charm that brings us, He can make us free to change the way we need to be.

If you want to access a field in a superclass, but want to change the access of the variable in the subclass to a computed value (or for that simple type code, the base class and subclass return a different type code) this is when using the self encapsulate filed, the field ego encapsulation is just the first step , after self-encapsulation, you can optionally override the value/SetPoint function in the subclass according to your own needs.

Practice:

    • Establish a value/accessor function for the field to be encapsulated.
    • Find all the reference points for the field and change them all to the set value/accessor function. If the reference point is to read the value of the field, it will call the accessor instead. If the reference point is to be given a field, change it to a value function. Of course there's a little trick here that will help you find all the reference points faster and more quickly, that is, by renaming the fields and using the compiler to help you find all the reference points.
    • Declare the field as private.
    • Review to ensure that all reference points are found.
    • Compile, test.

Example:

classintrange{ Public: Intrange (intLowintHigh ): M_low (Low), M_high (high) {}BOOLIncludes (intArg) {            returnArg >= m_low && Arg <=M_high; }        voidGrowintfactor) {M_high= M_high *factor; }    Private:        intM_low; intM_high;}

In order to encapsulate M_low and m_high we define the values/SetPoint functions and use them.

classintrange{ Public: Intrange (intLowintHigh ): M_low (Low), M_high (high) {}BOOLIncludes (intArg) {            returnArg >= low () && arg <=High (); }        voidGrowintfactor) {M_high= M_high *factor; }        Virtual intLow ()Const        {            returnM_low; } VirtualintHigh ()Const        {            returnM_high; }    Private:        intM_low; intM_high;};

At the same time, one thing to note here is that your accessor and the SetPoint function are called in the constructor. You need to be aware that C + + is now not polymorphic in the constructor by default, that is, if you put a virtual function in the constructor of the base class, when you create the subclass, When the constructor of the base class is entered, it does not call the virtual function of the subclass, still calls the virtual function of the base class.

It is also important to note that, by default, the Set value function is agreed to be used after the object is created , so the behavior during initialization may be different from the behavior of the set value function, in which case you either directly access the field in the constructor or create another initialization function separately.

Intrange (intint high ):    m_low (Low),    M_high (high) {    Initialize (low, high);} void Initialize (intint high ) {    = low ;     = High ;}

Of course, you may not see much value now, but if you have a subclass, the value of the above will come out.

classCappedrange: Publicintrange{ Public: Cappedrange (intLowintHighintcap): Intrange (Low, High), M_cap (CAP) {} virtualintCap ()Const        {            returnM_cap; } VirtualintHigh ()Const        {            returnqmin (Intrange::high (), Cap ()); }    Private:        intM_cap;};

You can now overwrite in high () to add the range cap to the consideration without modifying any of the Intrange's behavior.

"Refactoring – Improving the design of existing code" reading notes----self encapsulate Field

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.