Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

User interfaces for object-oriented systems, Part 4: Menu negotiation

A scalable architecture for building object-oriented user interfaces

Before we turn our attention to the main subject of this month's Java Toolbox -- menu negotiation -- it seems, judging by numerous reader inquiries, that I have a bit more explaining to do about the visual-proxy architecture that I discussed in the September column.

TEXTBOX: TEXTBOX_HEAD: Build user interfaces for object-oriented systems: Read the whole series!

:END_TEXTBOX

Operations on attributes

The first recurring question had to do with the notions of Employees and their salary attribute: How can you sum all the salaries of all the employees in some department without violating encapsulation? Or, to put it another way, why don't you have to get a number out of the Employee class to perform this operation?

My answer is that you don't get the value of the salary from the Salary object. You might have a salary() method that returns a Salary object that represents the salary, but the implementation of the salary is still hidden inside an object. The main purpose of the auxiliary Salary object is to remove the salary-manipulation functions from the main Employee interface and put them into a class of their own. That is, rather than give the Employee a print_your_salary() method, you'd give the Salary a print_yourself() method. (The salary would also support methods to do other salary-related operations, of course.) You could then print an employee's salary with either:

some_employee.print_your_salary();


or

some_employee.salary().print_yourself();


Adding its salary to a sum is also a reasonable request to ask of Employee in some situations; both of the following are workable object-oriented solutions, since neither exposes the way in which salaries are implemented:

some_employee.add_your_salary_to( Salary the_sum )
{   the_sum.add( my_salary );
}


Or, if you had resorted to a get method:

the_sum.add( some_employee.salary() );


Interactions between proxies

The second issue readers brought to my attention was: How do you handle interconnected controls on a form? For example, what if the status of some checkbox determines which values are valid in another proxy entirely? The quick answer is that the interaction happens at the model (abstraction) level, and the proxies take care of themselves.

The figure below demonstrates two common situations. On the left, a model-level object has displayed proxies for two attributes, one as a checkbox and the other as a field of some sort. When the user clicks on the checkbox, a model-level listener (manufactured when the proxies are created) notices that the checkbox has changed state and enables the associated field.

The more interesting example is on the right side of the figure. Here, there is a complex interaction between proxies for three objects of different classes: an instance of Company called employer, an instance of Group called division, and an instance of Person called employee. The proxy for the Company displays a list of divisions. It can do this without any communication with the rest of the system because of the qualified association. (Think of the qualifier as specifying a hashtable of Group objects, keyed by division Name. The Company can create a UI displaying all the division names simply by calling getKeys() on the hashtable.)

Resources
  • A usual, the code to this month's article is available in the "Articles" section of my Web site
    http://www.holub.com
The other Java Toolbox articles in this series
  • The Gang of Four
  • Design PatternsElements of Reusable Object-Oriented Software, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides -- the Gang of Four (Addison Wesley, 1994) http://www1.fatbrain.com/asp/bookinfo/bookinfo.asp?theisbn=0201633612