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?
Object
s' 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.