Splitting up services -> Business Objects?
I believe I structure my projects like many people do. You have a data layer (DAO's), service layer (services) and presentation layer (Spring MVC, Wicket, ...).
Usually a service starts of being quite simple and 'short'. Gradually however the service must support more and more use cases until after a while it becomes one huge class with many lines and methods and difficult to read and maintain. At that time you can either decide to stick with it or start refactoring which is a cumbersome and 'dangerous' job that can take a lot of work.
I am looking for a solution in how to prevent the need for any future refactoring.
One approach could be splitting up your services in several sub-services and make your original service a service façade. So, for instance, instead of a big UserService you could have a UserServiceFacade which delegates the calls to PasswordService, RegistrationService, ... .It's not a bad solution I think but I'm not too enthusiastic about it because:
- difficult to define in advance in which subservices to split the work; if you missjudged, you might still need te refactor aftwards or have a Service with only one method for instance
- reuse of Business Logic can be more difficult if for instance PasswordService and RegistrationService require common functionality
Another solution might be using Business Obje开发者_如何转开发cts which (in my understanding) can also be seen a subservices but then one per specific UseCase, so you might have BO's like CreateUserBO, CheckPasswordBO, DeleteUserBO, ... .
I'm a bit more enthusiastic about this approach because, in my opnion, it offers quite some advantages:
- the BO itself is very readable and only does with it's contract requires it to do; all the rest can be delegated to other BO's, a single BO will be short and to the point
- Easy to reuse functionality
- Easier to change/switch the implementation of a certain UseCase: just inject another implementation with Spring
- Easier to test: only need to test to specific UseCase, delegations to other BO's can be mocked
- Collaboration: less conflicts if several developers work on different BO's then when they work on the same service
I do however also see some possible downsides:
- a bit extra work (in the sort term at least)
- Much more classes which could decrease the readability of your project?
- one more abstraction layer: an extra step is required to find the actual implementation of a UseCase
The question or rather questions (sorry) are:
- Are Business Objects the ideal solution for this problem?
- Do you agree with the advantages/disadvantages of BO's that I list above and/or do you see other?
- Are there other (good) solutions to prevent mega services ruining your day?
I would recommend you to look at this article on Domain Driven Design if your application is anything serious than college assignment. The basic premise is structure everything around your entities and have a strong domain model. Differentiate between services that provide infrastructure related things (like sending email, persisting data) and services that actually do things that are your core business requirments.
I would also suggest to explore Spring Roo - which brings in some revolutionary stuff in as far as strcuturing your layers are concerned like not having to need DAO layers etc.
Hope that helps.
With the first approach you mention, instead of creating a 'facade', why not just extend that service? In that sort of situation you'd be able to reuse code from the super / original class.
I think if one organizes their package structure in a readable fashion, then having a number of smaller classes is certainly preferable in any case to have large classes that take on a lot of functionality and as such are more at risk for changes.
In the end I think both approaches are pretty similar, with either you can end up with a high degree of code reuse, and if you need to update something structure-wise, then its pretty easy to make global change (relatively speaking), and also easy to make specific implementation changes.
What I personnally do is that I always use a facade for my services. The logic is in internal classes of the service, but I provide an interface that client of that service can call.
I try to avoid from the begining to put any logic in the facade. It is just boiler plate code that redirect to the proper code logic.
So even if your service has many features, the facade is quite maintenable.
But if you control your whole source base, you should not hesitate to refactor and subdivide if you start to have too many features in one service. Even if you use several classes to do the job, clearly separate your service will be better in the long run.
精彩评论