I my last post, I described the benefits of applying the Repository pattern to encapsulate all logic pertaining to the direct manipulation of your data entities. The repository is responsible for shaping the data entities that will get passed back up through the ASL to your services or views, as well as pushing the data through the data services layer down to its final persistence location. You should note that this could be any number of data source types, from a relational database, to xml files, to an external web service. The repository is the manager of all such data centric interactions.
It is most important to note that when fetching data and passing it up into the application layers, it should be packaged appropriately based on the need of the calling layer. While you could simply pass full data entities of your Model into the application from repository calls, care should be taken to avoid unnecessarily exposing full Model entity details throughout your application. It is important to minimize the number of locations that will break if the data model changes over time, and rest assured, it will change over time. For this reason, we depend upon the ASL and Repository layer interfaces when using and accessing the Data Model as these methods can be used to create packages of data that represent just the specific information necessary to enact a Use Case or support a View. This collection of information is often referred to as the ViewModel; you can think of this as a Model specifically abstracted for the View, or a specialization of the domain Model.
We use the Data Transfer Object (DTO) pattern to create packages of information to abstract the ViewModel. And as the application layers are designed specifically to represent each Use Case, it makes sense to delegate to them the responsibility of creating such packages which will be contained in the Data Transfer Objects (DTO). The DTO’s are passed to the layers above to be used as needed, and subsequently passed back to the Repository for processing into the underlying data source using whichever data service technology is in force, whether NHibernate, Microsoft’s LINQ to SQL, the Entity Framework or calls to external services, etc.
Any DTO may contain an instantiation of a single entity, a collection of entities, or even just a limited property set representing whatever needs to be managed at the View or Controller level. At some point you may feel the need to reference properties of the Data Model’s entities, but in situations other than when Data Binding to controls, it is a better practice to limit direct property access, and instead use methods that act on the entity types and their Repositories as much as possible.
So, that’s it on layering for now. There will certainly be other classes and utilities in your solution as with any complex application, but utilizing ASL and Repository layers will give you some real bang for the buck. Once in place in your architecture, and once you get the feel for how to abstract the logic across these additional but thin layers, all of a sudden making changes to your system code becomes simpler, and you find yourself breaking and fixing your code less often, even though you may be re factoring faster and more frequently.
Adding layering functionality, even though you may have to spread it out across multiple classes, becomes less error prone because you find yourself writing simpler and less verbose code. Testing becomes easier because you only need to create tests for the smaller methods that you create at each layer. Method names can be more explicit and self-documenting because the methods themselves have a more explicit single purpose. And as your system grows, you become more and more aware of where each discreet piece of functionality lives and why it lives there, as a clean consistency of design slowly emerges and makes itself evident.
How about that…cleaner code, fewer bugs, easier to write, easier to test, easier to understand, easier to maintain. Who would’a thunk you get all this, just from adding a few more layers…but it’s true.