The behavior of the multi-form method inside the builder

Source: Internet
Author: User
Tags abstract final

The hierarchical structure of the

Builder call (order) brings us to an interesting question, or to a dilemma. What happens if you are currently in the inner of a builder and call a dynamic binding method for the object that you are building up? Inside the original method, we can imagine exactly what happens-a dynamically bound call is parsed during run time because the object does not know whether it belongs to the class where the method is located, or some classes derived from it. To maintain consistency, you might think that this should happen inside the builder.
But that's not exactly the case. If you call a dynamically bound method inside the builder, you use the definition overridden by that method. However, the effect may not be as we would like, and may result in some bugs that are difficult to discover.
Conceptually, the role of the builder is to let the object actually enter the existing state. Inside any builder, the entire object might just get part of the organization-we only know that the underlying class object is initialized, but we don't know which classes are inherited. However, a dynamically bound method call moves forward or outwards in the hierarchy. It invokes a method that is located in a derived class. If you do this inside the builder, the members that it manipulates may not have been properly initialized for the invoked method-which is obviously not what we want.
by looking at the following example, the question becomes clear:
 

: Polyconstructors.java
//constructors and polymorphism
//don ' t produce what you might expect.

Abstract class Glyph {
  abstract void Draw ();
  Glyph () {
    System.out.println ("Glyph () before Draw ()");
    Draw (); 
    System.out.println ("Glyph () after draw ()");
  }

Class Roundglyph extends Glyph {
  int radius = 1;
  Roundglyph (int r) {
    radius = R;
    System.out.println (
      "roundglyph.roundglyph (), radius ="
      + radius);
  }
  void Draw () { 
    System.out.println (
      "Roundglyph.draw (), radius =" + radius);
  }

public class Polyconstructors {public
  static void Main (string[] args) {
    new roundglyph (5);
  }
}///: ~


In Glyph, the Draw () method is abstract, so it can be overridden by other methods. In fact, we have to overwrite it in the roundglyph. But the Glyph builder calls this method, and the call is aborted at Roundglyph.draw (), which may seem intentional. But check out the output:

Glyph () before Draw () Roundglyph.draw (), radius = 0 Glyph () after draw () Roundglyph.roundglyph ()
, radius = 5

When the Glyph Builder calls draw (), the radius value is not even the default initial value of 1, but 0. This could be caused by a dot or a screen with no painting at all. This will have to start looking for bugs in the program and try to find out why the program doesn't work.
The initialization sequence described in the previous section is not complete, and that is the key to solving the problem. The actual process of initialization is this:
(1) The storage space allocated for the object is initialized to binary zero before any other action is taken.
(2) Call the base class builder as described earlier. At this point, the overridden draw () method is invoked (indeed before the Roundglyph Builder call), and the radius value is found to be 0, as a result of step (1).
(3) Invoke the member initialization code in the order in which it was originally declared.
(4) invokes the body of the derived class builder.

One prerequisite for taking these actions is that everything should be initialized at least 0 (or some special data type and "0" equivalent), rather than just being left out as garbage. This includes embedding an object handle inside a class through a "compositing" technique. If you forget to initialize that handle, an offending event occurs during the run. Everything else becomes 0, which is usually a serious warning signal when viewing the results.
On the other hand, the results of this procedure should be vigilant. Logically, we seem to have made an airtight design, so it's a very strange mistake. And no error messages are received from the compiler (C + + will behave more reasonably in this case). Mistakes like this can be easily overlooked and take a long time to find out.
Therefore, a particularly effective rule when designing a builder is to get the object into a ready state in as simple a way as possible, and to avoid invoking any method if possible. The only security calls within the builder are those that have the final attribute in the underlying class (also applicable to the private method, which automatically has the final attribute). These methods cannot be overwritten, so there is no such potential problem.

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.