How to solve the fragile base class with helper methods - java

I have understood the fragile Base class problem, and I know that we can solve it using Composition over Inheritance or declaring private method in the superclass.
Now I'm trying to understand how to solve this problem using helper method, so I will put the classic code of fragile base class and then I will put my solution with helper method, tell me if I do something wrong please.
This is the code of a fragile base class (from wikipedia)
public class JavaApplicationProvaHello {
public class A {
private int i;
public void inc1(){
i++;
}
public void inc2(){
inc1();
}
}
//---------------------------
public class B extends A{
#Override
public void inc1(){
inc2();
}
}
//------------------------
public class Test{
public static void main(String[] args) {
B b = new B();
b.inc1();
}
}
}
Now I change the class A and put two private helper methods which will be called by the public method inc1 and inc2
public class A {
protected int i;
public void inc1(){
inc1Helper();
}
public void inc2(){
inc2Helper();
}
private void inc1Helper(){
i++;
}
private void inc2Helper(){
inc1Helper();
}
}
In my compiler everything works, I was asking myself if this is the best solution to solve fragile base class with helper methods. Thank you for the attention.

"Best" is an opinion.
In my opinion, a better answer would be to leave a Javadoc comment on inc2() stating that it calls inc1().
/** Increments <code>i</code> by calling <code>inc1()</code> */
public void inc2()
...
Then anyone who extends A can see that in the documentation. If they miss it, then they will know when they look at the stack trace for their stack overflow exception.
This way still requires a few lines in the file but requires no more actual lines of functional logic code and no more generated byte code. The very Wikipedia article you mention suggests (and for Java, nonetheless) documentation as one of the answers.

Related

Template Method: How to use it when you want to be able to flexibly change primitive options?

The problem is best explained with the following code:
public class TemplateClass {
public void templateOne() {
checkConditionA();
primitiveOp1();
checkConditionB();
}
public void templateTwo() {
checkConditionA();
primitiveOp2();
checkConditionB();
}
protected abstract void primitiveOp1();
protected abstract void primitiveOp2();
// rest of the methods
}
Now I have code duplication with templateOne() and templateTwo(), but I would like to have just one template method but with interchangeable primitive operations.
What you want is, in essence, a guard block around a method call. DRY programming is good practice, but be advice that you do not wawnt to couple what should not be coupled. I would only couple those two methods if it is guaranteed that they must always be guarded by the same pre- and postcondition(s).
If this is the case, I would recommend to implement a method private void callWithChecks(Runnable primitiveOperation) and then pass the respective primitive operation as parameter to this method:
public abstract class TemplateClass {
public void templateOne() {
callWithChecks(this::primitiveOp1);
}
public void templateTwo() {
callWithChecks(this::primitiveOp2);
}
private void callWithCkecks(Runnable primitiveOperation) {
checkConditionA();
primitiveOperation.run();
checkConditionB();
}
protected abstract void primitiveOp1();
protected abstract void primitiveOp2();
// rest of the methods
}
If you do not want to use the function interface Runnable, you can of course define your own interface. I went with it, since it is a Java base class.
Two remarks on your code:
TempalteClass must be declared abstract, otherwise the code will not compile
If you intend to implement methods checkConditionA() and checkConditionB() within TemplateClass, I would recommend defining them as private or final such that they cannot be overridden.

Importing two utility classes with same name. Feature or useless?

For two utility classes with the same names, which contain only static methods, I proceeded as follows:
Simply imported the first
Created an instance of the second class.
Example:
package util1;
public class Utility {
public static void method() {
System.out.println("First Utility. static method");
}
}
package util2;
public class Utility {
public static void method() {
System.out.println("Second Utility. static method");
}
}
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = new util2.Utility();
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I don't need to write a full second util-class name for invoke its methods, but maybe I did not foresee something...?
P.S:
The methods of the class Component are called through a reflection by a certain BlackBox. All the multithread-safe features are in BlackBox.
UPD: I have found better trick:
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = null; // There are some changes
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I dont create new object, but is it possible to use it without any bugs?
IMO, this is confusing and could much more clearly be handled by something like:
public class CombinedUtilityComponent {
public static void usedByReflection() {
util1.Utility.method();
util2.Utility.method();
}
}
Or, better yet, in your code you can just fully qualify the class names and they become unique names without any confusing tricks.
Yes, this works. I wouldn't do it, though.
You're calling a static method as if it were an instance method. anotherUtility.method() has a useless reference to anotherUtility.
You also have an unnecessary instantiation of util2.Utility. This technique wouldn't work if the default constructor were disabled.

