Remove duplicate code blocks of overridden methods in Java - java

My project must comply by contract with all the sonarqube static analyzer rules (to my immense delight).
As shown in the picture I have a base class which is derived n time, and each derived class is derived a second time.
All my DoubleDerived classes override the methods foo1(), ..., fooM() generating n duplicate code blocks of size O(M) lines of code
class DoubleDerivedX extends DerivedX {
#Override
public void foo1() {
...
}
...
#Override
public void fooM() {
...
}
}
Currently my code violates the common-java:DuplicatedBlocks rule for this reason, as far as I can tell (I can't find official documentation about this) the analyzer consider a code block duplicated if it consists of three or more methods and if it is present in multiple file.
It is actually possible to remove the duplicated blocks of code, if yes how?
A trivial solution would be to use multiple inheritance, with a BaseDoubleDerived class derived from Base and from which the n DoubleDerived class derive, but it cannot be implemented in Java.
Edit: The Base and Derived classes are domain classes while the DoubleDerived classes are lazy loading Proxies that fetch data from repositories. The fact is that I can pretty much feel that this is a XY problem but I'm so close to the deadline that I know I don't have probably the time to implement the "right" solution.

Edit: They may say that I don’t believe in ‘if’ anymore is the object-oriented battle song (well, actually they don’t, I just made this up). if statements still have their place.
public class Base {
private boolean needsFooImplementationsForDoubleDerivedClasses;
public void foo() {
if (needsFooImplementationsForDoubleDerivedClasses) {
// DoubleDerivedX foo() implementation here
} else {
// Base foo() implementation here
}
}
}
Now control the value of needsFooImplementationsForDoubleDerivedClasses through constructor arguments. Like this:
class DoubleDerivedX extends DerivedX {
public DoubleDerivedX() {
super(true);
}
}
Original answer
One option is: put the common implementation for double derived classes in a separate method in the base class. Base and single derived classes will not need it and just ignore it.
public class Base {
public void foo() {
// Base foo() implementation here
}
protected void fooImplementationForDoubleDerivedClasses() {
// DoubleDerivedX foo() implementation here
}
}
So your double derived classes only need to do
class DoubleDerivedX extends DerivedX {
#Override
public void foo() {
fooImplementationForDoubleDerivedClasses();
}
}
Depending on your situation putting the common implementation in the base class may feel natural or unmotivated. In the latter case you may also look for a different shared place for it, but assuming that the method needs access to protected parts of Base, moving it out of Base may not be trivial.

Seems like this a candidate for composition over inheritance. If you can enclose the duplicated method in its own class, and invoke it via instances held in the DoubleDerivedX classes, that would eliminate the code duplication. But for that to work, a lot depends on how enmeshed the method is with the rest of the class (which could be an indication there are deeper issues that need addressing).

Related

Way to split big class and fix chain inheritance?

I had a big class, Admin, which had too many separate methods with different functionality and calls to a database and it was getting quite hard to manage, so I decided to split it, but now Admin is somewhat useless. I want to have Admin inherit all the smaller classes but the only way I can think of is through chain inheritance like so:
public class Admin extends A {
//code in here
}
public class A extends B {
//code in here
}
public class B extends C {
//code in here
}
None of the methods that are in B are used in A, but I want to use them in Admin. It feels like bad practice, but I don't know how to implement it in another way.
Is there a way to better create this class, without having to put every method from the classes in Admin
If you have cross-object behavior, which is not inherited through the current inheritance tree, you should isolate (decouple) this behavior from the tree, and make it inject-able according to needs. You can start by defining an interface which describes these behaviors and implement it whenever a particular object has a these.
For instance you can have:
public interface Capable{
public void doThis();
public void doThat();
}
And say B should have this behavior specification but not A, you can just do:
public class B extends A implements Capable {
//some other stuff
public void doThis(){..}
public void doThat(){..}
}

`public` modifier in package-private classes

Recently, I was writing a class that I decided to be package-private (that is, no access modifier, or the default one). It has an inner class and some private helper methods, and one method intended to be used by a class in the same package. All of these class members are static. But then I had a thought: should this one method have the public access modifier or no access modifier, like the class containing it?
On one hand, since the class itself is package-private, it can only be accessed and used within its package, so there is no practical reason to make the method public. But at the same time, semantically, this method is intended to be a public feature of the class, that is, a feature of the class intended to be used externally, so it would make sense to modify its access as such.
For those that like to see code,
final class DummyRemover {
private DummyRemover() {
}
public static int remove(Map<String, ClassNode> classMap) {
return 0;
}
// ...
}
or,
final class DummyRemover {
private DummyRemover() {
}
// Notice the modifier.
static int remove(Map<String, ClassNode> classMap) {
return 0;
}
// ...
}
What is the best choice here? Is there a rule of thumb for deciding what access modifiers to use in a case like this?
There are two reasons why a method should have a higher visibility than its enclosing class:
1. The enclosing class is a base class
... which is intended for extension by subclasses, which might eventually be public, and the method at hand is supposed to be publicly available. E.g.
abstract class Base {
public void x() {}
}
public class Sub extends Base {
}
// Now, everyone can call:
new Sub().x();
usually, however, if this is your intention, you will declare your method x() in an interface anyway. Even if you don't declare x() in an interface, design-wise, it's probably better to keep the base method at the same visibility level as its class, and "open up" the method in the subclass, as that will communicate intent more clearly:
abstract class Base {
void x() {}
}
public class Sub extends Base {
/** public Javadoc here */
#Override
public void x() {
super.x();
}
}
I don't see any reason why this approach should be applied to static methods as in your case.
2. The method must be public
... because it implements a method from an interface. Unfortunately, Java doesn't offer package-private or private interface methods. So the following is usual, even without any subclasses, and even if the interface itself might be package-private (or even nested private):
final class Y implements X {
#Override
public void x() {}
}
This (unfortunately) also applies to static classes on interfaces, which can only be public:
interface I {
/* implicitly public */ static void x() {}
}
There are two schools of thought on this:
One group prefers adding unnecessary modifiers (e.g. public in this case, private in private classes) as a form of "documentation in code". For example, this is the viewpoint Eric Lippert espouses in his answer on this related C# question.
The other group prefers to never add source code that has no functional effect: if public isn't doing anything then it doesn't belong in your source code.
I think I am now firmly in the second camp, but I understand the arguments from the first camp and I think it's not nearly as cut and dried as it might first appear. Reasonable people can disagree, which is why (like braces and whitespace) this is something you should decide once in a project style guide and then never debate again. :-)
I personally think that making the method public might be misleading to the reader.
On the other hand, it supports extensibility (If the class should ever be made public, the change is easier).
Whenever I need to choose between readability and extensibility, I go for the YAGNI principle and choose readability.
See wiki for more about YAGNI: https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it

How to inherits/uses methods from multiple classes

Current I have a base class that contains project init and teardown method, and some large number of common methods, and these methods are inherited/used by its subclasses.
Because the based class is getting huge, so I am trying to move these common methods into newly created classes to improve the modularity of the project. And the original base class inherits the methods from those newly created classes. (multiple inheritances?)
Is there any suggestion to refactor this? also need to minimize the impact to the subclasses.. minimal code changes will be perfect..
Base class
-method1()
-method2()
-method3()
-method4()
-method5()
-method6()--------
| |
| |
subclasse1 subclass2
First of all, there is no multi inheritance of classes (only multi inheritance of interfaces) in java.
However in java 8 you can write default implementations of interface methods (see "Default Methods" on docs.oracle.com). But there are some restrictions:
You still can't declare fields in a interface
If you have 2 default implementations of the same method in different interfaces, you still need to override them.
You may be better off using the adapter pattern, i.e. refractor your code to something like this:
public class BaseClass {
private final Adaptee1 adaptee1;
private final Adaptee2 adaptee2;
// ...
public BaseClass(Adaptee1 adaptee1, Adaptee2 adaptee2 /* , ...*/) {
this.adaptee1 = adaptee1;
this.adaptee2 = adaptee2;
//...
}
public BaseClass() {
this(new ConcreteAdaptee1(), new ConcreteAdaptee2() /* , ...*/)
}
public void method1() {
adaptee1.method1();
}
public void method2() {
adaptee1.method2();
}
public void method3() {
adaptee2.method3();
}
public void method4() {
adaptee2.method4();
}
// ...
}
public interface Adaptee1 {
void method1();
void method2();
}
public interface Adaptee2 {
void method3();
void method4();
// ...
}
//...
public class ConcreteAdaptee1 implements Adaptee1 {
//...
}
public class ConcreteAdaptee2 implements Adaptee2 {
//...
}
//...
You could even pass the adapter to the adaptees in the method calls, if you need access to methods in other adaptees as well for example.
But you should check first, if the class can be split into multiple classes in a good way (i.e. the adaptees should be independent). Don't split the class into parts at all cost. If you can't make the adaptees independent, you should keep it as a single class and rely on your IDE instead to navigate the code easier (Code folds, bookmarks, ...)
In Java, one class cannot extend multiple other classes, however it can implement as many interfaces as you'd like. Unfortunately, implementing an interface will not provide the methods you need.
As far as I could think this out, you have the following options:
1) If you don't want to change all your references to the Base class, and the Base class has some methods that are really broad and may apply to many classes, you could put those into one class and have your base class extend that one.
example:
public class SuperBaseClass{
method1()
method2()
method3()
}
public class BaseClass extends SuperBaseClass{
method4()
method5()
method6()
}
You could even create a SuperDuperBaseClass which SuperBaseClass extends to continue the chain as far as you'd like. The problem with this technique is it forces a hierarchical structure to your project.
2) You could split the Base class into multiple other base classes (I would recommend this one). Sort out your methods into categories and put them in appropriately named base classes. For example, throw all your methods which crunch numbers into one class named Algorithms. Put all your methods which tie other classes and functionalities from your project into one class called Tools. Do this until your whole project is sorted. It will clean everything up as much as possible and keep things manageable in the future. The problem with this is you will have to change everywhere the Base class used to be referenced.
3) You could just leave the Base class as it is. Since it's only a supporting file, you shouldn't really have to be digging through that code very often, so it won't hold you back too much that this file gets a little messy.

