[Ekiga-devel-list] Design of the engine : why abstract Ekiga::Foo and Ekiga::FooImpl matter



Hi,


this mail is meant to explain why having two classes doesn't make the code more complex just for the sake of it, but because it brings nice features.


The fact that Ekiga::Foo is purely abstract means :

1. that anyone trying to write an instance of it, say Bar::Foo, will get notified by the compiler if they forget to implement one of the methods, or if they mispell one of them -- the compiler is helpful!

2. that anyone trying to write a very specific implementation is completely free to do so, as the abstract class is, well, abstract ;

3. that anyone trying to write an implementation with no special needs can just inherit Ekiga::FooImpl and be done!


So when writing new code, the presence of two classes doesn't get in the way, and even gets the compiler to help : that is a bonus.


Now, now... we decide that Ekiga::Foo is too weak and add a method. This immediately :

1. breaks Ekiga::FooImpl, which immediately gets fixed ; of course it also breaks every class inheriting from Ekiga::FooImpl, but they all get fixed at the same time -- and the fix can only be correct (more on that later) ;

2. breaks every class inheriting from Ekiga::Foo, and the compiler says so : the code won't compile as-is, someone will have to have a look at all classes with very specific needs, and write correspondingly specific implementations, so everything is correct.


And that's all : we made sure we either had all methods reimplemented or none -- no in-between! So when modifying existing code, the presence of the two classes ensures that the compiler will push every problem explicitly under our eyes : there will be no silent break.


Compare with a situation where Ekiga::Foo has naive implementations of everything directly in the base class:

1. Anyone writing an instance of Ekiga::Foo with an overriden populate_memu (where the base had populate_menu) will have a hard time knowing they made a typo : the compiler won't catch it. Silent break!

2. Anyone writing an instance of Ekiga::Foo may implement only two thirds of the method, get something which won't run, but will gladly compile. Silent break!

3. Anyone writing an instance with very specific needs will find the variables used by the base class implementation in the way : if they want to put some information in a 'tokens' variable the base class said was a list of strings, but should now be a list of Bar::Token, will need to name it my_tokens, but "tokens" will still take some room, and if they forget a my_ somewhere, the compiler might not complain if they don't use string/Bar::Token-specific api. Silent break!

4. You've been lucky : you only reimplemented populate_menu, and kept the other base implementations because they fit. Someone modifies the base implementation (added a method and made the default implementations follow : all nice and clean!). Your code still compiles, but of course, won't work. Silent break!


I think the purely abstract Ekiga::Foo and Ekiga::FooImpl is better : it is more expensive, but you do get what you paid for.


Snark


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]