An absence of clearly defined domain boundaries is probably one of the biggest causes of design failure out there. I’ve seen at least one business fail as a direct result this and another currently in dire trouble because of it (execs leaving in droves).
One of the fist steps in determining domain boundaries is to know what the domains actually are. Domains and / or collections of related domains then may be published as services.
Horizontally, the definition of a domain usually begins when mapping business areas to application functionality. For example, a domain’s boundaries may become the same as the processes of a given department within that business.
Vertically, domains are derived from the nature of the technical operations that have to be performed. For example, persistence is the remit of one domain (eg. DAO), UI rendering another.
Whilst there are general rules regarding fundamentals of domain design, the specifics depend on the nature of the business.
Another thing to mention is that domains should be completely decoupled. The domain should only be familiar with it’s own set of interfaces and not know about those of the other domains. The only common classes / components they share should be core classes, the nature and function of which are tightly controlled by a top level architectural committee with a single leader (i.e. Chief Architect).
Operations between domains should be ‘orchestrated’ by an external agent (or orchestration engine). This agent is responsible for executing the various processes that to complete, require the assistance of various domains. The agent will need to take the information (objects) from one domain and convert them into what’s required for the domain performing the next step of the process (eg. decorate these objects with interfaces that are specific to that second domain) and then have the second domain do its work and so on.