I am torn between several different OOP approaches to code reuse and code structure, and I cannot figure out the best option for my case.
Currently, I have a base class called 'Plot' (a piece of land) which handles the core functionality of a standard plot type and any other plot type. So I figured it would make sense to have any other Plot type that uses the core plot functionality to extend Plot. However, I am now realizing that there are many downfalls to this approach. Here is the current basic 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.
More reasons why I think this approach is undesireable can be found here (http://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html)
I thought about using Composition, but I realized that this was not a good option either because I still need to override functionality of the base Plot class.
So at this point, I know I should use interface inheritance over implementation inheritance. Perhaps I can make Plot an interface that defined the core functionality for all Plot Types (Standard, Estate, Etc.). Now this is where I am stuck because I am faced with the issue of code reuse. I do not want to implement the same standard functionality for all Plot types, so I thought about using a sort of procedure class (lets call it PlotHelper) that defined public static methods to handle a lot of the core functionality given a 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 with this is that now the core functionality is no longer internalized. The bits and pieced of functionality that is now in the public static methods in PlotHelper used to be handled together in the base Plot class which meant more modular and internalized code.
So finally, now that you know where and why I am stuck, is there any preferred solution that avoids implementation inheritance and maintains internalization of type specific code? Or perhaps you can think of a completely different approach that would be great for this case.
Thanks for your time!
Abstract classes allows you to implement a method (Code reusability) and declare abstract methods (Interface inheritance).
You can then implement a doStuff()
method in your Plot
abstract class and create an abstract method like doSpecificStuff()
to 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 can't be instantiated tough, so you'll still need a StandardPlot
class. Also declaring doStuff()
as protected
you ensure that the method is called only by Plot
class and it's subclasses.
Maybe Template Pattern would apply to you?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With