Does business logic belong in the service layer? - google-app-engine

I've got a set of classes, namely, a data transfer object, a service implementation object, and a data access object. I currently have business logic in the service implementation object; it uses the dao to get data to populate the dto that is shipped back to the client/gui code.
The issue is that I can't create a lightweight junit test of the service implementation object(it's a servlet); I think the business logic should be elsewhere, but the only thing I can think of is putting business logic in the dao or in yet another layer that goes between the dao and the service implementation.
Are there other options, or am I thinking about this the wrong way?
It's a GWT/App Engine project.

I don't understand why you can't unit-test the servlet, e.g. as per this SO question (there are others on similar themes) -- can you please explain?
Edit: if there's no special reason, I suggest you should the business logic in the service layer (where it seems to belong) and unit-test it there -- the approaches suggested in the SO question I just quoted, for example, seem reasonably lightweight (though I didn't test them specifically).

You can put your business logic in it's own jar file and test this component independently from the integration with the web (servlet)
The servlet is just a protocol, it is not your business logic, more an integration point.
It must be easy to imagine to expose your same business logic through a thick client.
Also in that case, you should not hide the business logic under buttons or links.
One more note: you might want to look into the MVC framework; struts. Your model will hold the business logic.
Hope this helps.

The servlet is the controller , it is a very big mistake, to put the business logic there.

Related

CakePHP - where to put service logic

I am Java programmer who tries to investigate CakePHP - currently I have problem with application structure/design. I could not understand where to put core logic of application.
When I am developing in JavaEE, common approach looks like following:
Model classes are simple beans which represent data entities (products, people etc) - mostly like data structures with getters/setters;
Controller classes are simple enough classes which aggregate necessary data and inject them into dedicated View template which is then sent to user;
DAO (DataAccessObject) or Repository classes are ones which can load and store entities into database;
Service classes are usually singletons which contains certain business-logic methods - these are called by controllers, by other services or by scheduled actions, on the other hand they themselves call DAO / Repository methods to fetch or modify data.
For example if I have entities Person, Product and Order, when user selects some product and clicks "put it into my cart/basket" new Order for this Person should be created and this Product should be added to this Order (we may check that Person is not bad debtor and that Product is present at store etc.) - all this work is performed in methods of OrderService called by some controller.
Usually some kind of IOC (Inversion of Control) is used so that all services and controllers have links to necessary services etc.
Now I am slightly bewildered about how this all is done in CakePHP. Where should I put this business-logic etc. ?
In CakePHP the model layer is made up from collection of active record instances, called AppModel. They combine the storage-related logic (that you would usually put in DAOs and/or Repositories) with business logic (what usually went into your "models").
Any other domain related logic (from your Service) becomes part of controller.
If you want to know, how you are supposed to implement domain business logic in CakePHP, just look up articles which praise active record pattern.
Personal opinion
CakePHP and CodeIgniter are two of the worst frameworks in PHP. They are filled with bad practices.
Actually, if you were doing correct-ish MVC, then model layer would contain all of the business logic and everything that is related to it. Model layer is made of DAOs, Repositories, Domain Objects (what you call "models") and Services.
While your descriptions of Java-based code indicates, that you are kinda moving in that direction, CakePHP is not even remotely close to it.
Then again, it might be that my understanding of MVC is just wrong.
The controllers should only contain logic relevant for the whole thing being a web application. Your business logic belongs into the models. I think it is one of the basic mistakes that you find in many cakePHP applications, that to much logic is put into the controllers, which actually belongs into the models.
In CakePHP. the "M" is just a bunch of Data Models instead of Domain Models.
In my opinion. CakePHP is made for RAD development. It is not a good fit for enterprise applications.
My opinion though.

unit testing restful webservices

