In past projects I've noticed that many maintainability problems arise from the wide spread mixup of data access and business logic, and high dependancy of logic on entities. I'm not attempting to design a hypothetical system that avoids all of this, but I am interested in reducing the problems introduced in the long run by tighly coupled code.
Overview (simplified to represent only the problem at hand):
- Cross Cutting: entities
- Presentation Layer: UI, displays stuff using entities, usually initiates calls to the BLL
- Business Logic Layer (BLL): logic that works with entities, usually implemented as static methods, often also calls the DAL
- Data Access Layer (DAL): mappers that provide CRUD methods for entities (hand-coded SQL queries)
Changes
I intend to make all parts more testable and maintainable. Therefore I decided to introduce a number of changes, mostly in the DAL and BLL since they cause the most trouble. Logic is embedded in queries and the BLL becomes highly dependent of the DAL's methods and entities.
DAL
- Introduced a mechanism that generates SQL from C# rather than hardcoding the queries. This enables compile-time errors rather than run-time. We should be able to catch inconsistencies with the queries and the entity model earlier on this way.
BLL
- Removed the reference to the DAL (decoupling them entirely), all logic is called from the UI through a new "glue" layer, which links the UI to the DAL and the BLL.
In my opinion, so far so good, this should work out pretty well for us. Now comes the biggest change.
- Another change I intend to introduce is a variation to the command pattern, in order to remove the dependency on the entity model. I also want to make sure that business logic is testable. Therefore it seems to me that the "glue" layer should translate entities into command objects that contain just the data a certain piece of logic needs. When the model changes, only the mappings needs to be adjusted and the business logic remains intact.
This seems like a good idea but I expect a huge amount of business logic, resulting in tons of command objects to maintain. Is this a justified fear or am I worrying too much? What are your experiences with these kinds of problems?