Xebozone
Xebozone

Reputation: 510

Java: Best practice - Callback vs member class

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();
        }
    }


}

Upvotes: 0

Views: 1168

Answers (1)

Krease
Krease

Reputation: 16215

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.

Upvotes: 1

Related Questions