Hello guys,
Here is a second architecture change in the model/controller/view system
that will make our lives much easier when developing Elisa's user
interfaces.
It is a binding system remotely inspired from Cocoa that makes
relationships between models, controllers and views more declarative
than imperative.
Basically, it automatises transmission of properties across models and
controllers and controllers and views.
An example being more valuable than a thousand words, it goes like that:
Imagine you have a model and a view for books such as the following:
class BookModel(Model):
title = "an amazing story"
author = "joel the great"
class BookView(View):
def display_title(self, title):
self.label1 = title
def display_author(self, author):
self.label2 = author
Now you want to update BookView when modifications are made to the
'title' property of the BookModel.
* Without bindings, you do it like that:
- create a BookController that receives notifications of changes in
BookModel
- write glue code in it to replicate that attribute in BookController
and keep it up to date (remember that a View is notified exclusively of
changes happening in the Controller)
class BookController(Controller):
def attribute_set(key, old_value, new_value):
if key in ("title", "author"):
setattr(self, key, new_value)
- in the BookView you would need something similar:
class BookView(View):
def display_title(self, title):
self.label1 = title
def display_author(self, author):
self.label2 = author
def attribute_set(self, old_value, new_value):
if key is "title":
self.display_title(self, new_value)
elif key is "author":
self.display_author(self, new_value)
- plus in BookController and BookView you would also need some
initialisation code (the snippets above only take into account value
updates)
* With bindings, it is now as simple as that:
- create a BookController that declares what attributes of BookModel
should be bound to itself:
class BookController(Controller):
bindings = {"title": "title",
"author": "author"}
- do the same in BookView:
class BookView(View):
bindings = {"title": "label1",
"author": "label2"}
And voilĂ !
No code being required, that makes it easy to create a GUI to design the
bindings and change the behaviour. In the future, I expect future
improvements of this system such as:
- transformation of bound values (apply a transformation to the title
before passing it to the View)
- more than just attribute of self bindings; example: binding a value
directly from the Model to the View
Also this system is now used for children Controller and View creation.
Example: if the attribute bound is a Model then it will not be copied
over to the corresponding attribute but instead a new Controller will be
created and connected to the Model.
This change is backwards compatible but it is strongly advised to start
using the bindings system since it is a requirement for the soon to come
dynamic switching of controllers and views.
Florian