We’re designing a new application and we ran into some architectural question when thinking about data ownership.
We broke down the system into components, for example Customer and Order. each of this component/module is responsible for a specific business domain, i.e. Customer deals with CRUD of customers and business process centered around customers (Register a n new customer, block customer account, etc.). each module is the owner of a set of database tables, and only that module may access them. if another module needs data that is owned by another module, it retrieves it by requesting it from that module.
So far so good, the question is how to deal with scenarios such as a report that needs to show all the customers and for each customer all his orders? in such a case we need to get all the customers from the Customer module, iterate over them and for each one get all the data from the Order module. performance won’t be good…obviously it would be much better to have a stored proc join customers table and orders table, but that would also mean direct access to the data that is owned by another module, creating coupling and dependencies that we wish to avoid.
This is a simplified example, we’re dealing with an enterprise application with a lot of business entities and relationships, and my goal is to keep it clean and as loosely coupled as possible. I foresee in the future many changes to the data scheme, and possibly splitting the system into several completely separate systems. I wish to have a design that would allow this to be done in a relatively easy way.
I’d say this is a good case for the repository pattern, where you define an interface (or a small number of them) that contains all the data logic. Implementations of this interface are then passed to components via an IoC.
This pattern doesnt entirly get around the coupling problem though, the reporting repository would have knowledge of the customer table, but atleast that knowledge would be contained to a small number of classes. (in theory you could put the reporting logic in the customer repository, but that is not the best practice, since users are more ‘primitive’ than reports, it depends on the system though and would mean less coupling)
You can get more info on the repository pattern here and here