1

I am currently trying to design a Java EE web application.

The views are quite complex, i.e. several dynamic drop down menus. The content of those drop downs may depend on the internal state of the model, user privileges etc., only to mention one thing here.

In order to avoid logic in the presentation layer, I introduced a service facade layer, where all those conditional decisions which data to ship to client is done, as well as conversion to DTOs.

To avoid dozents of calls of my JSF / CDI Backing Bean to the service layer, I thought about collecting all the neccessary data for the view in one big DTO, so the client has to do only one call for initialzation. I see the advantage that all the data can be collected in one single transaction, which ensures that it is easy to ship consistent data to the client. the presentation layer becomes very leight weight and intuitive. The presentation layer does not have to bother where the data comes from, it's all available in the single custom service facade.

But I am also facing the problem that I am tightly coupling my service to the view which feels to be terribly wrong. Finally I would end up in one service facade per view, which provides the DTO for a special view and which is receving and delegating all actions which the client is triggering. Now, if there are changes in the view (e.g. an additional input field), I would have to modify the service facade and the shipped DTO as well.

Do the advantages of such single service facade overweight or are they rather negligible? Do you have some suggestions for the design here?

Basically, which approach should I prefer and why?

Approach 1:

@Named @ViewScoped
public class MyBacking implements Serializable {
    @Inject private Service service;

    @PostConstruct
    private void init() {
        this.dto = servive.find();
    }
}

@Stateless
@Local(Service.class)
public class ServiceFacadeImpl implements Service {

    @Inject private ServiceA serviceA;
    @Inject private ServiceB serviceB;

    public DTO find() {
        PartA a = serviceA.find();
        PartB b = serviceB.find(a);
        return Mapper.map(a,b);
    }
}

Approach 2:

@Named @ViewScoped
public class MyBacking implements Serializable {
    @Inject private ServiceA serviceA;
    @Inject private ServiceB serviceB;

    @PostConstruct
    private void init() {
        this.aDTO = serviveA.find();
        this.bDTO = serviceB.find(aDTO.foo);
    }
}

@Stateless
@Local(ServiceA.class)
public class ServiceAImpl implements ServiceA {        
    public ADTO find() {
        Part a = ... 
        return Mapper.map(a);
    }
}

@Stateless
@Local(ServiceB.class)
public class ServiceBImpl implements ServiceB {        
    public BDTO find(ADTO a) {
        Foo foo = a.foo ... 
        PartB b = ... 
        return Mapper.map(b);
    }
}
  • One thing that is constantly changing is the user interface because everybody is an expert at recommending UI changes. Thus, your goal should be to design your system so the UI can change repeatedly without requiring application changes. Mainly because App changes require regression tests which tend to take much longer than UI testing. Thus, I don't like the 1 big DTO concept at all because it will certainly cause application changes as the UI changes. – Dunk Aug 31 '16 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.