Together with Jürg, the Vala man and Murray, who before becoming a pregnant guy was and still is coding on things like Glom and gtkmm, I’ve been writing up a document. This document explains iterators like the ones you’ll find in .NET and Java.
This is related to the Iterators concept because the document about iterators could be part of a solution for this.
I once had to write a custom GtkTreeModel (I think I still suffer from vertigo) and therefore I sent treeview Kris an analysis about this.
There’s a rule that an interface should be a contract for solving exactly one problem.
Use interfaces to say “What objects can do” or “What can be done to an object”. You can let a class implement multiple interfaces. There’s absolutely no need to make huge interfaces. An interface should define that your class “Does One Thing”. Another interface defines that your class “Does Another Thing, too”, and a last interface defines that your class “Also Does This”. My class Z can do D, E and F. Therefore: class Z implements D, E and F.
Instead, the contract being GtkTreeModel requires you to solve five problems:
- being iterable: you can go to the next node
- being a container: you can add and remove things from it
- being observable: it notifies a component about its changes
- being a tree: sometimes items can parent other items
- having columns: it’s something that describes columns
Summarizing: interface TreeModel means BEING a D, E, F, G and H at the same time. Correct would be if you specified that TreeView requires a model that does D, does E and perhaps also does F. In case treeview is showing the things as a tree, it requires that the model also does E and does H.
GtkTreeModel should have been five different interfaces.
Shocking! But in my opinion, true.
The consequence is that having to implement a GtkTreeModel has become a difficult task.
“You have to implement solutions for all five problems anyway!”, you might think. That’s true. However! If there were five interfaces, other people would have made default solutions for four other interfaces. Meanwhile “you” focus on “your” specialization. For example Rhythmbox and Banshee are specialized in huge models that contain a specific set of data that must be searchable. Preferably search and sort are done by a database instead of a model-filter.
Banshee and Rhythmbox developers:
- … don’t have to care about the Columns problem
- … don’t have to care at all about the Tree problem
- … don’t have to care about the Container problem: they never need to add nor remove things from it because they set up their model instantly by passing a query to a data source. Maybe the feature “remove from playlist” requires solving the Container problem?
- … unless they support inotify on the MP3 folder of the disk, they don’t even have to care about the observer problem
Yet with GtkTreeModel you have put the burden on application developers to solve all five the problems in their model. No wonder Banshee developers decide to code their own TreeView in .NET!