Best way to pass a variable from outer class to inner class

I'm building an android app (but this is not important for the post) and I'm writing a method called scrollUntilSelectedAvatar() that contain a class:
public class AvatarManager {
private HorizontalScrollView avatarPageHorizontalScrollView;
//mehod that contains the inner class
public void scrollUntilSelectedAvatar(HorizontalScrollView avatarPageHorizontalScrollView){
this.avatarPageHorizontalScrollView = avatarPageHorizontalScrollView;
avatarPageHorizontalScrollView.post(new Runnable() {
#Override
public void run() {
AvatarManager.this.avatarPageHorizontalScrollView.scrollTo(100, 0);
}
});
}
}
My question is: what's the correct way to access avatarPageHorizontalScrollView (that I pass to the method as an argument) inside the inner class new Runnable().
The way I found (AvatarManager.this.avatarPageHorizontalScrollView) doesn't seems the best way.
Thank everybody for the help :)
The way you did it - is the one and only correct. Syntax of some thing about inner classes may seem quite strange. But it is just like it is.
public class A {
private int a;
private abstract class B {
public abstract void printA();
}
public B makeB() {
return new B() {
#Override
public void printA() {
System.out.println(A.this.a);
}
};
}
}

Reflection VS static stuff

Recently I've been restructuring a Java code of mines trying to eliminate, wherever possible, static stuff (variables and methods) and replace it with better coding practices.
I also started studying reflection and noticed that it allows me to do some things1 that, at first, I could only achieve (or, at least, that's how I see it) with static calls or references.
However, while I've been reading that the use of static is not much recommended, it doesn't seem to be the same with reflection.
So, I'm asking: instead of making a method static and calling it like ClassName.methodName(), is it a legitimate use of reflection making it an instance method and invoking it by java.lang.reflect.Method.invoke()?
1 like dynamically accessing a class' content
Here's a code sample:
Hypothetic situation that works (but I don't want to make the method static):
import static java.lang.System.out;
public class Foo
{
private static boolean light;
public Foo()
{
turnOn();
}
public static void turnOn()
{
light = true;
}
public static void turnOff()
{
light = false;
}
public static boolean isGreenLight()
{
return light;
}
}
public class Boo
{
public Boo()
{
if (Foo.isGreenLight()) // I need to access Foo.isGreenLight() from here, but cur-
{ // rently that method is not static (it should be to do so)
out.println("Ok!");
}
}
}
public final class Main
{
public static void main(String[] args)
{
final Boo boo = new Boo();
}
}
Hypothetic situation that also should work (how it'd be using reflection):
import static java.lang.System.out;
import java.lang.reflect.Method;
public class Foo
{
private boolean light;
public Foo()
{
turnOn();
}
public void turnOn()
{
this.light = true;
}
public void turnOff()
{
this.light = false;
}
public boolean isGreenLight()
{
return this.light;
}
}
public class Boo
{
public Boo()
{
if ((boolean) Class.forName("Foo").getMethod("isGreenLight", null).invoke(new Foo(), null))
{
out.println("Ok!");
}
}
}
public final class Main
{
public static void main(String[] args)
{
final Boo boo = new Boo();
}
}
Expected output (untested):
Ok!
Using reflection is a code smell, especially if the intent behind what you're writing does not warrant it.
It is difficult to say much more without seeing code as it's all just guesswork.
I would:
enumerate the reasons behind why you had those static members in the first place
determine if the static modifier was in fact the right decision in the first place: i.e. should these be instance or class members? How might they be used by "clients" of the classes in question? What paradigm am I using? Functional or Object Oriented code. Does it satisfy DRY, SOLID and KISS programming practices?
consider if I'm over-engineering in the first place
More importantly:
I would design my code through tests first, which drives the design of your API through the eye of the user, with the added benefit that you have test coverage before you've even implemented. Often times when writing code this way I eliminate such questions because the solution is more obvious when thought from the perspective of a user rather than a designer. It becomes a question of pragmatism rather than satisfying architectural design goals and philosophies.

How to use reflection to get a constructor where you are passing in a super class as a paremeter

Today while coding I began a deep dive into the world of reflection. I have messed with it in small bits and pieces before but never to this extent and no matter where I look I can find no answer to my question and so here I am! Currently what I am trying to do is use reflection with a class whose constructor requests a parameter but for ease of use I wish to use the super class of the parameter.
Here is the code causing problems with some explanations:
this.listener = (MyListener) listenerClass.getConstructor(MyAppState.class).newInstance(this);
The thing is that MyAppState is the class that all of my appstates extend from and each listener takes in its own specific AppState that extends MyAppState but has extra features different from each other. What I need to know is what I can put in my .getConstructor() to specify that the class I am passing in is the super of the parameter it wants.
Here is a theoretical example of the code:
this.listener = (MyListener) listenerClass.getConstructor(Class extends MyAppState.class).newInstance(this);
So is this possible or should I just work with my code to have a second constructor that accepts the MyAppState class, or something else along those lines.
Also, sorry if this is off topic but to prevent problems in the future, I am being told this question is subjective. Is there any way to word future questions to not be as subjective or is the method to figure out whether the question is subjective just a bit flawed?
[EDIT] As requested, a few more examples related to the question:
public MyAppState(Node screen, Class listenerClass)
{
this.screen = screen;
try
{
this.listener = (MyListener) listenerClass.getConstructor(MyAppState.class).newInstance(this);
}
catch (Exception e)
{
Logger.getLogger(MyAppState.class.getName()).log(Level.SEVERE, "The listener for the {0} appstate could not be created using reflection.", new Object[]{this.getClass().getName()});
System.exit(-1);
}
}
Above is the full parent class's constructor, the said class extends one more class but it contains no constructor and so I am not sure if it is needed. If it is please feel free to ask for it.
public class OptionsMenuState extends MyAppState
{
public OptionsMenuState()
{
super(new Node("Options Screen"), OptionsMenuStateListener.class);
}
That is one class and its constructor with pieces cut off to keep it short.
public class MainMenuState extends MyAppState
{
public MainMenuState()
{
super(new Node("Start Screen"), MainMenuStateListener.class);
}
Here is another class and its constructor.
[EDIT] As suggested, I created a program that roughly mimics what I am attempting to do.
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
//This is what I want to do but I don't know how to have java allow me to pass in Greeting.
createObject(SimpleSentence.class);
createObject(DifferentSentence.class);
}
public static void createObject(Class theClass)
{
theClass.getConstructor(Greeting.class).newInstance(new Hello());
}
class SimpleSentence
{
Hello firstWord;
public SimpleSentence(Hello word)
{
firstWord = word;
}
}
class DifferentSentence
{
Howdy firstWord;
public DifferentSentence(Howdy word)
{
firstWord = word;
}
}
class Greeting
{
}
class Hello extends Greeting
{
}
class Howdy extends Greeting
{
}
}
Short answer is you can't. getConstructor(Class<?>...parametertypes) is very explicit because it needs to match exactly zero or one constructor only.
You will need to go through all the constructors to find one, that has a parameter that is assignable from MyAppState
e.g. outline:
final Constructor<?>[] ctrs = listenerClass.getConstructors();
for (Constructor<?> constructor : ctrs) {
if (constructor.getParameterTypes()[0].isAssignableFrom(MyAppState.class)) {
// use this one?
}
}

Categories

Resources