Question

I'm trying to convince a colleague that a function should take an interface as a parameter, and not the object itself. I think small objects can be fine to pass across, but for large ones I would give them an interface and just pass the i/f over, not the whole thing.

Note that there will only ever be one of these large classes - the i/f will never be used for a different object. This is merely for hiding the implementation of an object.

Would you agree that separating a large class into an interface(s) is good practice?
Are there any disadvantages to doing this?

Example:

public interface class IVeryLargeClass
{
    void DoSomething();
    ...
};

public ref class VeryLargeClass : public IVeryLargeClass
{
public:
    virtual void DoSomething() { ... }
    ...
};

public ref class AnotherClass
{
public:
    AnotherClass(VeryLargeClass^ vlc)  { vlc->DoSomething(); }
 // OR
    AnotherClass(IVeryLargeClass^ vlc) { vlc->DoSomething(); }
};
Was it helpful?

Solution

One of the first principles you learn in OO development:

Program to an interface, not an implementation.

You indicate that "there will only ever be one of these large classes - the i/f will never be used for a different object". This might be true in your case, but I wish I had a nickel for every time such a statement turned out to be wrong.

In addition to considering whether there might be multiple implementations of your interface, you should also consider whether your concrete object exports (or might export) additional methods that do not share a logical affinity with the operations declared in the interface. In such a case, you could simply declare the additional operations in one or more additional interfaces. A client, then, need only couple with the interface that exports the operations in which it is interested.

Put simply, interfaces provide a means of managing the coupling between clients and providers.

OTHER TIPS

The Dependency Inversion Principle can be summed up as: It is better to depend on abstractions than concretions.

It's almost always better to pass an interface than it is to pass a concrete class.

That said, high cohesiveness against internal types is ok within a particular module, but that's very subjective as to when and how you should pass concrete objects.

I'd prefer to avoid creating and interface for the sake of creating an interface. If you can use that interface in more than one place, then you have a winner - or if this is a public function and class and you specifically want to simplify.

If you pass an implementation, you kind of loose one of the advantages of using interfaces, meaning separating the logic from the actual implementation.

The interface of a software module A is deliberately kept separate from the implementation of that module. The latter contains the actual code of the procedures and methods described in the interface, as well as other "private" variables, procedures, etc.. Any other software module B (which can be referred to as a client to A) that interacts with A is forced to do so only through the interface. One practical advantage of this arrangement is that replacing the implementation of A by another one that meets the same specifications of the interface should not cause B to fail—as long as its use of A complies with the specifications of the interface (see also Liskov substitution principle).

http://en.wikipedia.org/wiki/Interface_(computer_science)

The other issue is your very large class itself. This may not be within the scope of what you're doing, but a very large class implies that it might be doing too much in the first place. Can you refactor it into smaller classess, where the information required within the function you're calling is encapsulated in its own smaller class? If you create an interface against that class you may find it that much more re-usable than against the very large class you currently have.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top