From: "Tomas Jelinek" <tjelinek(a)redhat.com>
To: engine-devel(a)ovirt.org
Sent: Friday, January 25, 2013 11:55:43 AM
Subject: [Engine-devel] [engine-devel] frontend builders proposal
Hi All,
as many of you may know, the way how the frontend and backend models
are built on frontend (uicommonweb project) is not really ideal.
Currently this logic is copy pasted over and over again to different
places where it is needed with minor changes to fulfill the specific
requirements. It is not only aesthetically problematic, but I recall
tons of bugs caused by introducing a new field and forgetting to add
it to every place it is used in GUI.
Now, as there will be big changes in the VM/Template models
(
http://www.ovirt.org/Features/Instance_Types), so the way how the
VM, Template, Pool and also the newly created Instance Types models
are being built has to be touched anyhow, it is a great opportunity
to rethink the way how we do it.
I have created a simple infrastructure
(
http://gerrit.ovirt.org/#/c/10874/) which could be used for it, and
a PoC patch which uses this infrastructure
(
http://gerrit.ovirt.org/#/c/11354/). Please note that the PoC is
not really impressive in means of removing duplications, I wanted to
start with the simplest possibility.
The principles behind the infrastructure:
- have small, well named, easy to understand and reuse builders
- this builders can be chained together or embedded to each other to
build the full resulting object (composite pattern)
- this builders can be asynchronous, and the next builder in the
chain has to be executed only when the current is completely done
The structure:
- the base is an interface called Builder which has a method
build(source, destination, rest)
- the builder implementing this interface
+ will get the source and destination objects
+ copies whatever he wants from source to destination
+ when done, executes build on the first element of the rest
+ this may sound awkward, but this is the way how the async calls
can be "linearized" in a general way, not embedding anonymous
class into anonymous
class into anonymous class... as we do it today.
+ for synchronous builders, there is a BaseSyncBuilder which
takes care of this boilerplate calling of next and exposes a
simple method
build(S source, D destination)
+ to simplify the creating and running the chain of builders, there
is a BuilderExecutor class (can be created as sync or async)
So, a simple example - even more simple than the PoC patch :)
//create the first builder
class FirstLetterBuilder extends BaseSyncBuilder<String,
StringBuilder> {
@Override
protected void build(String source, StringBuilder destination) {
// copy the first letter to the destination
destination.append(source.charAt(0));
}
}
//create the second builder
class SecondLetterBuilder extends BaseSyncBuilder<String,
StringBuilder> {
@Override
protected void build(String source, StringBuilder destination) {
// copy the second letter to the destination
destination.append(source.charAt(1));
}
}
// usage
...
// create the destination object
StringBuilder res = new StringBuilder();
// configure the executor with the two builders
BuilderExecutor<String, StringBuilder> executor = new
BuilderExecutor<String, StringBuilder>(
new FirstLetterBuilder(),
new SecondLetterBuilder()
);
// execute the builder chain ("ab" is the source, res the
destination)
executor.build("ab", res);
// use the result
...
That's it. And the nice part is, that this FirstLetterBuilder and
SecondLetterBuilder can be reused anywhere or combined with any
other builders.
Any comments on this will be more than welcome!
great and really simplifies work and eliminate bugs resulted from copy/past code
gave +1
Thanks
Eli
Thank you,
Tomas
_______________________________________________
Engine-devel mailing list
Engine-devel(a)ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-devel