Let say we have an Order class and OrderManagerService class.
Order class: [some state and methods that act on the state]
Item[]
status
OrderManagerService class: [have no state. only following static methods]
createOrder
getOrder
Question: Let say we are using a relational DB in the back. Our goal is to update Order status. Well, the status need to get updated in the DB. My concern is where to put the updateStatus method.
Should I call OrderManagerService.getOrder then, call Order.updateStatus?
or create a new method as OrderManagerService.updateOrderStatus?
well, 1st option seems following encapsulation. But, personally I dont like it as we may end up calling DAO layer from entity objects [perhaps, that might be ok]. Wondering what would be a right design choice and why? any help is greatly appreciated.
Option 2 - create a new method as OrderManagerService.updateOrderStatus?
Why?
Your service layer should encapsulate the logical business unit of work and in your case the UOW is
get the order from DB
update the status of the object
persist the changes
and you would demarcate the updateOrderStatus(...) with a transaction. and the service is still stateless.
I think OrderManagerService should have an array of Order class items. This way you could iterate through each item and update the status there. Or if you are looking for accessing a single order item go directly to it via the Order class and update it there.
In either case with your current setup the updateStatus() should be in the Order class.
How about observer pattern?
updateStatus() would be in Order class, which would be observed by OrderManagerService class.
Each time you changed status (or anyting else) Manager would see it and do some actions if needed (for example update the status in the DB).
The manager could bind to Order when creating an instance and returning it in getOrder() method.
You could also implement some method to unbind Manager from an order if an instance of the order is destroyed (concern only in unmanaged languages).
Since the title of your question contains "using object-oriented design", I'd put the state transition logic in the Order itself because objects are supposed to encapsulate behavior in addition to data.
Having all behavior contained in Services can be likened to an Anemic Domain Model, which is up to you to decide if it's a bad thing or not - there's a lot of debate over that.
Why is there a separate OrderManagerService class? I'd bung all those methods into Order.
(That's probably not theoretically correct or gang-of-four-compliant design pattern but I dn't care because it would make more sense.)
Related
It seems that Spine's Model.updateAttributes only updates attributes, and does not create new ones in case you supply any.
In my usecase, I have a controller that creates part of the attributes. Then through an Ajax request the server responds with the full object, and I want to update the model instance living in Spine with the additional variables.
For example, I have a model with attributes: name, date_created. Through the controller a user instantiates an object providing only the name. An Ajax request notifies the server which in turn responds with a name and a date_created. This date_created should then be added to the user's model.
Model.updateAttributes doesn't work, and I wouldn't be too fond of deleting the object and creating a new one - that just seems as too much overhead. I could provide default values for variables that are not set upon creation, but that also has a negative side. I guess what I'm looking for is a method that could be called Model.createOrUpdateAttributes. Can anybody recommend a way to achieve this? Thanks!
I might haven't fully understood your usecase, but I'll try to answer.
You need to declare whatever attributes a type of a model has with the configure class method. This declaration helps various model function to do their job later.
After you declare all the attributes you need, you can create model instances with any of the previously declared attributes.
You don't have to provide values for all the declared attributes.
After the ajax call returns, the date_created will be set on your model instance. Until this happens it will be just undefined.
If this solution still can't work for you, please describe why, and I'll gladly try to help.
i have a general design question.
we have a fairly big data model that represents an clinical object, the object itself has 200+ child attributes in the hierarchy.
and we have a SetObject operation, and a GetObject operation. my question is, best practice wise, would it make sense to use that single data model in both operations or different data model for each? Because the Get operation will return much more details than what's needed for Set.
an example of what i mean: the data model has say ProviderId, and ProviderName attributes, in the Get operation, both the ProviderId, and ProviderName would need to be returned. However, in the Set operation, only the ProviderId is needed, and ProviderName is ignored by the service since system has that information already. In this case, if the Get and Set operations use the same data model, the ProviderName is exposed even for Set operation, does that confuse the consuming developer?
It would say: it depends :-)
No seriously. How do you edit / work on the object? I assume your software is calling the WCF service to retrieve an object, using an ID or a search term or something.
So you get back the object with 200+ attributes. How do you work on it, how much of it do you typically change?
If you typically only change a handful of attributes - then maybe having a generic SetProperty method on the service that would take the object ID, a property name, and a new value, might make sense. But think about how this is going to work:
the server side code will get the ID for the object
it will load the object from the database
it will then set a single property to a new value
it will save the object back to the database
What if you update four properties? You'd go through 4 of those cycles. Or: you could extend the SetProperty method to include a dictionary of (property name, value) pairs.
So I guess it depends on how many of those 200 properties are you changing at any given time? If you change 10%, 20% of those properties - wouldn't it be easier to just pass back the whole, modified object?
This looks like a good candidate for using your clinical object as canonical model and providing a restful style service interface. You can then provide different views, or representations of your your data object with only the fields required based on the usage model. Your verbs (get, set) will become the http standard Get, Put.
There are a number of open source Rest frameworks that you can use to make this easier to get started. Restlet is one that I have used successfully.
In my application I have a situation where we need to capture the when a record was created and modified and what user performed those actions. So I might have an object something like:
public class Product
{
int Id;
int Name;
DateTime CreatedOn;
int CreatedByUserId;
DateTime LastModifiedOn;
int LastModifiedByUserId;
}
What's the best practice for handling these in NHibernate? Via using an interceptor something like what's described here?
I don't think there's a "best" practice, but the use of event listeners is more common for this. There's a good example at http://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx
One thing you'll need to consider is that you need to store that userId somewhere. I'm currently doing that by assigning a static property on the listener on startup. It's not pretty, but it gets the job done.
I agree with Diego that I don't think there's a best practice. It depends on your application context. In Diego's link, and to use event listeners at the persistence (nHibernate) level, it needs to know how to lookup the current user. This may not make sense depending on your application. For example, if you're writing an ASP.NET MVC app, do you really want your persistence layer to depend on HttpContext to know the user? Yes, you could pass in some type of strategy, but this doesn't seem like it's always going to be the right thing to do.
I think it's perfectly valid to have your service layer construct the object and add the creator itself. Then pass the whole object, with the creator already hydrated, down to nHibernate to persist. The creator would be saved to the database the same way as any other property.
Prior to persisting updates to my business entities, I need to perform validation checks to determine which properties have been changed. For example, certain fields can only be updated when the "Status" property has a particular value. E.g. when an Order entity has a Status of finalized, only the notes (string) field can be updated. Is this sort of thing possible using NHibernate, or should I be tracking the changes myself in the Business entities?
If I understand what you're trying to do, Gabriel's solution is not quite what you need. If it is not, you can try an event listener. Those allow you to hook into a common event (like on save) and do some processing before NHibernate finishes the save/insert/update/delete. Alternatively, you could look into using interceptors by implementing the IInterceptor interface.
This sort of thing is indeed possible. Coding Instinct has a great post introducing NHibernate.Validator.
I'm used to the layout that LLBLGen gives when it generates objects based on a database structure, which might generate the following class files for a given "User" table in the database:
/EntityClasses/UserEntity.vb
/CollectionClasses/UserCollection.vb
This provides some base functionality for data access. However, when you want to implement business logic on top of that, how are you laying things out? For example, given a table structure that might look like this:
USER
userId
firstName
lastName
username
password
lockedOut
What if you wanted to lock out a user? What code would you call from the presentation layer? Would you instantiate the UserEntity class, and do:
User = new UserEntity(userId)
User.lockedOut = true
User.Save()
Or would you create a new class, such as UserHelper (/BusinessLogic/UserHelper.cs), which might have a LockOutUser function. That would change the code to be:
UH = new UserHelper()
UH.LockOutUser(userId)
Or would you extend the base UserEntity class, and create UserEntityExt that adds the new functionality? Therefore, the code from the presentation layer might look like:
User = new UserEntityExt(userId)
User.LockOutUser()
Or... would you do something else altogether?
And what would your directory/namespace structure and file/class naming conventions be?
I think what you are looking for is a service layer which would sit on top of the domain objects. You essentially have this with your second option although I might call it UserService or UserTasks. By encapsulating this LockUser process in a single place it will be easy to change later when there might be more steps or other domain objects involved. Also, this would be the place to implement transactions when dealing with multiple database calls.