Java: Best practice - Callback vs member class - java

In Java, what code to call a method in a singleton would be better practice, and why?
Please note that the following code is psudocode, not necessarily compilable code.
I ask this, as Method 2 (calling a method directly) is easier to implement in code, but not as often seen from my experience.
I'm developing for Android, but I suppose this question could apply to any Java program.
Something happens in class B. A method in Class A must be called.
Method 1: Interface registered in ClassA is called from ClassB
public class ClassA
{
// Member class B object
ClassB mClassBObject = new ClassB();
// Singleton has a private constructor
private ClassA(){}
public void onCreate() // Or main, or whatever method...
{
// Set callback for ClassB
mClassBObject.setOnSomethingHappened
(
new OnSomethingHappened()
{
public void callback()
{
// Do something in Class A called in Class B
}
}
);
}
}
public class ClassB
{
// Registered member callback
OnSomethingHappened mCallback;
// Interface for callback
public interface OnSomethingHappened()
{
public void callback();
}
// Method to set callback for this object
public void setOnSomethingHappened(OnSomethingHappened callback)
{
mCallback = callback;
}
// A method that invokes the callback in Class A
private void someMethod()
{
if (mCallback != null)
{
mCallback.callback();
}
}
}
Method 2: Calling a method directly from ClassA in ClassB
// We could also call a static method, but in this example, we are assuming a Singleton.
public class ClassA
{
// Reference to self
private static mSelf;
// Singleton has a private constructor
private ClassA(){}
public void onCreate() // Or main, etc
{
mSelf = this; // Store a reference to this Singleton class
}
public void someMethod()
{
// Do something in ClassA
}
public static getSelf()
{
return mSelf;
}
}
public class ClassB
{
// Code...
private void someMethodInClassB()
{
// Get ClassA to call
ClassA classAObject = ClassA.getSelf();
if (classAObject != null)
{
// Call method in ClassA
classAObject.someMethod();
}
}
}

It really depends on which way you want the dependency chain to go. I'm going to generalize the pattern I think you're trying to describe.
I'm the second example, B depends on A. As you mentioned, this is simpler, since what we're trying to setup is exactly that relationship.
In the first example, A depends on B. Technically this could be written so that A and B both depend on C (the callback mechanism). This kind of setup is popular as it reduces coupling between the components (A and B), allowing more flexibility for future changes.
The way you have written it doesn't quite capture this reduction of coupling in a "best practice" sort of way though... You'll find good examples where B represents a library or third party component, and A is your code. Clearly the library can't depend directly on your code, so this style of dependency inversion is used.

Related

Why does calling a method from base class calls the child method?

