Removing interfaces from your code, whether they're done explicitly (e.g., Java's interface
construct) or implicitly (e.g., a C++ abstract class), removes your ability to take advantage of some forms of inheritance. (I say "some forms" because in general terms, interfaces are equivalent to abstract classes but are treated differently by different languages.)
Take this example, written in no particular language:
class Juice { ... }; // Represents any kind of juice.
interface Fruit {
Boolean is_edible();
Juice make_juice();
};
class Apple implements Fruit {
Boolean is_edible() { return true; }
Juice make_juice() { ... ; return juice; }
}
class Banana implements Fruit {
Boolean is_edible() { return true; }
Juice make_juice() { ... ; return juice; }
}
// Processes and accumulates the juices of many fruits.
class Juicer {
Vector<Juice> accumulated_juice; // Where all the juice goes
// Process a Fruit for consumption. Complain if it's
// not an edible fruit.
Void process(Fruit f) {
if ( ! f.is_edible() ) throw_exception;
accumulated_juice.add(f.make_juice());
}
}
This is pretty straightforward. The Juicer
can process()
any Fruit
you hand it because the interface guarantees that:
- There's an
is_edible()
method determine if the Fruit
is edible
- There's a
make_juice()
method to produce the juice
You can develop a Kumquat
or a Mango
or a StarFruit
and you'll never have to modify the Juicer
to understand them. Juice is juice.
If you remove interfaces, all of that simplicity goes away:
// Assume same class declarations as above without "implements xxx" clause.
class Juicer {
Vector<Juice> accumulated_juice; // Where all the juice goes
// Process a Fruit for consumption. Complain if it's
// not an edible fruit.
Void process_apple(Apple a) {
if ( ! a.is_edible() ) throw_exception;
accumulated_juice.add(a.make_juice());
}
Void process_banana(Banana b) {
if ( ! b.is_edible() ) throw_exception;
accumulated_juice.add(b.make_juice());
}
// Add methods for additional fruits here.
}
All of the process_xxx()
methods are identical except for what type they take as an argument. Even though Apple
and Banana
have methods called is_edible()
and make_juice()
with identical signatures, the language won't just let you call them by name because they're part of different classes. This means your Juicer
has to have more code added every time you develop a new fruit.
Once this grows to more than these few classes, it becomes a maintenance nightmare if you need to make changes to how the process()
method works internally. Further, any other code that handles your fruits has to have all of this additional code
HTH.
For example: What's the role of commonly used IEventDispatcher. What if this class was not created. Would it be very difficult to use Eventdispatcher ?
– Vishwas Dec 15 '12 at 17:47