The best way to maximize code reuse by avoiding inheritance and maintaining internalization

I am torn between several different OOP approaches to code reuse and code structure, and I cannot find a better option for my case.

Currently, I have a base class called "Plot" (plot of land) that handles the basic functionality of a standard type of chart and any other type of chart. So I decided that it makes sense to have any other type of Plot that uses the functionality of the main plot to extend the Plot. However, I now understand that there are many problems with this approach. Here is the current base structure of my code (in java):

public class Plot { public void doStuff() { // Do stuff for Standard plot type } } public class EstatePlot extends Plot { @Override public void doStuff() { // Make sure we still handle the base functionality (code reuse) super.doStuff(); // Make sure we also do stuff specific to the Estate plot type } public void extendedFunctionality() { // Do stuff that only applies to the Estate plot type } } 

I do not like this approach for several reasons.

  • There are times when I need to override a method to provide more functionality, but I do not want to execute all the code in the parent method. (i.e. no control or accuracy of code reuse)
  • There is a strong interaction between classes. (i.e., the base class Plot can have an undesirable effect on the behavior of any subclasses, since they are closely related. This is called the fragile problem of the base class).

Other reasons why I think this approach is impossible can be found here ( http://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html )

I was thinking about using Composition, but I realized that this is not very good, because I still need to override the functionality of the base Plot class.

So, at this point, I know that I should use interface inheritance over implementation inheritance. Perhaps I can make Plot an interface that defines the basic functions for all Plot types (Standard, Estate, Etc.). Now this is where I get stuck because I ran into the problem of reusing code. I don’t want to implement the same standard functionality for all types of Plot, so I thought about using a class of procedures (lets call it PlotHelper), which defined public static methods for processing many basic functions, taking into account the Plot object. Here is an example:

 public interface Plot { public void doStuff(); } public class StandardPlot implements Plot { @Override public void doStuff() { PlotHelper.handleStuff(this); } } public class EstatePlot implements Plot { @Override public void doStuff() { // Make sure we still handle the base functionality (code reuse) PlotHelper.handleStuff(this); // Make sure we also do stuff specific to the Estate plot type } public void extendedFunctionality() { // Do stuff that only applies to the Estate plot type } } public class PlotHelper { public static void handleStuff(Plot plot) { // Do stuff for Standard plot type } } 

My problem is that now the kernel functionality is no longer internalized. The bits and set of functions that are now found in public static methods in PlotHelper are shared in the base Plot class, which means more modular and internalized code.

So, now that you know where and why I am stuck, is there any preferred solution that avoids implementation inheritance and supports the internalization of type code? Or maybe you can think of a completely different approach that would be good for this case.

Thank you for your time!

+6
source share
2 answers

Abstract classes allow you to implement a method (code reuse) and declare abstract methods (interface inheritance).

Then you can implement the doStuff() method in the abstract Plot class and create an abstract method, for example doSpecificStuff() , which will be implemented in your PlotType .

 public abstract class Plot { protected void doStuff(){ //Implement general stuff for Plot }; abstract void doSpecificStuff(); } public class StandardPlot extends Plot { @Override public void doSpecificStuff() { // Make sure we still handle the base functionality (code reuse) doStuff(); //if needed. You can call standardPlot.doStuff() and then //standardPlot.doSpecificStuff(); // Make sure we also do stuff specific to the Estate plot type } public void extendedFunctionality() { // Do stuff that only applies to this plot type } } 

Abstract classes cannot be complicated, so you still need the StandardPlot class. doStuff() declaring doStuff() as protected , you guarantee that the method is called only by the Plot class and its subclasses.

+1
source

Perhaps the template template is applicable to you?

+1
source

Source: https://habr.com/ru/post/977186/


All Articles