views:

191

answers:

3

You've probably heard of the Fat Model/Thin Controller vs. Thin Model/Fat Controller distinction. I recently heard that you can have something in between where some of the logic from the model goes into a service layer. How common is this? and do you know of (or can think of) any real examples that illustrate it?

+6  A: 

Martin Fowler describes the Service Layer pattern of his great book Patterns of Enterprise Application Architecture. If you care about questions like the one you asked, you should read this book.

One use that comes to my mind is managing database transactions. Some people try to encapsulate starting and committing transactions in their domain models. But then they get confused when domain models invoke other domain models that also try to start and commit db transactions. So which model really gets to decide if a transaction is committed or rolled back? And what do you do if a given model is used in different ways by different clients?

The Service Layer is a solution for this, because this is the layer in which you can start and commit work that involves multiple domain models.

As for how common this is, I don't think it's common at all. Most people using Zend Framework (or any other PHP or Ruby framework) have just barely moved from "Active Record solves everything" to the new shiny, "Data Mapper solves everything." It seems this community learns only one new pattern every five years. They won't get to Service Layer for a while.


Re comment from @ktutnik:

No, the Service Layer pattern is different from Repository pattern. Repository is about abstracting database access so you can use a database like a Collection. Service Layer is about encapsulating complex application operations.

Another way of thinking about them is their relationship to the Domain Model. The Repository is used between the Domain Model and the database. Whereas the Service Layer uses one or more Domain Models.

Service Layer --->  Domain Model(s) ---> Repository ---> DBAL
Bill Karwin
one other thing that usually confused me.. service layer and repository.. is it the same or different think? thanks
ktutnik
+5  A: 

Service layer advocacy is relatively new and still subject to a variety of interpretations. I think it means having a layer that leverages multiple domain models which the controllers call (I may be simplifying it too much though). I recently developed a website making use of this and practical advantages I've encountered are:

  1. Features as a service helps with scalability. If you have an image service that initially uses the local service to do it's work it becomes easier to have that service point to another server or some 3rd party without having to make sweeping updates

  2. Flexibility. Half way through the project I decided to change a core piece of functionality and was able to do so painlessly; allowing me to quickly weigh the pros and cons of the update. This flexibility is useful when rapid prototyping and instills a certain confidence because if you need to revisit something it's not going to be a nightmare.

  3. Extensibility. I have already identified services in my application what I can forsee opening to other developers or other widgets, mobile apps in the future. Doing so in theory is just a matter of adding authentication and authorization to the service (because the features are already in it's own layer and I don't have to spend time trying to decouple what I want to expose from the rest of the code base).

  4. Services are easy to add and drop (maybe this belongs with one of the earlier points). I have services that a specific to a specific stage in the project (e.g. invite only stage) that I can drop once that phase is over.

I think it has practical advantages and a key to success in implementation is having a good way to manage the services in the application. I use symfony's dependency injection component

Akeem
Re #2, can you give a concrete example of how you changed that piece of functionality (the before and after) just so it's easier to understand how a service layer works in practical terms? In #3, you sound like you're talking about an API and #4 sounds like a permission system. I'm still trying to get what this service layer is about and the right way to use it, so maybe that's why I'm falling back on those more known concepts.
jblue
2. I switched from using solr to mysql and back with no great impact on my models or controllers. (as a matter of fact I'm waiting for doctrine for doctrine's mongodb implementation to mature a bit before I give that a go and this is why I mentioned that it helps build confidence.
Akeem
3. I am talking about making some of my services available to the 3rd party devs or even my own mobile apps or other ways to consume the content.
Akeem
4. I am using as an example to show that leveraging a service layer makes it easy to add or subtract functionality (maybe same as point 2). But I am able to add or subtract services without making my entire application fail. E.g. I have an invitation service that I can just pull out by removing from the config and the app will continue to run nicely.
Akeem
A: 

see ZFEngine it's cmf on ZF with service layer realisation

dima