Maximize the reusability of code and overcome the disadvantages of traditional object-oriented programming method in reusability

Source: Internet
Author: User
Programming | Object      Reuse is a myth that seems to be becoming a common understanding among programmers. However, reuse can be difficult to implement because traditional object-oriented programming approaches have some drawbacks in terms of reusability. This tip describes the three steps that make up a different method of supporting reuse.   First step: Move the function out of the class instance method because of the lack of accuracy of the class inheritance mechanism, it is not an ideal mechanism for code reuse. That is, if you want to reuse a single method of a class, you must inherit the other methods of the class and the data members. This redundancy unnecessarily complicates the code that will reuse this method. The dependency of an inheriting class on its parent class introduces additional complexity: changes to the parent class affect the subclass, and it is difficult to remember which methods are overwritten (or which methods are not overwritten) when you change either side of the parent class or subclass, and it is not clear whether the corresponding parent class method should be invoked. Any method that performs a single conceptual task should be independent and should be used as the preferred method to reuse. To do this, we must go back to programming, move the code out of the class instance method and move it into the globally visible process. To improve the reusability of such processes, you should write such methods as writing static utility methods: Each procedure completes its work using only its own input parameters and/or calls to other global visible procedures, and no non-local variables should be used. This weakening of external dependencies reduces the complexity of using the process, which can facilitate its reuse elsewhere. Of course, even code that does not plan to reuse can benefit from this structure because its structure is always quite clear. In  Java , methods cannot exist out of class. However, you can take steps to make the method a publicly visible static method of a single class. As an example, you can use a class similar to the following: class polygon {. Public int getperimeter ()  {...} Public boolean isconvex ()  {...} Public boolean containspoint (point p)  {...} and change it to a form similar to the following: class polygon {. Public int getperimeter ()  {return ppolygon.computeperimeter (this); Public boolean isconvex ()  {return ppolygon.isconvex (this);} Public boolean containspoint (point p)  {return ppolygon.containspoint (this, p);} The,ppolygon  is shown below: Class ppolygon {static public int computeperimeter (Polygon  polygon)  {...} Static public boolean isconvex (Polygon polygon)  {...} Static public boolean containspoint (polygon polygon, point p)  {...}} The class name  pPolygon  reflects that the process encapsulated by the class is primarily related to the object of type  Polygon . The  p  in front of the class name means that the only use of the class is to organize the public visible static process. However, it is not normal for class names to begin with lowercase letters in  Java , and classes like  pPolygon  do not complete the usual class functions. This means that it does not represent a class of objects; it is just an organizational entity required by the language. The full effect of the changes in the above case is that the client code no longer has to reuse its functionality by inheriting  Polygon . This functionality is now provided in the  pPolygon  class in a process-by-unit basis. The client code uses only the functionality it needs without having to worry about features that it does not need. This does not mean that the class will not play an active role in the new procedural programming style. On the contrary, classes perform the necessary grouping tasks and encapsulate the data members of the objects they represent. In addition, the class has excellent reusability by implementing multiple interfaces with polymorphism, see the instructions in step two. However, you should classify methods that derive reusability and polymorphism through class inheritance into lower-priority technologies, because incorporating functionality into an instance method is not the best choice for achieving reusability. Four-person-co-authored bestseller  design patterns  briefly mentions a technology that is only subtly different from the technology. The  Strategy  model in that book advocates the encapsulation of each family of related algorithms with a common public interface so that client code can interchange these algorithms. Because an algorithm is usually written as one or several separate processes, this encapsulation emphasizes reusing the process of performing a single task (that is, an algorithm) without emphasizing the reuse of objects that contain code and data and perform multiple tasks. This step also embodies the same basic idea. However, using an interface encapsulation algorithm means that the algorithm is written as an object that implements the interface. This means that we are still tied to the process of data coupling and other methods of encapsulating the object, thus making reuse more complex. It is also a problem to instantiate these objects each time the algorithm is used, which reduces the performance of the program. Fortunately,, design patterns  offers a solution that solves both problems. You can use  Flyweight  mode when writing  Strategy  objects so that each object has only one well-known shared instance (the instance handles execution issues). So that each shared object does not maintain state between two accesses (so the object does not contain any member variables, thus resolving many coupling problems). The generated  Flyweight-Strategy  mode is highly integrated into the globally available stateless process of encapsulating the functionality in this step. Step two: Convert an input parameter type of a non-basic data type to an interface type inheritance of polymorphism through an interface parameter type rather than through a class, which is the real basis for reusability in object-oriented programming methods, as  Allen Holub  in   " Build user interfaces for object-oriented systems, part 2 "  said. "...  reusability is achieved by writing an interface, not by writing a class." If all parameters of a method are references to well-known interfaces that are implemented by classes that you have never heard of, the method can manipulate objects of classes that do not yet exist when you write code. Technically, the reusable method is not the object passed to the method. "Apply  Holub  's discussion to the results of the first step, and once a feature block can be used as a globally visible stand-alone process, you can further improve its reusability by converting each of its class-level input parameter types to interface types." In this way, the realObjects of any class that now have the interface type meet the requirements of the parameter, not just the requirements of the original class. In this way, the process can potentially be used for more object types. For example, suppose you have a static method that is globally visible: Static public boolean contains (rectangle rect, int x,  int y)  {...} This method is designed to determine whether a given rectangle contains a given position. Here you should change the type of the  rect  parameter from class type  Rectangle  to the interface type, as follows: Static public boolean contains (Rectangular rect, int x, int y)  {...} Rectangular could be the following interface:public interface rectangular  {rectangle getbounds ();} Now, objects that can be described as  Rectangular  classes (which can implement  Rectangular  interfaces) can be passed to   as parameters of  rect  Prectangular.contains (). We can improve the reusability of the method by relaxing the constraint on the parameters that can be passed to the method. However, for the above example, when the  getBounds  method of the  Rectangle  interface returns a  Rectangle , you may not know the use of   What is the real benefit of the rectangular  interface, that is, if we know that the object we want to pass in is returned  Rectangle; why not pass in the  Rectangle  type to the interface type? The most important reason is related to the collection. Suppose there is such a method: Static public boolean areanyoverlapping (collection rects)  {...} This method is designed to determine whether  rectangular  objects in a given set overlap. Next, in the method body, when you process each object in the collection in turn, how can you access the  rectangle  of that object if you cannot convert the object to an interface type such as  Rectangular ? The only option is to convert the object to a specific class type (we know that there is a method in the class that provides  rectangle), which means that the method must be aware of what class type it is going to operate on, so it can be reused only with these types. This is the first step to avoid the problem! Step three: Select an input parameter interface type with less coupling what type of interface should you choose to override the given class type when performing the second step? The answer is: any interface that can adequately describe the requirements of the process for parameters and the least burdensome. The smaller the interface the parameter object is to implement, the greater the chance that any particular class can implement the interface  --  thus the number of classes to which the object can be used as the parameter. It is easy to see if you have such a method as: Static public boolean areoverlapping (window window1, window  Window2)  {...} This method is designed to determine whether two (assuming  rectangular) Windows overlap, if the method only requires its two parameters to provide their respective  rectangular  coordinates, It is best to simplify the types of these two parameters to reflect this fact: static public boolean areoverlapping (rectangular rect1,  RECTANGULAR RECT2)  {...} The above code assumes that the previous  Window  type object can also implement  rectangular. You can now reuse the functionality contained in the first method of any  rectangular  object. You may have many times that the available interfaces that fully specify the parameter requirements contain too many unnecessary methods. When this happens, you should define a new public interface in the global namespace so that other methods that may face the same dilemma reuse the interface. You may also have many times that it is best to create a unique interface to specify the requirements of a single process for a parameter. The interface you create is used only for that parameter.This often happens when you want to treat a parameter as a function pointer in  C , for example, assuming there is a process: Static public void sort (list list,  sortcomparison comp)  {...} This procedure sorts a given list by using the given comparison object  comp  comparing all the objects of the list,sort  the whole requirement for  comp  is to invoke its single method to perform the comparison. So,sortcomparison  should be an interface that contains only one method: Public interface sortcomparison {boolean comesbefore ( OBJECT A, OBJECT B);} The only purpose of this interface is to provide  sort  with a way to access the functionality required to complete its work, so  SortComparison  should not be reused elsewhere. The above three steps are designed to improve existing code written with more traditional object-oriented methods. Using these three steps in conjunction with object-oriented programming, you can build a new approach that you can use to write code later, so writing code will improve the reusability and cohesion of the method, as well as reduce the coupling and complexity of the methods. Obviously, you should not perform these steps on code that is inherently unsuitable for reuse. This code usually exists at the presentation level of the program. The creation of code for the user interface of the program and the binding of input events to the control code that completes the actual operation are two examples that are not reusable, because their functionality varies greatly from program to process and is simply not possible to achieve reusability.

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.