- Advance:
I assume I don’t need to tell you what a Design
Pattern is and how it works. I suppose if you’re reading this post it’s because
you have knowledge about the commons Design Patterns (MVC or DAO for example).
Inside the set of Behaviour Patterns, we can find the
“Method Template” Pattern (in Wikipedia we can find a good explanation about
this Pattern, what is the main objective of the Pattern and how is the strategy
that this Pattern follows)
But if you
don’t want to read it I’ll resume to you. This pattern starts from an abstract
idea but with the knowledge about how many steps an algorithm must follow. Starting
from this abstract idea, you can develop your code in all the concrete levels
as you need to develop your application.
Talking
about code, the strongest point of this Pattern is the reusability when you
know your application must follow the same steps for all your entities with
little differences. It’s usual to use this pattern in addition with the FactoryPattern or the Service Locator Pattern (about Service Locator Pattern, a lot of
people don’t consider it as a Pattern and they prefer talk about it as a
AntiPattern we should discuss about this
in another post)
In this
post you can find a running application just for seeing how the application
works under this design pattern. You can check the code in this revision of the
next SVN address:
Rev: 4
- Explanation
My code
talks about a Service, and this Service uses
a Facade for the management of Vehicles (only two kinds of vehicles
because I only used two abstractions levels for my example). The Service is not
implemented yet but just launching the Tests inside the application, you will
see an example of this pattern, also you will understand how it works and the benefits
this idea could give you in your future applications.
For the
checkout of the code, you should know this example was developed as a MavenProject, under the 1.7 JDK using Spring 3 annotations.
About the
application, the main idea is a Facade using a ServiceLocator to get an
instance of an Interface. This interface is implemented by an Abstract Business
class which defines the main steps of the algorithm to validate and to execute
a vehicle. But at the end of these methods the Abstract Class calls to an
abstract method named “methodConcrete”.
You can
find two concrete implementations of the Abstract class; in this Concrete class
(one for Engine Vehicles and another one for Animal Vehicles) you just can see
we only have to develop the abstract “methodConcrete” defined in the Parent
Class.
My code was built so fast so you can see the
database is simulated by a HashMap and I use a Service Locator as a Factory.
But this is just the beginning, in future post I will include improvements as a
clean Spring FactoryBean and an embebed database using JPA annotations.
- API Tier
Object
|
Description
|
TemplateDTO
|
Data
Transfer Object.
This
object will be used as a template for all the Data Transfer Objects of my
app. Will be used for the definition to make an Interface which use Generics.
|
VehicleDTO
|
Data
Transfer Object.
This
object will be used as a container of all the common attributes to define a
Vehicle.
|
EngineVehicleDTO
|
Data
Transfer Object.
This
object will contain the concrete attributes for an engine vehicle.
|
AnimalVehicleDTO
|
Data
Transfer Object.
This
object will contain the concrete attributes for an engine vehicle
|
VehicleEnum
|
Enumeration.
This
Enumeration will be used to select a template for working. In each label we
can find an attribute called “service” used to locate the specific business
bean.
|
- SERVICE Tier (Service Implementation not implemented)
Object
|
Description
|
VehicleFacade
|
Facade
for a non-existing service. This facade uses a Service Locator object to find
the concrete business bean to be used.
If
any error appears, will throw a FacadeException
|
- BUSINESS Tier
Object
|
Description
|
TemplateBusiness
|
BusinessObjectGeneric
interface to define a generic API for all the objects which extend from TemplateDTO
|
AbstractVehicleBusinessImpl
|
BusinessObjectAbstract
class which implement the TemplateBusiness and
which define the main steps of the two operations, “validate” and “execute”.
|
EngineVehicleBusinessImpl
|
BusinessObjectConcrete
Business class to define the concrete steps for the validation and execution
of a Engine type vehicle
|
AnimalVehicleBusinessImpl
|
BusinessObjectConcrete
Business class to define the concrete steps for the validation and execution
of a Animal type vehicle
|
- Code snapshots
VehicleFacadeImpl
|
@Override public void manageVehicle(VehicleDTO vehicle, VehicleEnum template) throws FacadeException { if (template == null) { throw new FacadeException( MessageUtils .getMessage(MessageUtils.ERROR_TEMPLATE_NOT_INFORMED)); } @SuppressWarnings("unchecked") TemplateBusiness<TemplateDTO> templateBusiness = this.templateServiceLocator .getTemplate(template.getService()); try { templateBusiness.validate(vehicle); templateBusiness.execute(vehicle); } catch (BusinessException b) { throw new FacadeException( MessageUtils.getMessage(MessageUtils.ERROR_VEHICLE_WRONG), b); } } |
As you can see, using this pattern we can reutilize code a lot, because we don’t need different methods for each kind of vehicle. Just we can use only one method specifying the template to used. |
AbstractVehicleBusinessImpl<T
extends VehicleDTO> | |
|
|
In this abstract class we’re reutilizing code so much because we validate the common attributes to all the differents kinds of vehicles. When we’re executing the “execute” method, we can see we have the common business logic (validate if an id exists in the system) in this abstract class delegating the concrete business logic (or validations) in all the objects which extend from this abstract class |
EngineVehicleBusinessImpl | |
|
|
Here we have all the concrete steps for an Engine vehicle. You can see we only have to put in these methods all the things relative to the management of our concrete DTO (in the case of validation), and in the execute we only need to put steps related to the store of the vehicle in the place defined for it. But really all the logic is defined in a high level abstract template. Reaching this point, maybe we could introduce new abstraction levels following the same idea presented in this example. The JVM at runtime will know what concrete object must be used, because all of them are part of the same object family. |
AnimalVehicleBusinessImpl | |
|
|
Here we have all the concrete steps for an Animal vehicle. You can see we only have to put in these methods all the things relative to the management of our concrete DTO (in the case of validation), and in the execute we only need to put steps related to the store of the vehicle in the place defined for it. But really all the logic is defined in a high level abstract template. Reaching this point, maybe we could introduce new abstraction levels following the same idea presented in this example. The JVM at runtime will know what concrete object must be used, because all of them are part of the same object family. |
- Conclusions
You can get conclusions by your own, the main idea all
the benefits of this pattern was explained all around the post. Using this idea
you make your code reusable, and you can introduce concrete objects in the
application, which start from an abstract idea. That concept of abstraction
gives you freedom to model at your interest, but I should advice maybe it’s not
a good idea to introduce so many levels.
From my point of view, the weakness of this pattern would
be:
- Excessive coupling between the concrete elements and the high levels object, because all of them must be part of the same family.
- Depending about how many levels you need to introduce in the family, the debug from the top level to the concrete level sometimes is hard to follow (is not easy to debug)
- If you introduce a new method in one of the high level objects, you should introduce the expected behaviour in the low levels objects. In other words, the pattern doesn’t have enough scalability.
No comments:
Post a Comment