I'm a student, learning Java. I know, protected means access from children or the same package. Here we inherit and override a protected method. And after such an action, whenever the base class wants to call its own method it calls the new overridden one from the subclass. I've been debugging this for a while and marked the execution order with comments. But I can't understand why doesn't it call the base method when I clearly call that from inside the base class constructor?
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public A() {
initialize(); // third
}
protected void initialize() {
System.out.println("class A"); // we never go here
}
}
public static class B extends A {
public B() {
super(); // second
initialize(); // fifth
}
protected void initialize() {
System.out.println("class B"); // fourth, sixth
}
}
}
That's a task from one website, so basically the solution is to change access modifier of the initialize method from protected to private. But I still fail to understand why is the problem happening.
What you're trying to do is defeat the purpose of polymorphism. You can, but you have to make the call specifically. Add a Boolean to your method and call the super.initialize(Boolean). Again, this defeats polymorphism and the extending class HAS to know about the super class. NOT VERY ELEGANT.
public class Solution {
public static void main(String[] args) {
new B(); // first
}
public static class A {
public static boolean USE_SUPER = true;
public A() {
initialize(USE_SUPER);
}
protected void initialize(boolean unusedHere) {
System.out.println("class A");
}
}
public static class B extends A {
public static boolean USE_EXTENDED = false;
public B() {
super();
initialize(USE_EXTENDED);
}
protected void initialize(boolean useSuper) {
if (useSuper)
super.initialize(useSuper);
else
System.out.println("class B");
}
}
}
As Dakoda answered, the root cause is polymorphism. That means we may create child objects, but refer to them as their parent type and when we call the methods of the parent layer we actually refer to the child's methods.
In my case, I create a child object (marked //first) B, which has its own body of the initialize method. One nuance of the inheritance is that it doesn't include constructors, so I can call the parent's constructor (marked //second). Inside the parent's constructor, I call the initialize method - that is the polymorphism because I call the method of the child from its parent abstraction layer.
Here is the answer to the question - this happens, because we only allocated memory for a B instance, that means, we took A as our base and started to extend it (while we can overwrite anything inside). The only two things we did are:
We created a constructor (it wasn't included in the base, as mentioned above)
We overwrote the initialize method code. The code for this method that is inside the base is now lost for this object.
This concept of polymorphism is designed that way and there is no way for us to access the base method unless we specifically create an object that is either A itself or a child that doesn't overwrite this method.

Java abstract class not working as expected [duplicate]

Excuse any minor syntax errors or whatnot, I'm experiencing this with a Jitsi module and not being super familiar with Java want to confirm what is going on and why and how it should be fixed.
public abstract class A
{
public A()
{
this.load();
}
protected void load()
{
}
}
public class B extends A
{
private String testString = null;
public B()
{
super();
}
#Override
protected void load()
{
testString = "test";
}
}
The application is doing this when creating an instance of the class B using a load class by name method:
Calls overridden load() in class B
Initializes variables (calls "private string testString = null" according to debugger), nulling them out.
Is this expected Java behavior? What could cause this? It's a Java 1.6 application running on the 1.7 JDK.
Is this expected Java behavior?
Yes.
What could cause this?
Your invocation of non-final overridden method in non-final super class constructor.
Let's see what happens step-by-step:
You create an instance of B.
B() calls super class constructor - A(), to initialize the super class members.
A() now invokes a non-final method which is overridden in B class, as a part of initialization.
Since the instance in the context is of B class, the method load() invoked is of B class.
load() initializes the B class instance field - testString.
The super class constructor finishes job, and returns (Assuming chaining of constructor till Object class have been finished)
The B() constructor starts executing further, initializing it's own member.
Now, as a part of initilization process, B overwrites the previous written value in testString, and re-initializes it to null.
Moral: Never call a non-final public method of a non-final class in it's constructor.
This is a common problem-pattern with initialization-on-construction, and can frequently be found in infrastructure code & home-made DAOs.
The assignment to 'null' is unneeded & can be removed.
If that's not enough as a quick patch, then: Move all the post-construction init to a separate method, and wrap it all in a "static method" pseudo-constructor.
And if you're doing DAO stuff, it's really good to distinguish between "load" and "create", since these are completely different instantiations. Define separate "static constructor" methods & perhaps separate internal inits, for these.
abstract public class A {
protected void initAfterCreate() {}
}
public class B {
#Override
protected void initAfterCreate() {
this.testString = "test";
}
// static constructors;
// --
static public B createB() {
B result = new B();
result.initAfterCreate();
}
}
Demonstrating load/create separation for a DAO:
public class Order {
protected int id;
protected boolean dbExists;
static public load (int id) {
Order result = new Order( id, true);
// populate from SQL query..
return result;
}
static public create() {
// allocate a key.
int id = KeyAlloc.allocate( "Order");
Order result = new Order( id, false);
}
// internal constructor; not for external access.
//
protected Order (int id, boolean dbExists) {
this.id = id;
this.dbExists = dbExists;
}
}

Calling method from constructor

Excuse any minor syntax errors or whatnot, I'm experiencing this with a Jitsi module and not being super familiar with Java want to confirm what is going on and why and how it should be fixed.
public abstract class A
{
public A()
{
this.load();
}
protected void load()
{
}
}
public class B extends A
{
private String testString = null;
public B()
{
super();
}
#Override
protected void load()
{
testString = "test";
}
}
The application is doing this when creating an instance of the class B using a load class by name method:
Calls overridden load() in class B
Initializes variables (calls "private string testString = null" according to debugger), nulling them out.
Is this expected Java behavior? What could cause this? It's a Java 1.6 application running on the 1.7 JDK.
Is this expected Java behavior?
Yes.
What could cause this?
Your invocation of non-final overridden method in non-final super class constructor.
Let's see what happens step-by-step:
You create an instance of B.
B() calls super class constructor - A(), to initialize the super class members.
A() now invokes a non-final method which is overridden in B class, as a part of initialization.
Since the instance in the context is of B class, the method load() invoked is of B class.
load() initializes the B class instance field - testString.
The super class constructor finishes job, and returns (Assuming chaining of constructor till Object class have been finished)
The B() constructor starts executing further, initializing it's own member.
Now, as a part of initilization process, B overwrites the previous written value in testString, and re-initializes it to null.
Moral: Never call a non-final public method of a non-final class in it's constructor.
This is a common problem-pattern with initialization-on-construction, and can frequently be found in infrastructure code & home-made DAOs.
The assignment to 'null' is unneeded & can be removed.
If that's not enough as a quick patch, then: Move all the post-construction init to a separate method, and wrap it all in a "static method" pseudo-constructor.
And if you're doing DAO stuff, it's really good to distinguish between "load" and "create", since these are completely different instantiations. Define separate "static constructor" methods & perhaps separate internal inits, for these.
abstract public class A {
protected void initAfterCreate() {}
}
public class B {
#Override
protected void initAfterCreate() {
this.testString = "test";
}
// static constructors;
// --
static public B createB() {
B result = new B();
result.initAfterCreate();
}
}
Demonstrating load/create separation for a DAO:
public class Order {
protected int id;
protected boolean dbExists;
static public load (int id) {
Order result = new Order( id, true);
// populate from SQL query..
return result;
}
static public create() {
// allocate a key.
int id = KeyAlloc.allocate( "Order");
Order result = new Order( id, false);
}
// internal constructor; not for external access.
//
protected Order (int id, boolean dbExists) {
this.id = id;
this.dbExists = dbExists;
}
}

Return a private class implementing an interface keeping the implementation private

Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO

Accessibility of variables and functions within my classes

I have 2 questions, but they are about the same (similar?) problem.
First question:
public class A {
public void myProcedure() {
doSomethingA();
}
private void doSomethingA() {}
}
public class B extends A {
#Override
public void myProcedure() {
doSomethingB();
// IT DOESN'T CALL super.myProcedure
}
private void doSomethingB() {}
}
public class C extends B {
#Override
public void myProcedure() {
// I need to execute A's myProcedure here
}
}
How to run A's myProcedure, without setting doSomethingA to public?
Second question:
I create my own TextBox, there is a variable named myValue. Now I create an AdvancedTextBox that inherits TextBox, and AdvancedTextBox need to access myValue variable. The problem is, I want future developer using both TextBox and AdvancedTextBox, or inherit them can't access myValue. Is it possible?
EDIT: Oli Charlesworth and NullUserException ఠ_ఠ tell me to let C inherit A directly (first question). However, there's some cases this can be disaster. For example: A = TextBox, B = AdvancedTextBox, C = NumberAdvancedTextBox, if C inherits A, so C have to do everything that B does again, with some small changes.
How about this ...
Put A and C in the same package, and then put B in a different package.
Remove "private" from A.doSomethingA()
Give C an instance of A. ( Favor Composition Over Inheritance )
Since C and A are in the same package, C can call A.doSomethingA() anytime.
Here is definition of A
package ac;
public class A {
public void myProcedure() {
doSomethingA();
}
void doSomethingA() {}
}
Here is definition of B
package b;
public class B extends A {
#Override
public void myProcedure() {
doSomethingB();
// IT DOESN'T CALL super.myProcedure
}
private void doSomethingB() {}
}
Here is definition of C
package ac;
// do you really need to extend B?
public class C {
A a = new A();
public void myProcedure() {
a.doSomethingA();
}
}
Since doSomethingA is an implementation detail. I would change it from a private to protected to allow subclasses to call it directly.
If some outside module calls A.myProcedure, it is not necessary for doSomethingA to be public. The other module is not calling doSomethingA directly, and that's all that matters. The deliberate intention of Java scope modifiers is that they only apply when you call a function DIRECTLY, not indirectly via another function. This way a class can have a small number of public functions that define the public interface. This can be carefully documented and very stable. Then these public functions can call any number of private functions, and you can freely shuffle these private functions around, say to improve performance, or to work with a new environment, etc, without having to change the public interface.

Categories

Resources