Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In my experience, the "Model" in MVC is often not really a single layer. I would regularly have "backend" models and "frontend" models, where the backend ones would have properties that I want to hide from the UI code, and the frontend ones have derived or composite properties which are more meaningful in the context of the UI.

Recently, I have started to introduce a third layer in between when database normalization created tables that did not really match the conceptual domain objects anymore. In those projects I have model classes that are equivalent with the DB structure, these become components of objects that represent the domain model, and finally these are filtered and amended for displaying information to the user.

Are there patterns or guidelines for how, when and why to organize the data model across application layers?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

In node.js I generally use a only three layers.

Data layer:

A simple layer that talks directly to the datasource. It's only job is efficiently extracting data from the source and writing to it. The datasource can be anything, a TCP endpoint, a HTTP endpoint, a database, a filesystem, etc.

Domain layer:

The domain object layer. This is similar to your "M" in MVC. It's an object representation of a domain object. It has methods for construction, manipulation, validation and other logic.

Note that a single domain object can talk to several different objects from the data layer and that several views can transform a domain object.

View layer:

The view takes a domain object and transforms in an easily printable way. For example, in the view layer I would convert a timestamp to a human readable string or do my i18n language conversion.

It also does any other view logic. Generally you have multiple view objects for a single domain object.

And of course it also converts data from the domain object into a format you want, whether it's binary, xml, json, html, some arbitary TCP protocol, plain text, csv, etc.

IO Layer

You generally also need some form of IO layer that talks to the other layers.

i.e. the IO layer

  • unpacks input
  • calls the correct domain object from either data or a domain object instance
  • passes the data/domain instance through the view layer
  • pipes the raw information returned from the view layer (html/json/binary/...) down the output

Multiple applications

Now a single application has these three layers. If I had a dynamic website then I would have these three layers on the server and these three layers on the client.

If I had my own unique data source to talk to then that remote data source would also use these three layers, it would have it's own domain objects, it's own data layer on it's own data sources and it's own view layer which other services talk to when they use me as a data source.

Pretty picture

enter image description here

Image Source

share|improve this answer
    
Source of the image? –  Yannis Rizos Nov 25 '11 at 1:02
    
@YannisRizos is it less credible if I drew it myself? Google doc –  Raynos Nov 25 '11 at 1:06
    
Nope. It's great that you did the extra effort to visualize your answer. Most people wouldn't, that's why I asked for the source. You should point that somewhere in the answer, so people can credit it to you if they decide to use it. +1 from me. –  Yannis Rizos Nov 25 '11 at 1:10

Your keywords are "Rich domain model" and you should be aware of anemic domain model antipattern.

In my (Java) applications I have these layers:

  1. Business objects (database object + bahaviour related to the data), transparently mapped to DB via Hibernate, injected with service dependencies using Spring anotation @Configurable - because they contain dependencies, it is possible to have data + operation at one place - embracing OO design (notice the difference when using anemic model, which has data in one layer, and operations in another (this approach is procedural and destroys polymorphism and inheritance)).
  2. Data access objects - Encapsulate communication with DB, this layer can be easily exchanged, if I decide to change DB access implementation (for example from JPA to JDBC or maybe object DB)
  3. Service layer - contains actions, which do not operate over business objects (hashich and crypto services) and services, that operate over a set of business objects, hence a single BO could not have this responsibility.
  4. Service facade - The true service layer as it is known from the similarly named pattern. Encapsulates the application, provides API for calls from the outter world (only those operations, which are relevant for callers, no inner issues). Security and transaction handling is done here. As well as transformation of inner data into data transfer objects.
  5. Data transfer objects - Simple wrappers, which just contain data to be transported to the world outside your application. You cannot use your BO, because they have methods, which cannot be called outside without context, and worse - they contain private data. Just image, if it is wise to send UserBO to outter world, when it contains hashed password and the salt. Also DTO may differ from BO - they may have different granularity.
  6. Some view layer - I use JavaServerFaces. But with this implementation, it really does not matter, it would be the same, if there were web services, REST or even binary API.

And one more link for another good article by Alistair Cockburn - Hexagonal architecture/Ports and adapters.

share|improve this answer
    
How is the data transfer object different from the view layer? Why can't a view layer do that transporting? Also how is the service facade different from the view layer? Are they not just another way to "view" data in some format? –  Raynos Nov 25 '11 at 0:24
    
The view layer is for representation. For example rendering HTML or destop view components. DTO is just transferring data to another application/application layer. View layer cannot do transporting, because it can be provided even by another application, or there might be more view layers - one for thin client, one for thick, one for web services... So the service must do it (or every view technology, but this violates DRY principle (do not repeat yourself)) –  malejpavouk Nov 25 '11 at 6:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.