I currently represent my Business Layer and Data Layer in a single project in my application. I have very good separation of concerns between the two sets of classes. However, My Data Layer classes take as parameters and return my business objects. So I will have code that loosely resembles (please don't be too critical of this code, my production code doesn't look much like this):
//business class fragment
public bool Save()
{
if(this.IsValid)
{
//DataProvider is one of many data access classes that implement an IDataProvider interface. Switched elsewhere in the class. This allows switching of Database providers, xml, etc.
DataProvider.Save(this);
return true;
}
return false;
}
public List<MyBusinessObject> GetObjectsByCriteria(string criteria)
{
return DataProvider.GetMyBusinessObjectsByCriteria(criteria);
}
I don't want my business classes to have to deal with DataSets any more than I like having my Data Layer classes deal with Business Classes.
I have read up a lot on Data Access Objects, or Data Transfer Objects to possibly solve this problem, but the this seems like an anti-pattern case for those patterns.
What can I do? How to I elegantly achieve complete separation of these two layers of my application?
When separating the business and presentation logic, you need to consider the following: Avoid affinities between the two parts of the application. Be aware of the DPL-restricted API; see Exception conditions for LINK command for details. Be aware of hidden presentation dependencies, such as EIBTRMID usage.
The data layer manages the physical storage and retrieval of data. The business layer maintains business rules and logic. The presentation layer houses the user interface and related presentation code.
The business logic layer contains objects that execute the business functions. The Command pattern should be considered to implement these objects. With the Command pattern, each use case in the requirements document is implemented as a separate command or set of commands executed in the business logic layer.
The Business Layer is the place where all the business/domain logic, i.e. rules that are particular to the problem that the application has been built to handle, lives. This might be salary calculations, data analysis modelling, or workflow such as passing a order through different stages.
This is a more general problem than just how to separate Domain Model from Data Access. The same problem occurs when you attempt to separate your Application Logic from your Domain model, your Presentation Model from Application Logic and so forth.
The common solution is a technique called Dependency Injection (DI). Some people also refer to it as Inversion of Control (IoC).
The seminal text on the subject was Martin Fowler's article Inversion of Control Containers and the Dependency Injection pattern, but we have come a long way since then, so be sure to examine some more recent texts as well.
You can implement DI manually, like described in this blog post, or you can let a DI Container (i.e. a framework) do the work for you.
Common DI Container are:
I don't think you can have the two completely separated, but you can ensure that the dependency isn't bi-directional.
I think it's important to define a couple of things:
The persistence, service, and view layers know about the model objects; the model objects are oblivious to the layer they're in.
The dependencies for the layers are unidirectional and flow back to front:
You unit test from back to front, because the dependencies make it easy to mock.
It's impossible to have NO dependencies, but you should design them so there are no cycles.
The only class with no dependencies is one that is called by no one and never calls another class. It's neither useful nor a worthwhile design goal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With