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?
相关问题
- Views base64 encoded blob in HTML with PHP
- how to define constructor for Python's new Nam
- Laravel Option Select - Default Issue
- PHP Recursively File Folder Scan Sorted by Modific
- Keeping track of variable instances
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 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:
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
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.
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).
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
See ZFEngine it's cmf on ZF with service layer realisation