UI Software Architecture - MVC + Code Generation?

T

timasmith

Hi,

I have an architecture question for designing a suite of rich client
applications. The synatx is Java although there is little specific to
the language - I consider this a software engineering dilema.

What do you think of my solution as follows?

My general requirement is to avoid hand crafting each gui application.
Many are similar with a subset of controls others are using but
following a simple form data entry layout. There will be more complex
interactions between controls to be scripted.

I have a data/business layer which ultimately creates objects, here is
a simplified one as example - there are getter/setters per field

public class PatientObject {
private String patientName;
private Date birthDate;
private int genderId;
private int locationId;
}

I have a table which lists the gui controls in use for each app:

control_id addAction width height Text
1 addLabel 200 20 Patient Name
2 addPatientName 200 20
3 addLabel 200 20 Birth Date
4 addBirthDate 100 20
5 addLabel 200 20 Sex
6 addGenderId 100 20
7 addLabel 200 20 Location
8 addLocationId 100 20

I have an auto generated Application which will dynamically build the
controls

public class MyApp extends JFrame {
private AppController controller;

private addControls(ControlList controls) {
this.patient = p;
Enumeration e1 = controls.elements();
while (e1.hasMoreElements()) {
ControlObject co = (ControlObject) e1.nextElement();
if (co.getAddAction() == "addLabel") {
addLabel(co);
} else if (co.getAddAction() == "addPatietName") {
addPatientName(co);
} // repeats for all the unique controls in the
// the table above
}
}

private void addPatientName(ControlObject co) {
JTextField textField = new JTextField();
textField.setWidth(co.getWidth());
textField.setHeight(co.getHeight());
getCurrentContainer.add(textField);
}

private void addLocation(ControlObject co) {
JList list = new JList((ListModel) controller.getLocations());
list.setSize(200,60);
getCurrentContainer().add(list);
}
}

I guess the addControls should use reflection rather than generating a
large method - but I like the compile time check against the table by
auto generating the method name.

The controller has the lookup lists, each implementing ListModel to
directly update the application model and trigger additional
application logic. That works ok.

The part I am not thrilled with is that I have to map back text fields
back to the data model

e.g. in AppController
private PatientModel patient;
public void saveData() {
patient.setPatientName(myApp.getPatientName());
...
}

Ideally I could have a model for *every* GUI control - but the
javax.swing.text.Document looks too heavy for my datamodel to implement
for every field - so it seems better to map the data.

Any other thoughts on this architecture?

thanks

Tim
 
H

H. S. Lahman

Responding to Timasmith...
What do you think of my solution as follows?

My general requirement is to avoid hand crafting each gui application.

One way to do that is to use a commercial window builder. B-)

If you are driven by some masochistic tendency and actually want to
build the GUIs yourself, my advice would be to do it the same way the
commercial window builders do it: abstract the overall GUI paradigm
invariants and relegate detailed differences in GUI design to
configuration data. The paradigm for a GUI is Window/Control (as
opposed to specific business notions like Patient). One can abstract
the paradigm in a subsystem where the business semantics only appears in
the form of externally defined title and label strings. One then
provides a pure message interface to the business layer that interprets
identity into the GUI Window/Control objects. (Think: DTOs.) That
identity mapping can be provided in an external configuration file.

If one does that, then one can reuse the GUI subsystem as-is across
applications by simply providing an application-specific configuration
file and interface. That's because the Window/Control abstractions
don't depend on the specific applications and how one talks to the OS
window manager doesn't change; the only things that change from one
application to another are the Window objects instantiated, the Control
objects instantiated, the relationships between them, and the data
initialized into their attributes -- all of which one can synchronize to
specific business contexts across the boundary via configuration data
for identity embedded in the interface messages.

[BTW, the interface should reflect the business view of user
communication needs. So think: GoF Facade pattern where the Facade
class' implementation does most of the identity mapping (using the
configuration data via lookup tables) when dispatching to
Windows/Controls. Thus the Facade knows that a pile of data values in
the message data packet maps to a specific Window object and the Value
attributes of its associated Control objects. IOW, the business logic
sends monolithic Patient data and knows nothing about how that is broken
up into multiple GUI objects.]


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
(e-mail address removed)
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH
 
T

Thomas Hawtin

I have a table which lists the gui controls in use for each app:

control_id addAction width height Text
1 addLabel 200 20 Patient Name
2 addPatientName 200 20
3 addLabel 200 20 Birth Date
4 addBirthDate 100 20
5 addLabel 200 20 Sex
6 addGenderId 100 20
7 addLabel 200 20 Location
8 addLocationId 100 20

Hard coding the pixel width and height like that is probably a bad idea.
A better idea would be to go for slightly higher level properties.

It might be worth reconsidering putting the description in a database.
Would writing the code in code not be easier, both in terms of
implementing and updating? It also allows you to break the rules in an
emergency. At least start that way.
Ideally I could have a model for *every* GUI control - but the
javax.swing.text.Document looks too heavy for my datamodel to implement
for every field - so it seems better to map the data.

PlainDocument should be fine. If you write your model in this way, it
makes it trivial to put everything together.

You should be able to end up with model code like:

public class PatientModel {
private final Document name = new PlainDocument();
private final DateModel birthDate = new DefaultDateModel();
...
public Document name() {
return name;
}
public DateModel birthDate() {
return birthDate;
}
...
}

View building like:

form
.text("Patient name", model.name())
.date("Birth date", model.birthDate())
.gender("Sex", model.genderID())
.location("Location", model.genderID())
;

And some infrastructure along the lines of:

public class DateModel extends AbstractSimpleModel<Date> {
// Need to copy values due to terrible design of Data class.
@Override
public Date get() {
return new Date(super.get().getTime());
}
@Override
public void set(Date date) {
super.set(new Date(date.getTime()));
}
}

Tom Hawtin
 
M

Michael

I implemented a similar idea that automatically maps the gui fields to the
data model using reflection. I created a data entry control for each data
type, so the type declarations look something like:

public class Contact {
public TextAttribute FirstName = new TextAttribute();
public TextAttribute LastName = new TextAttribute();
public FormattedTextAttribute WorkPhone = new
FormattedTextAttribute("'(###')' ###-####");
public FormattedTextAttribute HomePhone = new
FormattedTextAttribute("'(###')' ###-####");
....

Each "Attribute" includes one or more editors that are automatically
extracted by the application framework, so the entire default gui is
generated automatically based on the data model. You can see some examples
of the guis that are generated:

http://www.mammothsoftware.com/groovy_plugins/groovy_plugins.htm

and

http://www.mammothsoftware.com/screenshots.htm

Regards,
Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top