I am going to talk a little about my experiences with design patterns, specifically when building a Swing application.
Being the visual guy that I am, I decided to put together a little visual schematic showing the four most important (in my opinion) design patterns that should be applied when building your typical Java Swing application :
They are :
- Mediator Pattern
- Command Pattern
- Delegate Pattern
- Decorator Pattern
In this first part, out of the proposed four part blog, I am going to talk about the decorator pattern.
Decorator Pattern
The decorator pattern can facilitate the rendering of a business model bean in the context of the MVC pattern. The decorator wraps or masks the bean and can present the bean in a certain way for a particular GUI component.
The pattern deals with ‘decorating’ a business model bean with one or more decorators. The decorators can add, remove, enhance or modify properties of the bean they are masking. This reduces work that a renderer (the View) might need to do.
Examples what a decorator might do :
- Modify the formatting of a date.
- Derive an extra field. Eg: Age from date of birth
- Hide unnecessary fields (useful when doing data binding on, for example, a table)
The decorator pattern can also be used to enhance GUI components (in the context of painting over), although I won’t be talking about that here.
The classic approach is to have an interface defined like this :
1 2 3 4 5 6 7 |
interface IPatient{ public String getId(); public String getFirstName(); public String getLastName(); public Date getDob(); } |
A normal business bean called Patient.java will implement this interface. A decorator class will also implement this interface, such as in the following code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
class PatientDecoratorTable implements IPatient{ private IPatient patient; public PatientDecoratorTable(IPatient patient) { this.patient = patient; } public String getId() { return "#" + patient.getId(); } public String getFirstName() { return patient.getFirstName(); } public String getLastName() { return patient.getLastName(); } public Date getDob() { return patient.getDob(); } public String getFullName() { return patient.getFirstName() + " " + patient.getLastName(); } public int getAge() { Calendar dob = Calendar.getInstance(); dob.setTime(patient.getDob()); Calendar tdy = Calendar.getInstance(); int age = tdy.get(Calendar.YEAR) - dob.get(Calendar.YEAR); if (tdy.get(Calendar.DAY_OF_YEAR) <= dob.get(Calendar.DAY_OF_YEAR)) age--; return age; } } |
Decrorator Pattern and Tables
The decorator pattern is very useful when used with Swing tables. In the above example the decorator functions as a wrapper. An extra column called ‘Age’ can be added to the table and render this newly derived field, using the appropriate wiring in the table model.
If the derived field requires a lot of processing then it can perform its processing during object construction, storing its value in a new field. This new field can then be accessed just like all the other values. For example:
1 2 3 |
public int getAge() { return calculatedAge; } |
This reduces the work that the cell rendering has to do, which can be intense if a user is often scrolling through a table.
Hiding Fields?
Although the classic approach in using the decorator pattern uses a common interface between the bean and decorator; I find that sometimes that is unnecessary.
It is sometimes sufficient to pass the bean through the constructor. Using the pattern this way allows the hiding of unwanted fields, for example maybe in our table example we don’t care about date of birth, however we want to show the patient’s age.
NOTE: Hiding fields is especially useful using databinding : Especially when databinding uses reflection on all the getter methods.
Decorate your Tree
Decorators can be used when displaying data in JTrees :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
class PatientTreeDecorator implements IPatient{ IPatient patient; public PatientTreeDecorator(IPatient patient) { this.patient = patient; } public String getId() { return patient.getId(); } public String getFirstName() { return patient.getFirstName(); } public String getLastName() { return patient.getLastName(); } public Date getDob() { return patient.getDob(); } public DefaultMutableTreeNode getPatientNodeBranch() { DefaultMutableTreeNode base = new DefaultMutableTreeNode(this); base.add(new DefaultMutableTreeNode(getLastName())); base.add(new DefaultMutableTreeNode(getFirstName())); base.add(new DefaultMutableTreeNode(getDob())); return base; } public String toString(){ return patient.getId(); } } |
In the above example the decorator is also responsible for organizing representation of its internal bean in the form of a tree branch structure. The method getPatientNodeBranch() can be used when attaching the object to a tree node like this :
1 2 3 |
for (IPatient patient : cardiacPatients) { cardiacPatientsNode.add(new PatientTreeDecorator(patient).getPatientNodeBranch()); } |
The decorator pattern (using a common interface) allows for the nesting of decorator implementations. You could have a decorator for your table, and have this nested inside your decorator for your tree.
Further reading: |
Hi Mate,
I could connect with it very easily. You explained decorative design pattern beautifully with a real world example.
Thanks,
great series on swing and design patterns. when would part 4 be available?
Delicious explanation..!!
Hi felixzacat,
Thank you for sharing your insight for this design pattern. Simple and clear the example you made, straight to the point of the design pattern. All is good up the point of the decorator to be used in a table that uses reflection. I have that implementation of a generic tablemodel, that analyzes the class object, retriving all the getters and setters from the object and by method invocation gets the corresponding value. Along with this generic model, I use ORM modeling for my classes/entities. So if I get this right, I can use this pattern, to pass in the decorator the entity to be displayed in a table, but pass the decorator class into my tablemodel, analyze that class, that may hide for example associations to collections in my entity, or any other fields I do not want to be displayed. Also, that would be a much quicker way, since now my class analyzer recurses into any associations that are not of any primitive type (String, int, etc), which takes a long time to recurse, since ORM modelling creates many associations from one entity to another plus reverse associations and so on and so on…So by doing this I can void this long recursion. If you comment on this it would be much appriciated. Thank you once more.
Hi @George I will reply on Monday. Don’t have time at the moment
Hi @felixzacat, I am following up on my last question, to see if you had a chance to take a look at the question I posted a few days ago. I tried to figure out the question by doing some testing on my own, I have some ideas but I am not sure if I move in the right direction. If you have time I would appriciate any comments. Thank you once more.