[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! Thank you, Tomas

----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: engine-devel@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@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel

----- Original Message -----
From: "Eli Mesika" <emesika@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org Sent: Saturday, January 26, 2013 10:58:57 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: engine-devel@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
Hi guys, I agree that this refactoring can significantly help us reduce code complexity, there is another issue that your suggestion doesn't address, but we may want take the opportunity to address it if we are already considering refactoring for this code: this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic. Thanks, Gilad.
Thank you, Tomas _______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel
_______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel

this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic. Not sure if I have understood you correctly - do you mean moving the frontend logic (e.g. visibility of fields according to some selection) and also the frontend models to the server? I would say it is better to have this on FE.
However having the validations common between FE and BE would be great. We could prepare a different patch for this. ----- Original Message ----- From: "Gilad Chaplik" <gchaplik@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org, "Eli Mesika" <emesika@redhat.com> Sent: Monday, January 28, 2013 5:08:41 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal ----- Original Message -----
From: "Eli Mesika" <emesika@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org Sent: Saturday, January 26, 2013 10:58:57 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: engine-devel@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
Hi guys, I agree that this refactoring can significantly help us reduce code complexity, there is another issue that your suggestion doesn't address, but we may want take the opportunity to address it if we are already considering refactoring for this code: this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic. Thanks, Gilad.
Thank you, Tomas _______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel
_______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel

----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: "Gilad Chaplik" <gchaplik@redhat.com> Cc: engine-devel@ovirt.org Sent: Wednesday, January 30, 2013 11:11:41 AM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
[adding missing part from the thread]
I agree that this refactoring can significantly help us reduce code complexity, there is another issue that your suggestion doesn't address, but we may want take the opportunity to address it if we are already considering refactoring for this code:
this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic. Not sure if I have understood you correctly - do you mean moving the frontend logic (e.g. visibility of fields according to some selection) and also the frontend models to the server? I would say it is better to have this on FE.
IMHO, we should uiqeury (or something similar) or uiplugin (or striving towards it), that get the entire dialog data (with /without ui). I'm not sure what is the benefit with your refactoring, can you elaborate on that? but let see what others think.
However having the validations common between FE and BE would be great. We could prepare a different patch for this.
I think that common validations are nice to have, and it is least of our problems.
----- Original Message ----- From: "Gilad Chaplik" <gchaplik@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org, "Eli Mesika" <emesika@redhat.com> Sent: Monday, January 28, 2013 5:08:41 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
----- Original Message -----
From: "Eli Mesika" <emesika@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org Sent: Saturday, January 26, 2013 10:58:57 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: engine-devel@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
Hi guys,
I agree that this refactoring can significantly help us reduce code complexity, there is another issue that your suggestion doesn't address, but we may want take the opportunity to address it if we are already considering refactoring for this code: this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic.
Thanks, Gilad.
Thank you, Tomas _______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel
_______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel

----- Original Message ----- From: "Gilad Chaplik" <gchaplik@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org Sent: Wednesday, January 30, 2013 11:42:22 AM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal ----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: "Gilad Chaplik" <gchaplik@redhat.com> Cc: engine-devel@ovirt.org Sent: Wednesday, January 30, 2013 11:11:41 AM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
[adding missing part from the thread]
I agree that this refactoring can significantly help us reduce code complexity, there is another issue that your suggestion doesn't address, but we may want take the opportunity to address it if we are already considering refactoring for this code:
this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic. Not sure if I have understood you correctly - do you mean moving the frontend logic (e.g. visibility of fields according to some selection) and also the frontend models to the server? I would say it is better to have this on FE. IMHO, we should uiqeury (or something similar) or uiplugin (or striving towards it), that get the entire dialog data (with /without ui). I'm not sure what is the benefit with your refactoring, can you elaborate on that? The plan is to decouple the FE from the BE more in the future by changing the current API to call the REST. My patch is actually a step to this direction because we will not be able to use the backend models anymore and will need to use DTOs. If we will have the building logic centralized, it will be much more simple to refactor them to use the new DTOs. Any coupling with the server (like getting the dialog data instead of business data) is a step from the moving to generic REST API, and since this is a long term plan, I would be very careful.
but let see what others think.
However having the validations common between FE and BE would be great. We could prepare a different patch for this.
I think that common validations are nice to have, and it is least of our problems. agree
----- Original Message ----- From: "Gilad Chaplik" <gchaplik@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org, "Eli Mesika" <emesika@redhat.com> Sent: Monday, January 28, 2013 5:08:41 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
----- Original Message -----
From: "Eli Mesika" <emesika@redhat.com> To: "Tomas Jelinek" <tjelinek@redhat.com> Cc: engine-devel@ovirt.org Sent: Saturday, January 26, 2013 10:58:57 PM Subject: Re: [Engine-devel] [engine-devel] frontend builders proposal
----- Original Message -----
From: "Tomas Jelinek" <tjelinek@redhat.com> To: engine-devel@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
Hi guys,
I agree that this refactoring can significantly help us reduce code complexity, there is another issue that your suggestion doesn't address, but we may want take the opportunity to address it if we are already considering refactoring for this code: this dialog demonstrates the greatest difference (IMHO) between server side pages to applets, the back and forth filling the form by retrieving all elements one by one. I would think of a concept similar to server side pages, i.e. retrieving all data, visibility and even validations (compat?), in a single request, and let the server have the logic.
Thanks, Gilad.
Thank you, Tomas _______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel
_______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel

Makes the frontend code much more readable, great job! Tal. On 01/26/2013 10:58 PM, Eli Mesika wrote:
----- Original Message -----
From: "Tomas Jelinek"<tjelinek@redhat.com> To: engine-devel@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@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel
_______________________________________________ Engine-devel mailing list Engine-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-devel
participants (4)
-
Eli Mesika
-
Gilad Chaplik
-
Tal Nisan
-
Tomas Jelinek