I am wondering if anyone knows the proper way to unit test a restful webservice. I have a set of webservices built using recess, and I would like to write test code for them. Unfortunately, since my webservices are tied to a database, my tests end up populating the database which seems like a problem.
I am mostly asking about the proper approach to dealing with this from a unit test standpoint. Do I clear the database of the values I have inserted after testing? Do I have a special test database with a whole set of special test routes? I am at a bit of a loss for the best way to approach this.
Obviously in other cases of similar database wrapper classes you would just pass in a dummy database that you set up at the beginning of the tests. This seems like it would be much more challenging though when it comes to working with a restful framework like recess.
I'd appreciate any thought you all might have on the right way to deal with tests saving information to the database.
Thanks in advance.
Generally when testing a web service you are testing the full stack, from the outside in. This means you request a resource and check if the results conform to your expectations.
In nearly all cases populating the database right before every request is a good approach. It might seem like overkill, but in reality with a web service you can't guarantee proper test coverage by mocking/stubbing various elements.
Coming from the Ruby world, Cucumber is the ideal approach as it lets you test from a high level. When you combine this with Rspec to do actual unit testing (lower level tests that query your objects directly) you get the best of both worlds. These libraries even come with something called 'database cleaner' which will manage populating and depopulating the database for you.
You might find the following blog post by Rspec's author very helpful, as it explains brilliantly why you should avoid too much mocking and stubbing. http://blog.davidchelimsky.net/2011/09/22/avoid-stubbing-methods-invoked-by-a-framework/
Generally speaking you have two options:
1) Use a dedicated test database with known data on which you can set your expectations - replace the DB with a "pristine DB" before starting testing. This would be considered integration testing since you are in fact dependent on the database.
2.) Make your code independent of the actual data store and pass in the dependency to the persistence layer. For unit testing you can write (or mock out) a custom persistence layer/object that allows you to observe the state changes that your are unit testing.
A healthy mix of both depending on the scenario usually provides good coverage.
Also instead of testing your Restful web service consider just delegating to a POCO within each service endpoint and then just test these POCOs directly - much easier testable and all you have left to do is verifying the mapping between service endpoint and POCO.
My understanding is that if you do your tests in this order you can test all the verbs but there will be no additional data in the DB at the end.
POST ( add a new record)
GET ( fetch the newly added record)
PUT/PATCH ( modify the newly added record)
DELETE (delete the newly added record)
Of course somebody else using the database at the same time might see transient values during the duration of the test.

Business logic not on the presentation tier