Java: Is there a way to you enforce a implementation of private methods?

I have 5 or 6 classes that I want to have follow the same basic structure internally. Really most of those that the classes should follow are just for the use of the function itself, so I really want these methods to be private.
Is there any way to achieve this? I know interfaces would work great but they won't take private members and won't allow you to redefine the scope in the implemented method. Is there any workaround for this?
Thanks
I think the closest you can get is using an abstract class with abstract protected methods:
abstract class A {
protected abstract void foo();
}
class B extends A {
protected void foo() {}
}
To define common logic, you can call the protected method from a private method in the super class:
abstract class A {
private void bar() {
// do common stuff
foo();
}
protected abstract void foo();
}
This way, you can allow subclasses to fill the private common template method with specific behavior.
Create an abstract base class that outlines the structure and common flow. Specify abstract methods for the steps in the flow that must be implemented by the inheriting classes.
Hmm, private functions can't be called by any other classes, even by subclasses. So what's the point in having private functions with the same name in different classes?
There is no way to enforce it at compile time, but you can write a unit test or a simple program to test for the existence of the methods using reflection.
I assume you are doing this to make the classes consistent for aesthetics/design reasons. If you are doing it for some other reason you should really use the abstract protected way others are suggesting.
Here is some code to get you started on such a tool/unit tests (you should improve the error messages at the very least, and I would really suggest unit tests rather then what I have here):
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Main
{
public static void main(String[] args)
{
check(B.class, Modifier.PRIVATE, void.class, "doit", new Class<?>[] { int.class });
check(C.class, Modifier.PRIVATE, void.class, "doit", new Class<?>[] { int.class });
}
private static void check(final Class<?> clazz,
final int modifiers,
final Class<?> returnType,
final String name,
final Class<?>[] params)
{
try
{
final Method method;
method = clazz.getDeclaredMethod(name, params);
if(method.getModifiers() != modifiers)
{
System.out.println("modifiers do not match");
}
if(method.getReturnType() != returnType)
{
System.out.println("return type does not match");
}
}
catch(final NoSuchMethodException ex)
{
System.out.println("could not find method");
}
}
}
interface A
{
void foo();
}
class B
implements A
{
public void foo()
{
doit(0);
}
private void doit(final int x)
{
}
}
class C
implements A
{
public void foo()
{
doit(0);
}
private int doit(final int x)
{
return (5);
}
}
Create an outline 'common' class, with all your private methods on them.
Then create your 5 or 6 classes , each which have a field on there of type 'common'.
You won't be able to call the private methods of course (but you say these are really internal to the class) - you'll have to advertise some public methods to alter state as well of course.
public class common {
private method1() { ; }
private method2() { ; }
public other() { ; }
...
}
public class myclass1 {
common commonMethods;
}
public class myclass2 {
common commonMethods;
}
or even (assume 'common' is defined as above):
public class template {
common commonMethods;
}
public class myclass1 extends template {
...
}
So you get a (package-protected) 'commonMethods' field for 'free' on each of 5 or 6 subclasses.
After subsequent discussion on this thread, it appears the author doesn't actually want to share logic : just method signatures essentially , so this answer doesn't fit with that requirement.
While the interface methods themselves must always be public, you could make the interface package private and keep all of your Car (for example) implementations in the same package.
package com.some.car.pkg;
interface Car
{
public void gas();
public void brake();
}
Even though the methods are public, it doesn't matter since outside of the package com.some.car.pkg, Car is not visible. This way, all of your implementers would not be forced to extend an abstract class. The fact that you want common methods means truly private isn't the real solution, and IMHO, you want an interface, since it sounds like in your case an abstract class isn't quite right as there is no shared logic.
My 2 cents.
The "throw MethodNotImplementedException();" might be a useful construct.
If abstract protected really isn't protected enough, I wonder what the concern is. In any case, an alternative similar to monojohnny's would be to use the strategy pattern. This ensures that:
derived classes must define the behavior
derived classes can't access the behavior after defining it
instances can't access one another's behavior
E.g., with apologies for borrowing the car metaphor despite no automotive chops:
public interface GearBoxStrategy {
public void changeGear(int newGear);
}
abstract public class Car {
private GearBoxStrategy gearBox;
public Car(GearBoxStrategy g) {
this.gearBox = g;
}
public void accelerate(double targetSpeed) {
int gear = getTargetGear(targetSpeed):
gearBox.shift(gear);
}
}
public class AutomaticTransmissionCar {
public AutomaticTransmissionCar() {
super(new AutomaticTransmissionGearBoxStrategy());
}
}
public class ManualTransmissionCar {
public ManualTransmissionCar() {
super(new ManualTransmissionGearBoxStrategy());
}
}
Create an abstract base class with a method marked final that describes the common flow that includes your private methods. Marking it as final means that it can't be extended by subclasses and thus the business logic is enforced as long as your calling code utilizes it. Extension points can be created by marking methods as protected. For example say you have a class that represents a retail store.
private final void doTransaction() {
float amountDue;
// a protected or abstract method that extenders can override
Collection items = this.unloadShoppingCart();
for (Object item : items) {
// another protected or abstract method
amountDue += this.getPrice(item);
}
// your private method
amountDue += this.getSalesTax(amountDue);
}
Is it possible to make all the classes inherit from the same base class?
If so, one thing you could consider would be at runtime in the base class's constructor use reflection to validate that the subclass is following the rules you describe, and throw an exception if it fails your validation rules.
The naive implementation of this test of course would have significant performance issues, so you'd have to be pretty clever about the way you implement the test.
For a start, the test should only be run once for all instances of a particular subtype T. So, you would have to cache the validation information somewhere. One way to do this would be to use some kind of static (global) hash table in the base class keyed on the type of each subtype.
You would also have to perform some kind of thread safe synchronization around this cache. What you really need to avoid on this is a performance hit for reads. What I've done in a similar case before was use a combination of the double check locking pattern and the use of an immutable hashtable so that you only take a performance hit for locking when attempting to write to the hashtable (i.e. when you create the first instance of a particular subtype T).
I'm actually not experienced in Java, what I describe, I implemented in .NET, which is why I can't provide you with a code example, but all the concepts should be easily transferable to Java - everything I mention is (AFAIK) available on both platforms.
Take a look at XDepend, it uses reflection to create a database based on your compiled code.
http://www.xdepend.com
It's aimed at software architects who wish to be able to quickly check potentially large libraries of compiled code for potential problem areas. It has inbuilt reports and visualization for such things as relationships between classes, cyclomatic complexity, coupling etc. etc.
In addition, it includes an inbuilt sql like query language "CQL" (for "code query language"). Using CQL you can define your own reports. You probably should be able to use it to define a report for violations of the rules you describe. Also, you can embed CQL queries directly into your code using annotations.
I haven't looked into it, but have used it's .NET equivalent 'NDepend', and it's a very cool tool.
Of course, you could also write your own custom tool which uses reflection to check your specific rules. XDepend may still be worth looking at though - it should be a lot more flexible.
Here's an idea: write a simple text parser to check for the existence of the methods. Include it as a task in Ant. As long as you are insisting on some form of coding standard, some simple text-matching should do it, ie, simply look for the formatted signature in the required source files.
In a comment you wrote "Yes that is the whole point. I know they can be called different things but I don't want them to be."
Now, some people might just say "that's impossible" but like most things in programming, it's not actually impossible, it's just a lot of work.
If you really want to do this, you can create a custom Java Annotation for your class and then write an Annotation processor and call apt as part of your build process.
Like I said a lot of work, but it might be worthwhile if you want to learn how Annotations work.
Writing annotations is actually pretty simple. They work kind of like regular classes. For example, if you just want to mark a class for some reason you can create an empty or marker annotation like this
public #interface Car { }
Then in your Annotation Processor you can check to make sure Car has the right private methods.
I've written my own annotations, but I checked them at Runtime using the reflection API, rather then at build time. They are actually pretty easy.

