Wednesday, December 10, 2008
OO Language Use to Write Stored Procedures
So anyways, I always like to think outside the box and ask some crazy questions, and yesterday I committed a crime by asking the following question after I saw a demo of a trigger and a stored procedure written to solve a specific problem that would have been harder to solve with writing application code (rare case): "Now that Oracle allows writing stored procedures in Java and MS SQL Server allows writing stored procedures in C#, isn't that the holy grail for developers that complain about how procedural and non-OO stored procedures are and how they produce difficult to maintain code? The Oracle Java version may be behind its time, but it's light years ahead as a language than that of stored procedures, isn't it?"
I got a backlash almost by everyone, even from the most OO-centric developers. Apparently, I forgot about one very important detail that one of our new co-workers reminded me of. Stored procedure code meshes well with SQL, which is a DSL that makes writing query code much easier than in Java. This ends up with simpler code that is easier to read than embedding SQL queries within another language with a different paradigm, such as Java.
Now, if we take that to the extreme, we would write all the application's query logic in stored procedures. So obviously, there is a point of diminishing returns. Stored procedures may be simple to write for small cases, but when used to write a whole application, they end up with the same issues that prompted the invention of OO methodologies, like lack of expressiveness for domain models due to no support for inheritance and polymorphism, and difficult maintenance as a developer is required to dig many levels into a procedure's code before understanding what it does due to no support for abstraction (assuming the code is well factored in many tiny procedures calling each other.) When a procedure is a method on an object, there is a lot more context to what it does, which saves developers from having to dig to understand what it does.
So, while the stored procedure language is easier than Java for writing code intermingled with SQL for simple cases, that does not necessarily mean it scales well for big projects with complex domains.
One last point that one of my co-workers mentioned that made a lot of sense is that you don't need an Object-Oriented language to write clean code. My response to that though is while that's absolutely true, you may still need an Object-Oriented language to write clean code that is easy to maintain when dealing with a complex domain. Just because the code is clean, it does not mean it's easy to maintain if the language is not expressive enough (no polymorphism, no inheritance, etc...)
What do you think?
Monday, December 08, 2008
To Get or To Do
Sometimes though, a model may have a property calculated dynamically, such as total. Other times, a property is determined dynamically based on passed parameters, like sales for a particular customer.
In these cases, do you prefer the name of the method to be getTotal() and getSales(Customer customer) or would names that reflect the behavior be more preferable, like calculateTotal() and determineSalesFor(Customer customer)?
Sunday, December 07, 2008
NIH Syndrome or Blowing Reuse Out of Proportion?
The first thing that pops in my mind when I see them doing that is NIH (Not Invented Here syndrome.)
From my experience, reuse is not just about getting the features I need. It is also about stability, performance, usability, and other non-functional requirements that have been ironed out by the people who have created the reusable component and the communities that consumed it. Unless it fails in most of these areas, I usually don't see the point of re-inventing the wheel. While it seems simple to do on the surface, it is those hidden edge cases and bugs that creep up now and then that get me when re-writing it. This happens in the code when I have not thought of every possible scenario and in the design when I have not exercised the component in a real-world setting.
What's the flip-side to this argument though?
A lot of people in the agile community place great importance on minimalism. An ideal minimalistic code base does no more than necessary by your application. So, if you end up reusing components that do a lot more than needed, the complexity of learning how to configure them for your needs ends up offsetting the productivity gains behind using the components. In that case, re-inventing a smaller simpler wheel becomes a viable option.
The key thing though is determining whether a required feature is complex enough that figuring out all its edge cases and usage scenarios would be worth the time to re-write from scratch vs simply reusing an existing component that gets the job done. That trade-off is the key determining factor.
Does the programming language used play any role in the matter? I'd say yes. For example, I rarely find this option of "re-inventing the wheel" viable in Java since writing components in it is very slow. On the other hand, dynamic languages like Ruby and Javascript make it so quick and easy to build a component from scratch (when writing tests first) that it often is easier to re-write smaller components than to figure out how to use 3rd party ones.
What is your opinion of the matter? Do you have examples where you reused a component vs other examples where you ended up writing your own?
Tuesday, June 24, 2008
Glimmer Introductory Tutorial
http://eclipse.dzone.com/articles/an-introduction-glimmer
The article includes a brief introduction to Eclipse SWT concepts for both Java and Ruby developers who are not familiar with SWT desktop development. Additionally, the article maps Java conventions to Ruby convensions to facilitate learning Glimmer for Java developers who have not had any Ruby experience.
Feedback and feature requests are welcome.
Tuesday, June 03, 2008
Internal DSLs: Part 1
Rails, a popular Ruby web framework, benefits quite a bit from that fact as it has a DSL for specifying object model relationships, a DSL for naming pluralization rules, and a DSL for routing of web URLs to actions.
RSpec, a very popular Ruby testing library, allows developers to write unit-tests and functional tests with a syntax that is very close to plain English, making test code easy to maintain and useful as specifications of the software.
So, DSLs help developers raise the level of abstraction and reduce the input needed from users/developers to the absolute minimum necessary for getting the job done.
As an example from Glimmer, a new Eclipse Technology Project for SWT GUI development, here is how a UI author would create a shell with a label:
shell {
label {text "Welcome!"}
}
As you can see, this is the bare minimum needed to visually represent a shell containing a label.
Coding the same example in plain Java yields the following:
Shell shell = new Shell(Display.getDefault());
Label label = new Label(shell, SWT.NONE);
label.setText("Welcome!");
With the Java API, the developer has to be concerned with lower-level details, such as object assembly mechanisms and setting values following the JavaBeans standard, neither of which are truly UI authoring concerns.
Here is another example taken from Rake, a popular Ruby make-like build tool:
task :generate do
# code generation logic
end
task :load => :generate do
# database data loading logic
end
task :test => [:generate, :load] do
# test running logic
end
What is noteworthy about the Rake DSL is the visual factor of the syntax. Arrows are used to indicate dependency in a similar fashion to how one might use arrows in a hand-drawn diagram.
Without a DSL, the tasks could have been written as:
def generate
# generate running logic
end
def load
generate unless generate_ran
# load running logic
end
def test
generate unless generate_ran
load unless load_ran
# test running logic
end
As you can see, with purely imperative logic, the developer works at a lower abstraction level by having to manage the task run-order dependencies. While it may seem simple in that example, that can bloat to pages of code with enterprise Rake scripts, increasing the code surface and probability of making mistakes.
Therefore, not only does relying on internal DSLs help developers raise the level of abstraction, but it also minimizes the amount of code needed, thus reducing the probability of making mistakes and increasing productivity further.
Nonetheless, with all the excitement about internal DSLs, people may wonder... How do they compare to external DSLs? Where does their use really fit in? Can they be used by stakeholders or are they limited to developers only? Are there other alternatives?
Stay tuned for answers to these questions in future blog posts.
Friday, April 25, 2008
XOR vs Equality Operators (^ vs !=)
public boolean isSomethingValid() {
return !a ^ b;
}
At the end of the day, Nick Malnick came to me and mentioned that a discussion broke out in his room because "someone used an XOR!" I went to the room to see what the matter was, and apparently another programmer who encountered that statement rushed to others for help because he didn't know what to make of the ^ operator and didn't know it was even a part of the Java syntax.
As Nick and I were leaving home, we had a talk about it, and I realized that I could have achieved exactly the same effect by writing the following instead:
public boolean isSomethingValid() {
return a == b;
}
In fact, we discovered the following equivalence relationships:
a ^ b <=> a != b
!a ^ b <=> a == b
Given these relationships, we had further discussion about whether it's a good idea at all to use the XOR operator in our client's code-base given that the developers rarely ever use it and aren't accustomed to it.
So, again in the spirit of the past blog post If-Else vs Direct Return and Manuel's blog post If Then (If Then Else) Else (If Then Else), I'd like to know the public's opinion on the matter.
Would you use XOR or equality operators? Does the decision possibly depend on the context? In other words, do the equality operators make more sense in some situations and XOR make more sense in others? If so, what are the different situations that warrant the use of each?
Sunday, April 06, 2008
If-Else vs Direct Return
public boolean isConsumable() {
if (STATUS_NEW.equals(getStatus())) {
return true;
} else {
return false;
}
}
After the test passed, I went ahead and did a refactoring by turning the method into:
public boolean isConsumable() {
return STATUS_NEW.equals(getStatus());
}
The test passed again. However, my colleague wasn't happy with that implementation. I was taken aback because I thought since it was shorter, that meant we had less code to maintain. But, my colleague expressed that he found it more understandable as an English-statement to say something like:
if a.equals(b) return true else return false
instead of
return a.equals(b)
The first time I personally learned the ternary expression "condition ? true-result : false-result", I found it a mind-bender and preferred to use traditional If-Else statements instead. After a while, I got used to the ternary expression and it became a basic construct in my thinking. In the same token, right now whenever I read a line like "return a.equals(b)" under a boolean method, I quickly translate it in my mind to something like: method value is determined by equality of a to b. Therefore, I believe it is just a matter of habbit and getting used to the shorter syntax.
Still, I am curious to know other people's perspectives on this. Which syntax do you prefer and why (If-Else statement or shorter direct return statement)?
Wednesday, March 19, 2008
Glimmer at EclipseCon 2008
The PowerPoint slides are up! Click here to get them!
The highlight of the talk was the Tic Tac Toe game built with Glimmer that I demoed at the end. Thanks to all of you who participated in playing the game during the talk. And, sorry to those of you who had to withstand me throwing toys to participants around the room. :)
Sunday, January 06, 2008
JFace TableViewer vs Swing JTable
How does it compare to the Java Swing JTable though?
To populate a table, JTable requires developers to implement a class called TableModel, which abstracts the data presentation of a table. The actual method that populates the table is getValueAt(int rowIndex, int columnIndex), which returns objects to be rendered for every cell in the table.
TableViewer on the other hand notices a pattern in table population related to the fact that table data is usually broken into rows, and then per each row, it is broken into columns. It takes advantage of that by having developers specify how data is broken into rows through an IContentProvider implementation, and then specify how a row is broken into columns through an ITableLabelProvider implementation.
Since table data often comes in a list or collection of some sort, the benefit of the latter approach is that one can reuse the same IContentProvider implementation across many tables, only needing to implement different ITableLabelProviders for each use-case.
This can still be done in Swing by relying on an abstract TableModel that always expects data in a collection, but the IContentProvider makes the separation of concerns cleaner in TableViewer.
Swing JTable provides other advantages due to being a rendered widget instead of a native platform widget. It supports having a TableCellRenderer, enabling you to render data in any way you like (e.g. as buttons, checkboxes, canvas painting, etc...) whereas TableViewer always displays data only as text, image, or a combination of both.
Is the API of either TableViewer or JTable a factor in determining which to use to build your future business applications?
I would say no. The differences are mostly aesthetic as you can accomplish basic business needs easily with either widget.
What really sets the decision apart is that TableViewer relies on a native table widget, offering a more familiar look and feel and potentially better performance whereas JTable is a Java Swing platform-independent widget, giving you more control and flexibility over the look and feel of the table.
Update: While this may have been accurate for previous versions of SWT, the situation changed with SWT 3.3 as it now supports cell rendering just like Swing. Please check Tom's comment for more details.
Saturday, January 05, 2008
Type-Inference with Generics
Consider this, for an example:
public Object load(Class objectClass, Serializable id);
This is an Object-Relational mapping method that loads an object from a repository based on the object id. Unfortunately, it requires you to cast the object after the method call, cluttering your code unnecessarily, as shown in this example:
Person person = (Person)mapper.load(Person.class, 35);
While Java Generics are often applied at the Class level, they can also be applied at the method level. In fact, in this case, they would offer a neat application of type-inference. Here is how the load method is rewritten to take advantage of that:
public <TYPE> Object load(Class<TYPE> objectClass, Serializable id);
Now, one way of calling this method is as follows:
Person person = mapper.<Person>load(Person.class, 35);
Of course, this does not get rid fo the clutter, yet only moves it by turning the cast into a generic <TYPE> specification.
However, there is another way to call the method that takes advantage of type-inference. Java can figure out the TYPE from the objectClass you pass to the method, so all you need to do is this:
Person person = mapper.load(Person.class, 35);
This achieves clean loading of the object without any necessity to repeat yourself and specify the Person class again in a cast or generic <TYPE> specification.
Wednesday, December 05, 2007
Validation Bubbles
Validations were defined on domain model fields using Hibernate Annotations, such as @NotEmpty, @Email, and @Regex. Based on these annotations, database tables were generated automatically using the hbm2ddl tool, and validations were performed automatically utilizing a technique that I like to call Validation Bubbles.
How do Validation Bubbles work?
Whenever a model is saved, it validates itself (using the Hibernate validation framework.) If errors are found, they are wrapped and thrown in a validation exception, which bubbles up from the domain model layer to the application layer. At that point, the exception is caught by a custom Struts action super-class that stores validation messages as a request attribute. When the JSP page is being rendered, a custom JSP tag picks the validation messages from the request and renders them on the web page to the user.
What benefit do we get from Validation Bubbles?
The application layer gets cleaned up quite a bit as Struts actions do not need to invoke validation explicitly anymore. As long as a Struts action extends the custom Struts super-class that catches bubbled validation exceptions, its logic only needs to handle orchestrating the business use-case.
Additionally, by placing business validation rules on domain models, and generating the database tables and page-level validations from them automatically, we eliminate redundancy as we do not need to define the same validation rules in multiple places anymore.
Now, it would be cool if we can somehow additionally generate client-side javascript validations from the Hibernate annotations on the domain models. That will be my next endeavor.
Monday, December 03, 2007
HAML is to RHTML what JSTL was to JSP
JSTL closed the abstraction gap between JSP and Java code by allowing developers to write Java logic in XML... Yuck!!!
HAML on the other hand accomplished the same goal for RHTML and Ruby code by allowing developers to write RHTML in Ruby... Yumm!!!
Ok, that is not entirely true, but it is close enough. HAML is a DSL not directly based on the Ruby language as it does rely on a compiler to process its syntax. Still, it is very DRY, tidy, and easy on the eyes compared to RHTML. Check out the HAML/RHTML showdown on HAML's home page for a good demo of that.
If you're already utilizing HAML on a project, please share your experience with us. I'd be curious to know if it's a TKO against the likes of XHTML, RHTML, and JSP.
Thursday, October 25, 2007
First look at JFace Data-Binding 3.3
What is data-binding though?
The basic use-case of Data-binding is to synchronize the contents of user-interface widgets (e.g. text boxes, labels, etc...) with properties on domain models bidirectionally, primarily by relying on the Mediator and Observer Design Patterns from the Gang of Four, shielding the developer from the details.
For example, if you data-bind a text box to the name of a person, then whenever you modify the text box contents, the new value is automatically copied to the name property on the person model. In the same token, if the name on the person model gets modified programmatically, it gets automatically copied to the text box on the screen.
Here is some code to demonstrate how to do that with JFace data-binding:
Person person = new Person();
person.setName("Bob");
Text nameTextBox = new Text(composite, SWT.BORDER);
DataBindingContext dataBindingContext = new DataBindingContext();
dataBindingContext.bindValue(SWTObservables.observeText(nameTextBox, SWT.FocusOut), BeansObservables.observeValue(person, "name"));
Of course, the Person model has to have an addPropertyChangeListener method and a name setter that fires property changes according to the JavaBean spec:
public void setName(String name) {
String oldValue = this.name;
this.name = name;
propertyChangeSupport.firePropertyChange("name", oldValue, name);
}
One of the biggest differences in the new JFace Data-binding framework is the binding syntax:
3.2:
dataBindingContext.bind(text, new Property(person, "name"), null);
3.3:
dataBindingContext.bindValue(SWTObservables.observeText(nameTextBox, SWT.FocusOut), BeansObservables.observeValue(person, "name"));
Does that make you wonder if it's less user-friendly than the older syntax?
The benefit of the new syntax is realized in the method signature. The older bind method had Object in its signature parameters, so you could have made mistakes when invoking it. Therefore, the signature did not guide programmers about which parameters to pass.
The new API has bindValue and bindList to separate between them. The signature of the new bindValue only takes ObservableValue objects, which are easily created in factories like SWTObservables or BeansObservables. That restricts the parameters that can be passed
The observeText method takes any Control however, and I had problems realizing that I was supposed to only use observeText(Control, int) instead of observeText(Control) when observing a Text widget. I would like these methods to be more guiding to the developer with their signature. This can be done by having observeText, observeLabel, observeSpinner, etc... that have the exact widget they support in their signature (e.g. observeText(Text, int))
The cost of using the new 3.3 API is a much more verbose syntax that again makes me wonder if it is easier to just write observers myself to handle two-way synchronization for simple cases.
Nonetheless, JFace Data-binding lets you customize the way data flows from the widget to the model and vice versa using UpdateValueStrategy objects. This helps with more complex use-cases of data-binding when you would like life-cycle events to occur before or after a value is copied to the widget or model. Examples would involve data-conversion and business validation.
Still, I believe we need a simpler syntax for simple cases, which usually constitute about 80% of all use-cases. I look forward to seeing that being taken care of in future versions of JFace Data-Binding.
Monday, October 22, 2007
Learning Design Patterns
My motto for this has always been "Use it or Lose it."
When I first learned Design Patterns in my undergrad degree, I thought they were cool, but did not appreciate their full value and did not really get when to apply them and when not to. Naturally, due to not using them for a while (except for occasional use of singletons and observers,) I forgot many of them and was not able to detect the need for them when it arised.
Later when I was doing my graduate degree, I had the pleasure of relearning Design Patterns from a great instructor at DePaul University. That was when Design Patterns really clicked in my mind. A number of factors that contributed to that were the instructor's great emphasis on practical benefits to applying Design Patterns in real-world applications, my healthy-skepticism and asking of many questions, and the exercises that gave us the opportunity to apply Design Patterns whenever we learned them in order to better fulfill business requirements for maintainability and extensibility in real-world scenarios.
I was so excited about Design Patterns after taking that course that I started applying them at work on a new project and reaped great benefits from them. The use of Design Patterns like Decorator, Command, and Template Method helped create very flexible, maintainable, and extensible code for the ever-changing requirements that I had. The feeling I had whenever I received requirement changes and was able to incorporate them in practically no time due to the earlier application of patterns was absolutely exhilirating. From that point on, there was no turning back for me as I experienced first-hand the true benefits of Design Patterns on a real business application.
On later projects, I attempted to apply every Design Pattern that seemed to fit the problem at hand. That got me first-hand experience on many different Design Patterns and allowed me to truly learn when they provided value and when they did not. Additionally, more Design Patterns stuck in my mind due to having had first-hand experience of applying them.
Did I ever over-engineer? Of course. Do I regret applying the Design Patterns that caused that? Never. If you hold the pendulum in one side (lack of enough engineering) and never let it swing to the other side (over-engineering), you would never give it a chance to pass through the middle (just-enough engineering) and stabalize there eventually. In other words, If I had not tried new Design Patterns in the first place because of fear of over-engineering, I would not have realized their benefits later when I did successfully employ them in situations where they provided great value. Besides, that also helped stick them in my mind for future use.
So, what is the best way to learn Design Patterns and have them stick?
- Study them with a genuine interest to deeply understand them and recognize when applying them would reap you benefits in real-world scenarios. My best recommendation for a book is Head-First Design Patterns because of its visual style, great humor, and deep tying of Design Patterns to Object-Oriented Design principles, which are the foundations on which Design Patterns were built. However, other great books are: Design Patterns Explained, Applying Patterns and UML, Refactoring to Patterns, and Design Patterns: Elements of Reusable Object-Oriented Design.
- Early in the learning process, look for every opportunity to apply one of the Design Patterns. Keep a Design Patterns book next to you to refer to whenever you are designing new Object-Oriented code. That way, you can always check if a Design Pattern could help with the problem at hand, and thus get an opportunity to exercise it. In no time, you will develop a sense of smell for patterns and become able to detect the need for them instantly when it emerges without the need for a book.
- Once you realize the benefits of a Design Pattern in a particular scenario, learn to focus in the future on recognizing when the Design Pattern is absolutely necessary and when it is just over-engineering. This is the stage of learning in which you start balancing the pendulum back in the happy middle. You don't want the pendulum stuck at either end after all.
Thursday, September 20, 2007
AOP Why? When? Where?
- Why invest time learning AOP?
- When do we need to apply AOP?
- Where in our code do we apply AOP?
Well, the answers that I got go as follows:
- AOP helps separate mixed concerns that OOP cannot. For example, OOP does not have an easy mechanism to separate the transaction concerns from your business domain logic. AOP on the other hand can handle that transparently or provide developers with an annotation to apply on a method when a transaction is needed.
- We need AOP whenever our code is becoming unreadable and hard-to-maintain due to intersection of many different domains, such as the business domain, transaction domain, security domain, logging domain, and others.
- AOP is applied at the points of domain intersection, usually keeping the business domain code in the main application classes, yet separating code from other intersecting domains into applied aspects. So for example, the logic for "checking if the logged in user has access to the task they are executing" can be separated out into its own aspect outside the business domain code.
Next, I had a concern about how long it would take all the team developers to learn AOP before being able to reap its benefits. After all, AOP seemed to have a learning curve that is as steep as OOP's.
Well, here is one pattern that can be followed to start reaping AOP's benefits before everybody on the team has caught up with it. Have the first developer or two generate Java annotations that embed useful aspects (like a transaction annotation, method logging annotation, or security authorization checking annotation), and then provide it to the rest of the team for free use wherever needed. This will give the team a chance to learn AOP gradually and still reap the benefits while doing it.
Next, I wondererd how do you introduce AOP into a team with success?
Well, simply start using AOP to improve your development processes first. For example, use AOP to check your code at compile time for any violations of MVC principles (is the View talking directly to the database or is it going through the Model tier first?) This will help the team get acquainted with AOP without the risk of releasing malfunctioning software as AOP is only used for development purposes.
Last but not least, what are some of the recommended AOP libraries?
- Spring AOP
- JBoss AOP
- AOPAlliance (comes with Guice)
One note is that many AOP features are sort of built into Ruby, so Ruby developers rarely need to use AOP formally. The "begin" and "after" hooks in Rails controllers are an example of AOP.
If you are currently using AOP or have utilized it in the past, please let us know how things went and what benefits or drawbacks were reaped.
Sunday, March 25, 2007
GWT Part 2: Drag & Drop
I am building an agile project planning tool that makes heavy use of drag and drop to facilitate planning of user stories into iterations as recommended by the eXtreme Programming Planning Game.
I will show screenshots once I have the tool nearly completed, but in the meantime, let me say that I had great success using drag and drop in GWT due to the ease of their API. And, GWTDesigner made things easier as it enabled me to design UI visually without sacrificing code quality since it generates simple-to-understand code. In fact, I can modify generated code and GWTDesigner would still understand it and let me visually edit it since it works by reverse-engineering the source code.
Drag and Drop works in GWT as follows:
- Make sure that the root panel containing all widgets is an AbsolutePanel
- Create a single DragController instance for that root panel. Normally, you instantiate the implementing class PickupDragController unless you require special customizations.
- Depending on the drop action you need, create a DropController instance for every drop target. For example, you would use an IndexedDropController for a VerticalPanel drop target.
- Register all DropControllers with the single DragController
- Call DragController.makeDraggable(Widget) on every widget that will act as a drag source.
In the future, I will experiment with GWT remoting, and see how easy it can be used to facilitate transparent AJAX programming without the pain normally experienced with writing Javascript that works with different browsers.
Friday, March 02, 2007
Article posted on IBM DeveloperWorks
The article just got posted on the IBM DeveloperWorks website:
Customizing Eclipse RCP applications, Part 1: Techniques to use with SWT and JFace
Enjoy...
Wednesday, February 14, 2007
Google Widget Toolkit
Google Widget Toolkit seems like the closest thing there is to my dream.
I got to toy with it a little bit tonight. I ran some of the included samples, and implemented a few examples. I was pretty impressed by its project generation support, seamless integration with Eclipse, and fine-looking widgets.
The next thing to explore is drag and drop functionality. Will keep you posted.
Friday, February 09, 2007
Saturday, December 23, 2006
RCP Patterns and Anti-Patterns
RCP Pattern Summaries:
Is The Job Done Yet?
To avoid application freezing when performing long-running tasks, use The Jobs API to improve usability
Summaries Are For Viewing; Details Are For Editing
Manage complexity and simplify application usage by utilizing Views to display data summaries and Editors to allow editing of data.
Serve Me A UI Screen Please
Enable Plugins to share UI screens (e.g. dialogs, wizards, panes) via a UI Screen broker Plugin.
One Plugin Per Library
Put each 3rd party library in its own Plugin. this prevents having to download the library during application updates every time its client Plugins are downloaded.
Compose Widget
When two or more screens have a similar cohesive subset of child widgets (e.g. address fields), extract those child widgets into an aggregate reusable widget to avoid repetition.
Instant Bean Brew
Instead of requiring users to hit save to persist data changes, improve UI efficiency by implementing the instant-persistence-paradigm using the JFace DataBinding framework.
RCP Anti-Pattern Summaries:
Everything But The Kitchen Sink
Placing all classes in a single Plugin can significantly increase download size during application updates. This also makes it harder to offer an application with configurable features.
Edit The Universe
Using a single editor to edit all data models (or a big number of them) causes information overload and makes it hard to discern structure or workflow.
The Obese Wizard
Placing too many controls on one page in a Wizard can impact usability negatively. Instead, break controls into multiple pages according to a logical flow.
Are Those Really Family?
Wizards, Editors, or Views that are in the same category, but do not follow consistent UI standards (e.g. margins, widget sizes, or colors), can hurt the professional look of the application and slow down the user from learning it.
But How Do I Fix It?
Your application is validating user input on "save" or on some other life-cycle event. When the validation finally occurs, the user has no idea how to fix it. Provide validation errors as soon as possible, preferably on loss of focus or character press. If that is not possible, have a way to help users navigate to the problem. If that is not possible, give users enough information so they can solve the problem.