Best way of dealing with a common/central object



I have a program where I need to read and write data to a common (central?) object from most other obejcts. In a way it acts like a database or perhaps databus if you like. I cannot write it to a file. Currently I do it like this:

class A {
    private Common common;
    private B b;
    
    public A() {
        common = new Common();
        b = new B(common);
    }
}

class B {
    private Common common;
    private C c;

    public B(Common common) {
        this.common = common;
        c = new C(common);
    }
}

class C {
    private Common common;
    private D d;

    public C(Common common) {
        this.common = common;
        d = new D(common);
    }
}


...etc.

So I am passing the object “down the line” but it feels wrong doing it like this (given the amount of objects I am getting to). Is there a better way of doing this?

Edit: Class A can be instantiated multiple times, so Common is only common for all the objects in each individual A.

Answer

The real answer is “don’t”.

You can use the Singleton pattern; but, by doing so you are avoiding “object oriented programming” which is the method that Java uses to make the programs maintainable and repairable.

Once you have a single, central object, you can’t modify your code easily in many ways without investigating how the central object is impacted, and then investigating how all the other objects that also use the central object are impacted through the central object.

Instead create an object for each scenario. This allows you to process two scenarios at a time, which will make life easier when you start to make your programs multi-threaded, something you’ll want to do sooner or later, because otherwise you’ll only use 1 core in that 8 core processor.

Your language assumes a central object, so I can’t provide an example in your scenario. I’ll modify Commmon to Context where Context means “the scenario I’m dealing with now”.

Note that with such a change, you probably shouldn’t own the context, you should pass it along.

class A {
    private B b;
    
    public A() {
        b = new B();
    }

    public handle(Context context) {
        context.add(...whatever...);
        b.handle(context);
    }
}

class B {
    private C c;

    public B() {
        c = new C();
    }

    public handle(Context context) {
        context.remove(...whatever...);
        context.add(...something else...);
        c.handle(context);
    }
}

class C {
    private D d;

    public C() {
        d = new D();
    }

    public handle(Context context) {
        context.do(...whatever...);
        d.handle(context);
    }
}

The way to call this is now

Context c1 = new Context();
Context c2 = new Context();
A a = new A();
a.handle(c1);
a.handle(c2);

And as you can see, there’s no longer a need for a single “central” class.

Fitting the problem into the language, or selecting the language for the problem is a learned skill. Please avoid Singleton, as it is a hard learned anti-pattern, one that hurts software maintainability.

If you wrote all of your code with Singletons, the code could easily be ported into a non-object oriented language (like C, FORTRAN, etc) because Singletons are syntatic sugar for “global scope, with slightly better name spaces”. The reason that C++, Java, etc became popular was due to the easier code maintenance of structuring code into Objects.



Source: stackoverflow