Back Forum Reply New

Distribution Facade / Service approach

Hello,
I'm really having a hard time struggling with all of these issues :
1 - promoting a base development model to anemic and non anemic development (this model will be used for ~ 50 applications so it should adress simple and complex cases if possible).
2 - promoting a model enabling the distribution of remote services and non remote services.
3 - promoting a model which isn't too heavy-weight.
4 - by the way resolving the Open In View Session Hibernate problem would be a goodie !
I would like to have a development model resolving those issues.
I'm just talking about the middle tier (service, entity, dao, ...).
My sources of inspiration (6 months ago, so I quite forgot the few things I've understood) where the Domain driven design (), and
and martin fowler's PEAA (a pity they didn't gave some code for a complete Java application in their book).
I've tried to match to model I'm suggesting with Spring base model or AndroMDA's but it doesn't match.
So I suppose my model is wrong (quite a lot people are involved in those problems and are more intelligent than me).
But the proven models don't adress my problems so what is wrong ? It should be so hard to develop (we're not launching space ships with those java applications no ?).
I'll explain here the solutions I've found (or people or books adviced me) to solve those pbs.
Afterwards, I'll give some code.
2 - distribution of services
Versionning of service is the main problem for remote services (not for local ones).
I'll expose SOME (not all) of the services to partners (external applications managed by external companies).
The main distribution technology will be SOAP for the moment (I'm a fashion victim).
I don't want to impact my partners everyday I change my service, so I want to maintain at least two versions of the service interface at the same moment.
Solution someone adviced me (and it's running on a production environment, so it works) :
- separate and version the exposed interface from the internal service (internal interface or implementation).
I've also found some restrictions depending on the technology used for distributing my service (i.e. can't use Map, List or others usefull container objects with SOAP technology if I
want to be WS-I Basic Profile compliant). Also, I dont want to clutter all my services with those kind of restrictions since only a few services will be distributed, hence the additional rule :
- the input / output data is different between the exposed interface and the internal service.
In my suggested model, I'm introducing the facade object to denote this exposed interface. The service object will be used as the internal interface.
1 - promoting anemic and non anemic model
In the rich domain model (I really expect only 5% of the applications or even less to adopt it), the clients tiers should be separated (logically I mean) from the
domain tiers.
A separation layer can be the service layer (I mean here the Application Service Layer and not the Domain Service Layer - third page of chapter 8 of DDD).
Ok no problem.
But if the parameters and result of the service are domain objects (as specified in DDD - chapter Services paragraph 8), the isolation isn't achieved :
- a simple change in domain objects association will break my client.
- the client is able to call the domain object operation directly (bad !).
My suggested model 'breaks' this rule in the facade layer (more on this later).
3 - promoting a model which isn't too heavy-weight.
Yiks, I think the suggested model breaks this rule (it's going to be a pain in the ass to code VO ou TO / domain object transformation and the additionnal facade layer).
4 - by the way resolving the Open In View Session Hibernate problem would be a goodie !
No pb, I'm using the soution for the 1 and 2 pb to solve this.
So here's the suggested model :
- I'll model exposed services as a facade object.
The client of my middle tier must access it by using facade objects.
The IN/OUT values of facade model will be called Value Objects or Transfer Object (don't know which name to pick - so let's for the sake of dicussion pick the TO one).
The facade is responsible to transform the TO objects to domain objects (entities) and to call the service.
If I want I'll delegate transformation code to an assembler object (I'm not naming it builder it's not the same I think).
Also, I'm going to put transaction and security demarcation on the facade layer.
Also the facades will be dependent of the access technology (local, web service, ejb, ....).
For remote technologies implying others applications I'll version the Facade.
- I'll model application services as services.
The IN/OUT values are domain objects.
In the anemic model, services will use DAOs. services will be implemented as the Tutorial Spring services.
In the non-anemic one, this is another discussion... I'm not going in this one.
- entities will be dependant on anemic or non anemic model.
Here's some sample code (for the employee concept) :
The local facade interface (TO are in the same package as facade) :

Code:
package org.pag.demo.facade.local.employe;
public interface EmployeFacade {   public void createEmploye (EmployeDetailTO aEmploye) throws EmployeExistantException;   public void deleteEmploye (EmployeDetailTO aEmploye) throws ConcurrencyException;   public EmployeDetailTO getEmploye (EmployePkTO aEmploye) throws NoSuchEmployeException, InvalidKeyException;   public IPageTO searchEmployeList (EmployeSearchCriteriaTO aCriteria) throws InvalidCriteriaException;   public void updateEmploye (EmployeDetailTO aEmploye) throws ConcurrencyException;
}
The local facade implementation (extract) :

Code:
package org.pag.demo.facade.local.employe;
public class EmployeFacadeImpl implements EmployeFacade {   private EmployeService mEmployeService = null;   private EmployeAssembler mAssembler = null;   /* (non-Javadoc)    * @see org.pag.demo.facade.employe.EmployeFacade#getEmploye(org.pag.demo.dto.employe.EmployePkTO)    */   public EmployeDetailTO getEmploye(EmployePkTO aEmploye) throws InvalidKeyException, NoSuchEmployeException {       EmployeAssembler lAssembler = new EmployeAssembler();       EmployePk lEmployePk = lAssembler.toEmployePk(aEmploye);       Employe lEmploye = mEmployeService.getEmploye(lEmployePk);       return lAssembler.toEmployeDetailTO(lEmploye);   }
}
An extract of a manual assembler (I think I can later soften the easy straightforward transformation using AoP and dozer...) :

Code:
public class EmployeAssembler {   public Employe toEmploye (EmployeDetailTO aEmployeTO) {       EmployeImpl lEmploye = new EmployeImpl();    lEmploye.setIdentifiant(aEmployeTO.getIdentifiant());    lEmploye.setNom(aEmployeTO.getNom());    lEmploye.setPrenom(aEmployeTO.getPrenom());    lEmploye.setSalaire(aEmployeTO.getSalaire());    lEmploye.setCivilite(aEmployeTO.getCivilite());    lEmploye.setDateNaissance(aEmployeTO.getDateNaissance());    lEmploye.setCoordonnees(new CoordonneesImpl());    lEmploye.getCoordonnees().setTelephoneProfessionnel(aEmployeTO.getTelephone());    lEmploye.setAffectation(new AffectationImpl());    lEmploye.getAffectation().setCodeDepartement(aEmployeTO.getSocieteId());    lEmploye.getAffectation().setCodeSection(aEmployeTO.getSocieteNom());       return lEmploye;   }   public EmployeDetailTO toEmployeDetailTO (Employe aEmploye) {       EmployeDetailTO lEmployeTO = new EmployeDetailTO();       ...   }
}
The web service facade (please note the versionned package, the service is also using versionned TOs), extract :

Code:
package org.pag.demo.facade.ws.employe.v1;
public interface WSEmployeFacade1 {   public void createEmploye (org.pag.demo.facade.ws.employe.EmployeDetailTO aEmploye) throws EmployeExistantException;
}
The application service layer (anemic one) - please note parameters and result types are entities here :
package org.pag.demo.service.employe;
public interface EmployeService {   public Employe getEmploye (EmployePk aEmploye) throws NoSuchEmployeException, InvalidKeyException;   public void createEmploye (Employe aEmploye) throws EmployeExistantException;   public Collection searchEmployeList (EmployeSearchCriteria aCriteria) throws InvalidCriteriaException;   public IPage searchEmployePage (EmployeSearchCriteria aCriteria) throws InvalidCriteriaException;   public void deleteEmploye (Employe aEmploye) throws ConcurrencyException;   public void updateEmploye (Employe aEmploye) throws ConcurrencyException;
}
The application service layer implementation extract (anemic one) :

Code:
package org.pag.demo.service.employe;
public class EmployeServiceImpl implements EmployeService {   public Employe getEmploye(EmployePk aEmploye) throws NoSuchEmployeException, InvalidKeyException {       if (aEmploye == null || aEmploye.getIdentifiant() == null) {throw new InvalidKeyException (quot;identifiant non renseigné.quot;);       }       return mEmployeDao.getEmploye(aEmploye.getIdentifiant());   }   ...
}
I've submitted a similar thread in AndroMDA forum (forum/viewtopic.php?t=3733), but no reply - perhaps my questions or suggestions are stupid ? Please let me know !
Thank you

Apologies.  I read the thread but I'm not sure what the questions were.  Can you concisely summarise the main questions.

Yes of course :
I can't handle some use cases with the spring development model (client clients call service pojo, the service pojo accepts as params and return type entities).

Here are the cases :
1 - remote service distribution for partners or external applications.
Need a facade approach on top of the services to resolve versionning and type restriction of remote technology.
2 - rich domain model development. Since services accept domain objects, the client (presentation tiers) can directly use domain objects. Need a facade layer once more ?
3 - open session in view (problem appears when using an ORM tool such as Hibernate).

So perhaps I didn't undestood the model or perhaps there's something missing.
The purpose of this thread is to know if there's a piece missing, which one and give some sample code (I've provided mine, but it's perhaps broken...).

2 - rich domain model development. Since services accept domain objects, the client (presentation tiers) can directly use domain objects. Need a facade layer once more ?
An interesting pointer  :
docs/gett...ava/index.html, paragraph :
Data Propagation Between Layers.

3 - open session in view (problem appears when using an ORM tool such as Hibernate).
43.html (the site is down for now but i think the link is correct).
The solution is using a Filter. This does appears ok for a fast development but it expands transaction scope or begins a new transaction, so the solution will consume more database ressources.

Also, found this interesting thread, but doesn't solve remote services pbs, and doesn't end with a template code (which I would like of course  ) :

showthread.php?t=19429
¥
Back Forum Reply New