6

My course text suggests creating a 'facade' class to completely abstract the user interface from the domain layer. That is, the UI uses only basic types, and if it needs a reference to a domain object, it only knows it as an Object.

To give you an idea, this is what it might look like (example in Java but could equally apply to other languages):

public class Facade
{
    ...
    public Object getLastOrder(Object customer)
    {
        Customer castCustomer = (Customer)customer;
        Order lastOrder = domainController.getLastOrder(castCustomer);
        return lastOrder;
    }
}

Note: I'm not sure whether this is in fact a type of facade pattern (I've heard it defined differently elsewhere), but I don't want to get too bogged down in terminology.

Compared to nothing (having the UI call the domain controller directly), I can see that this has the advantage that the UI is much more independent of changes to the domain model implementation. There's always a risk that very major changes (such as not having anything representing an order any more) will break things, but this seems to be able to absorb anything else.

However, it seems to sacrifice type checking, and it means that getting even simple properties of domain objects more convoluted than it needs to be (anOrder.getNumber() vs facade.getOrderNumber(anOrder)).


My own thought was that it would be better for the UI to reference domain objects in terms of interfaces, rather than plain Objects. For example:

public class Facade
{
    ...
    public IOrder getLastOrder(ICustomer customer)
    {
        Customer castCustomer = (Customer)customer;
        Order lastOrder = domainController.getLastOrder(castCustomer);
        return lastOrder;
    }
}

or even if the domain controller itself exposed only the interface types, forgetting the 'facade' altogether.

As far as I can see, this is better from a type checking point of view. Major changes (e.g. removing Order from the system) can break things, but that was true of the 'plain Object' solution.

And any methods that are stable (e.g. anOrder.getNumber()) can be specified in the interfaces, so calling them from the UI is simpler and more object-orientated. Obviously this only applies to methods whose signatures are stable, to avoid breaking the UI, but the implementation is still free to change.

Is there something I'm missing? Does my 'interface' solution have any drawbacks I haven't spotted? Or is there a completely different, better solution that I haven't though of?

4
  • 1
    Your ideas seem solid. There is nothing that jumps out to me as being off-base. Commented Oct 3, 2013 at 14:03
  • 1
    I worked with a system were everything had an interface. It was painful to say the least. Commented Oct 3, 2013 at 14:16
  • possible duplicate of What is the point of having every service class have an interface?
    – gnat
    Commented Oct 3, 2013 at 14:23
  • @gnat Apologies if I wasn't clear, I'm looking for ways to keep the abstraction from my course's 'UI only knows about Objects' solution, but work on its drawbacks; whereas the question you link seems to me to be more along the lines of 'Is there any point in having this much abstraction?'. Many thanks for the link, it's interesting and related, but IMO it's a different question.
    – just me
    Commented Oct 3, 2013 at 15:04

2 Answers 2

3

I would advise you to use viewmodel classes for your UI instead of domain objects. There tends to be a large difference between the representation of data that your view needs and the representation of data that the domain needs.
Say you want to show a list of orders in the UI. An Order in the domain will probably have a lot of properties, some reference objects, etc. You'll probably not need most of those things in the UI, so just take what you do need, shove it into a viewmodel and bind that viewmodel to the UI.

PS: a facade is used to simplify working with one or more objects. If you want to achieve something and to do that, you'd have to make 5 calls to 5 different objects, a facade's responsibility would be to encapsulate those 5 calls, shielding you from the complexity of working with those 5 different objects.

3
  • Thanks for the answer. I haven't come across viewmodel classes before and most of what's on the internet seems to be directed at .NET; would you be able to point me in the direction of a good framework-agnostic introduction?
    – just me
    Commented Oct 8, 2013 at 13:50
  • @justme Not off the top of my head. I would point you to the MVVM pattern, but you'd find a lot of WPF related stuff, which may not be that helpful in your case. Short explanation: say you have a view, a controller and a model class (which you want to represent in the view). Your controller would retrieve the model class, create a viewmodel object, pump over the data you need from model object to viewmodel object and bind the viewmodel to the UI. The binding can be manually (form.txtWhatever.Text = viewmodel.Whatever) or automatically (in webdev KnockoutJS, WPF has its own databinding, ...). Commented Oct 9, 2013 at 8:17
  • That makes sense, thanks. Looks like a useful pattern...
    – just me
    Commented Oct 10, 2013 at 13:24
1

Advantage of the first version:

  • your API won't change, and it will be super-stable as it cannot be more general: public Anything DoSomething(Anything something) { }

Disadvantage:

  • the caller should always guess and cast your return value. What if the developer won't check your documentation and does this:

    if ((bool)yourObject.getLastOrder(customer)) { ... }

  • you are where you are started: both the caller and the function depends on the Customer concrete class. It is just hidden from the signature, so you introduce a new level of failure: what happens when you write the following totally logical code:

    Company theirCompany = MyDb.GetCompany(12345); Order order = (Order)yourObject.getLastOrder(theirCompany);

    You still have to check every single call if Customer class changes. You made matter worse by replacing all concrete types with object. There is a level when you cannot be more abstract and you are making more work for yourself.

If you have a program for handling orders you cannot prepare it to make only very little changes where you are not handling orders anymore... But you can prepare if there will be new types of orders and customers.

Given that, the only useful level of abstraction you can have here is to find out what is the minimal amount of information you need in your function/class about getting an order.

So, you slicing that information from your ICustomer interface. For orders you'll have, say, an ICustomerID interface:

public interface ICustomerID { int getID(); }

public interface ICustomer : ICustomerID { ... } 

public interface ICompany : ICustomerID { ... }

So back to your function:

public IOrder getLatestOrder(ICustomerID id) { /* get order */ }

And calling would look like this:

Customer customer = SomeFactory.GetCustomer(...);
Company company = SomeOtherFactory.GetCompany(...);

IOrder customerOrder = myObject.getLatestOrder(customer);
IOrder companyOrder = myObject.getLatestOrder(company);

You can have two totally different interface for Customer and Company; you can change their implementations any time; you won't have to change getLatestOrder.

1
  • Thanks for the answer. I think they're assuming the UI programmer would be disciplined enough to not cast in the UI code. I like the idea of splitting the interfaces up using inheritance.
    – just me
    Commented Oct 8, 2013 at 13:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.