In a RIA application you are supposed to put as much business logic as possible outside of the RIA layers (flash/silverlight etc). What is the reason behind this? Any logic that goes into the presentation tier gets the benefit of executing faster...
Is this because the RIA technology will most likely need a face lift down the road and you will have to rewrite all the business logic?
I'm not sure I agree with your premise, that you're "supposed" to put business logic outside the client. You are supposed to move the business logic outside the UI layer, but there are typically still a couple client-side layers left before you hit the back-end web service. A typical Silverlight application, for instance, is based on the MVVM model, which prescribes a View that has no business logic, a ViewModel which has a pretty good chunk of validation and business logic, and a model, which has the rest. And all of that is on the client side.
On the other hand, you really need a business logic layer on the server as well. You can't rely on a client-side application to filter out all the bad data: someone might be running an old version of the client, or a different client entirely, or might be trying to hack your system.
In other words, ideally, you should have your business logic and validations executing on both the client and on the server: on the client, because you need responsiveness, and on the server, because you need security. The question is how to get this, and there aren't any perfect answers.
One approach commonly taken in Silverlight applications (I'm less familiar with Flash) is to use WCF RIA services, which allows you to create validations in one place that are executed on both the client and server. Even if you're not using the WCF RIA Services framework, you can still get much of the same effect by linking to the source code of your validation/business logic classes on both the client and on the web service -- it's more work, but still probably less work than writing your validations twice and keeping them in sync manually.
Business Logic is a cross-cutting concern.
Will your users be entering dates? If so, the interface needs to know they are dates to give them a picker, and to prevent invalid entries. Maybe even restrict entries to a range. That is business logic. How can you keep it out and still have a meaningful interface?
Will users be entering at any time a US State or a Province? If so, the drop-down list will have to be populated, and that means the UI "knows" about foreign keys.
Will there be fields the user can see but not change? Why or why not? That is business logic. Will there be limits to what certain users can do based on certain conditions? That is business logic.
This does not mean the UI knows about all business logic, of course, many data-moving operations have nothing to do with the UI.
But in the end the question is not how to keep BL out of the UI, you cannot do that, the question is which kinds of BL will be in the UI. That tends to come down to types, ranges of values, allowed operations, and so forth.
So either the UI gets all of that information from a lower tier, or some of it is reproduced in the UI layer.
So, one reason is maintainability. If the client is already distributed everywhere, you don't need to require a re-install or re-download when a simple business rule changes. Simply deploy the change to the back-end and you are all set.
It also lets you do things like hide your database behind your firewall. If all of your business logic is in the front-end, it is likely that you need to expose the database publicly so that the business logic can be executed on the client.
But I fear that "business logic" is an overloaded term. What is "business logic"? The right architecture is the architecture that makes most sense for your application and needs.
As #Ken Smith said, you should certainly avoid business logic in your UI layer. This is for testability, maintainability, designablity, etc. But this does not mean that everything goes to the back end, especially in a RIA app with significant UI rules. In an MVVM app (Silverlight) or Presentation Model app (Flex), you put UI BEHAVIOR in the ViewModel or PresentationModel layer. Then, you put whatever level of business logic makes sense in your Model. That business logic might just be some validation. It might be more. That is dependent upon your architecture.

How to call operations other than CRUD in RIA Domain Service?

I have some trouble getting my head around how to implement more complex operations in a Domain Service in RIA Services. This is all Silverlight 4, VS 2010 and .Net Framework 4 in Beta 2.
Goal
I wish I could create an operation on my LinqToEntitiesDomainService that would have a signature something like this:
public UnwieldyOperationResult PerformUnwieldyOperation( UnwieldyOperationParameters p );
The idea is that this operation takes a colleciton of parameters and performs rather complex operations which would update different instances and types of the entities that are otherwise manipulated through the DomainService CRUD functionality.
Problem
The immediate problem i hit is that does not seem to be allowed to pass the custom type as parameter to the method, and I suppose something along those lines go for the return value. I want to encapsulate the operation parameters in a DTO for clarity, and this unwieldy operation does not have any corresponding entity in the legacy database that I have wrapped with Entity Framework 4.0 model, which I am in turn basing the Domain Service on.
Is a domain service supposed to deal with only the types that are entities in the underlying EF model? Is it not designed to expose more complex operations like my UnwieldyOperation?
If so, can I build another service somehow that allows both the operation signature and to manipulate the entity framework?
I have understood that only one Domain Service can handle an entity from the model. This has led me to cram all the CRUD and now also the UnwieldyOperation into one Domain Service, although my first idea was to split the service into smaller parts.
If I'd get the operation to work with parameters and return value in the Domain Service, my next wish would be to have the entities that are already loaded in the domain context at the client refresh themselves.
Is there any efficient mechanism for such a thing?
How would you go about to do that?
What I have so far...
In short, this is what I have so far:
I have wrapped an existing legacy database
with an Entity Framework 4.0 model with as
little extra padding/code as
possible. This means right-click, add and generate from database.
I have implemented the simpler CRUD operations in the DomainService and I am using them successfully to display and edit straight forward data. I have some encapsulation of logic through ViewModels in client but I expose the Entity classes directly, but I think this is unrelated to my problem/question.
I have realized that I can't add the UnwieldyOperation in an as straight forward manner as I initially thought... Also I suspect/hope that I have misunderstood some aspects of the Domain Service mechanism, which has led me to the current situation.
One way to go?
Writing this down in a question like this gives me the idea that perhaps I'd go in this direction:
LegacyModelService expose the CRUD operations as I have already done.
Expose the Unwieldy operations in another service. Should I make that a RIA Doamin Service or just plain WCF?
Access the Entity Framework model from the new UnwieldyOperationsService and manipulate the data layer there.
Explicitly reload or refresh the client domain context for the LegacyModelService at the client to reflect the changes that may have resultet from the UnwieldyOperation. What would be a good way get this done?
Check out http://msdn.microsoft.com/en-us/library/ee707373%28VS.91%29.aspx for naming conventions over and above simple CRUD, maybe Invoke or Named Update operations would be suitable?

WCF multiple data contracts or multiple service contracts representing multiple data model classes?

In my WPF application data model I have multiple classes representing data for interaction with backend DB through WCF self hosted service.
Should I have multiple Data Contracts or multiple Service Contacts or Endpoints in my WCF Sevice for representing these multiple WPF data model classes? What is correct (or maybe the only) way to architect WCF in this case?
There is a design recommendation called Interface Segragation Principle which basically states what the iDesign WCF Coding Standards also say: don't make your interfaces (= your service contracts) too big and too unwieldy.
Consider this: you have a huge service contract with hundreds of methods, and some third party would like to implement a subset of functionality, maybe only two or three of those service methods. If you have a single huge service contract, they would have to implement their 3-4 service methods of interest, and all the others, they would have to stub a dummy - e.g. something like throw new NotImplementedException(); or something. This is not a good idea, in general.
So the basic principle should be: try to group your service contracts in such a way that if ever someone else needs to implement a subset, they most likely will find a single service contract that has all the methods they need, and nothing else. Try to group your service contracts by topics, e.g. if you have 6 methods to search addresses, put those in a separate service contract. If you have 7 other methods to insert new addresses, update and delete existing ones - that should probably be a separate service contract (since you could well imagine someone wanting to only search for addresses - not modify anything).
So I guess there's no real hard rule what is good or not - try to group your service into "logically connected" groups of methods. That's not an easy thing to do, for sure! But it's worth the effort to think about how others might be using your services.
Also, if you have a few smaller service contracts, it's also a lot easier if you ever need to change anything. If you need to introduce a breaking change into a service contract, only those (hopefully few) users of that particular service contract with a few methods will be affected. If you always have to change your huge 200 method service contract, you'll always affect everyone - that might not be a good thing!
In WCF terms a data contract is a class used in a service contract operation. It's called a data contract because it is usually annotated with the DataContractAttribute in order to be recognized and serialized successfully (although starting from .NET 3.5 SP1 DataContractSerializer works with POCO objects and this attribute is no longer required). So you could have a single service contract with multiple operations dealing with multiple data contracts all exposed in a single endpoint.

Resources