Is it possible to hide or lower access to Inherited Methods in Java?

I have a class structure where I would like some methods in a base class to be accessible from classes derived directly from the base class, but not classes derived from derived classes. According to the Java Language specification it is possible to override access specifications on inherited methods to make them more public, but not more private. For example, this is the gist of what I need to do, but is illegal:
// Defines myMethod
public class Base {
protected void myMethod() {}
}
// Uses myMethod and then hides it.
public class DerivedOne extends Base {
#Override
private void myMethod();
}
// can't access myMethod.
public class DerivedTwo extends DerivedOne {
}
Is there any way to accomplish this?
Edited to explain why I would like to do this:
In this case the class structure is a data handling and import structure. It reads in and parses text files full of tabular data and then stores them in a database.
The base class is the base table class managing the database handling part of it. There is a fair amount of functionality contained in it that is common to all table types - as once they are in the database they become uniform.
The middle class is specific to the kind of table in the file being parsed, and has the table parsing and import logic. It needs access to some of the base class's database access functions.
The top level class is specific to the table and does nothing more than initialize the table's layout in a way the parent classes can understand. Also users of the base class do not need to see or access the database specific functions which the middle class do. In essence, I want to reveal these functions only to one level above the base class and no one else.
I ask because, although the code I posted as an example is illegal, there may be some other means to accomplish the same end. I'm asking if there is.
Perhaps hiding is the wrong way to phrase this - what I really need to do is expose some functionality that should be private to the base class to the class one level up in the hierarchy. Hiding would accomplish this - but I can see how hiding would be a problem. Is there another way to do this?
I think the very nature of the problem as you've posed it exposes conceptual problems with your object model. You are trying to describe various separate responsibilities as "is a" relationships when actually what you should be doing is describing "has a" or "uses a" relationships. The very fact that you want to hide base class functionality from a child class tells me this problem doesn't actually map onto a three-tiered inheritance tree.
It sounds like you're describing a classic ORM problem. Let's look at this again and see if we can re-map it onto other concepts than strict "is a" inheritance, because I really think your problem isn't technical, it's conceptual:
You said:
The base class is the base table class
managing the database handling part of
it. There is a fair amount of
functionality contained in it that is
common to all table types - as once
they are in the database they become
uniform.
This could be more clear, but it sounds like we have one class that needs to manage the DB connection and common db operations. Following Single Responsibility, I think we're done here. You don't need to extend this class, you need to hand it to a class that needs to use its functionality.
The middle class is specific to the
kind of table in the file being
parsed, and has the table parsing and
import logic. It needs access to some
of the base class's database access
functions.
The "middle class" here sounds a bit like a Data Mapper. This class doesn't need to extend the previous class, it needs to own a reference to it, perhaps injected on the constructor or a setter as an interface.
The top level class is specific to the
table and does nothing more than
initialize the table's layout in a way
the parent classes can understand.
Also users of the base class do not
need to see or access the database
specific functions which the middle
class do. In essence, I want to reveal
these functions only to one level
above the base class and no one else.
I'm not clear why a high-level class seems to have knowledge of the db schema (at least that's what the phrase "initialize the table's layout" suggests to me), but again, if the relationship between the first two classes were encapsulation ("has a"/"uses a") instead of inheritance ("is a"), I don't think this would be a problem.
No. I'm not sure why you'd quote the spec and then ask if there's any way to do the opposite of what the spec says...
Perhaps if you explain why you want to do this, you could get some suggestions on how.
When overriding a method you can only make it more public, not more private. I don't know why you use the word "general"
Remember that, ordering from least to most restrictive:
public<protected<default<private
Yes, "protected" is a less restrictive access modifier than default (when no modifier is used), so you can override a default method marking the overriding method as protected, but not do the opposite.
Can:
You can override a protected method with a public one.
Can't:
You can't override a public method with a protected one.
If you did this then DerivedOne would not be a Base, from the DerivedTwo's point of view. Instead what you want is a wrapper class
//Uses myMethod but keeps it hidden
public class HiddenBase {
private final Base base = new Base();
private void myMethod();
public void otherMethod() {base.otherMethod();}
}
You can't access protected methods of the base though this way...
What you describe comes close to what the protected access class is for, derived classes can access, all others cannot.
If you inherit from base classes you have no control over this might pose a problem, you can make the method inaccesible to others by throwing an exception while making the inherited code available to your classes by calling super directly, something like:
// Uses myMethod and then hides it.
public class DerivedOne extends Base {
#Override
public void myMethod() {
throw new IllegalStateException("Illegal access to myMethod");
}
private void myPrivateMethod() {
super.myMethod();
}
}
Edit: to answer your elaboration, if I understand you correctly you need to specify behaviour in the context of the base class which is defined in the middle class. Abstract protected methods won't be invisible to the classes deriving from the middle class.
One possible approach is to define an interface with the methods you would need to be abstract in the base class, keeping a private final reference in the base class and providing a reference to the implementation when constructing the middle class objects.
The interface would be implemented in a (static?) nested inside the middle class. What I mean looks like:
public interface Specific {
public void doSomething();
}
public class Base {
private final Specific specificImpl;
protected Base(Specific s) {
specificImpl = s;
}
public void doAlot() {
// ...
specificImpl.doSomething();
// ...
}
}
public class Middle extends Base {
public Middle() {
super(new Impl());
}
private Impl implements Specific {
public void doSomething() {
System.out.println("something done");
}
}
}
public class Derived extends Middle {
// Access to doAlot()
// No access to doSomething()
}
Inheritance works because everywhere you can use the base class, you can also use one of it's subclasses. The behavior may be different, but the API is not. The concept is known as the Liskov substitution principle.
If you were able to restrict access to methods, the resulting class would not have the same API and you would not be able to use substitute an instance of the base class for one of the derived classes, negating the advantage of inheritance.
What you actually want to accomplish can be done with interfaces:
interface IBase1 {
}
class Derived1 implements IBase1 {
public void myMethod() {
}
}
class Derived2 implements IBase1 {
}
class UseMe {
public void foo(IBase1 something) {
// Can take both Derived1 and Derived2
// Can not call something.myMethod()
}
public void foo(Derived1 something) {
something.myMethod();
}
public void foo(Derived2 something) {
// not something.myMethod()
}
}
It is possible, but requires a bit of package manipulation and may lead to a structure that is a bit more complex than you would like to work with over the long haul.
consider the following:
package a;
public class Base {
void myMethod() {
System.out.println("a");
}
}
package a;
public class DerivedOne extends Base {
#Override
void myMethod() {
System.out.println("b");
}
}
package b;
public class DerivedTwo extends a.DerivedOne {
public static void main(String... args) {
myMethod(); // this does not compile...
}
}
I would recommend being nice to yourself, your co-workers and any other person that ends up having to maintain your code; rethink your classes and interfaces to avoid this.
you have to make method final when override it
public class Base {
protected void myMethod() {}
}
// Uses myMethod and then hides it.
public class DerivedOne extends Base {
#Override
final protected void myMethod(); //make the method final
}
public class DerivedTwo extends DerivedOne {
// can't access myMethod here.
}

Categories