views:

83

answers:

5

I am doing the design of a small project where I didn't use programming against interfaces for all my classes. I found that some classes would hardly ever be needed to change, so I let them be referenced by their client classes as concrete classes.

So, let's say we have ClassB that'll be consumed be consumed by ClassA:

alt text

class ClassB {
}

My question is, should I create ClassB in ClassA, or should I pass that responsability "up" in the hierarchy? I'll depict both cases:

class ClassA {
    private ClassB classB;

    public ClassA() {
        this.classB = new ClassB();
    }
}

or

class ClassA {
    private ClassB classB;

    public ClassA(ClassB classB) {
        this.classB = classB;
    }
}

I'd like to hear about how would you do it and what'd be the rationale behind it!

Thanks

+3  A: 

It depends on the implementation, there is no general answer. If A has all the relevant data and knowledge to initialize B, then it could initialize it.

If you don't want A to know how to initialize B or you don't want to give A all the data for the initialization, then you should create it externally.

testalino
Seems like a good heuristic to follow.
devoured elysium
+2  A: 

you'd better inject interface which implemented by ClassB.

class ClassA {
private InterfaceB B;

public ClassA(InterfaceB B) {
    this.B = B;
}
}
class classB: InterfaceB
{
}

Please note that InterfaceB may be a regular class as base class for your derived ones. In this case it still works as interface.

Arseny
Yes, but I think you are missing my point. I don't want to bloat my code with basically 1 interface for each concrete class if I am not going to need that much flexibility. Maybe am I wrong thinking this way? I'm just trying to balance the project "complexity" and flexibility.
devoured elysium
@devoured well when your injection makes no difference. It would be the same as classB is a private member. Idea of DI is to be independent from concrete realization of depended classes.
Arseny
To use an interface instead of a concrete class is not going to blow up the complexity of your implementation. But it will allow you to be more flexible. This way, you do not create dependency between the classes which is hell to refactor afterwards.
Yoann
+1  A: 

In the former A is taking the full responsibility of class B instantiation. So, there is nothing which can go wrong. A knows B like anything. In case A wants few of the B properties to be set before invoking any method on it. It can do that by setting those just after intialisation.

In the latter, A can't be that sure of B.

Now, the choice is of course yours.

Adeel Ansari
A: 

i would suggest that , you can use delayed construction of your dependencies using Setter based Injection.

class ClassA
{
    private ClassB classB;

    public ClassA()
    {

    }
    public ClassB MyDependency
    {
        get
        {
             // Make it thread safe if you plan to use this dependency via multiple threads
            if (classB == null)
            {
                classB = new ClassB(); 
            }

            return classB;
        }
    }



}


class ClassB
{
}

in this way , you can ensure that Dependency is only created whenever it is needed.

saurabh
That, in the context of the original post, solves nothing. The question is about who has the responsability of creating classB, not on whether there are eager or lazy creation necessity. That is just adding unneeded complexity.
devoured elysium
Do you understand what is mean by the term "Dependency of a component" ?
saurabh
+3  A: 

Some advantages of your first option (A creates B):

  1. The user of class A needs to know nothing about B or how to create & configure it. This makes for a simpler programming model.
  2. B can also be made private/internal, so that users of your library don't need to wade through lots of helper classes they don't need to see.
  3. You can change the way A works to not use B at all without breaking calling code.
  4. Encapsulation - no one gets to tamper with B from the outside while A is running

Some advantages of your second option (A takes a dependency on B):

  1. The user of class A has full control over the B object - they can configure it differently, they can pass the same one into multiple instances of A if they want.
  2. It opens the door for different implementations to be passed in (if B is an interface or base class) which is of great value for unit testing, or extensibility.

Note that it is also possible to create a "best of both worlds" solution by using what is sometimes called "poor man's dependency injection":

class ClassA {
    private ClassB classB;

    public ClassA(ClassB classB) {
        this.classB = classB;
    }

    public ClassA() : this(new ClassB()) {

    }
}
Mark Heath