views:

54

answers:

2

I have business logic that could either sit in a business logic/service layer or be added to new members of an extended domain class (EF T4 generated POCO) that exploits the partial class feature.

So I could have:

a) bool OrderBusiness.OrderCanBeCancelledOnline(Order order) .. or (IOrder order)

or

b) bool order.CanBeCancelledOnline() .. i.e. it is the order itself knows whether or not it can be cancelled.

For me option b) is more OO. However option a) allows more complex logic to be applied e.g. using other domain objects or services.

At the moment I have a mix of both and this doesn't seem elegant.

Any guidance on this would be much appreciated!

+1  A: 

A common question, and one that is partially subjective.

IMO, you should go with Option A.

POCO's should be exactly that, "plain-old-CLR" objects. If you start applying business logic to them, they cease to be POCO's. :)

You can certainly put your business logic in the same assembly as your POCO's, just don't add methods directly to them, create helper classes to facilitate business rules. The only thing your POCO's should have is properties mapping to your domain model.

Really depends on how complex your business rules are. In our application, the busines rules are very straightforward, so we use Option A.

But if your business rules start to get messy, consider using the Specification Pattern.

RPM1984
Thanks. I have read about the 'Anemic Domain Model' which seems to be what you are proposing. I have to say this seems to go against my OO background but I can understand whay you might want to keep the POCOs clean in this way.
Nick
+3  A: 

The key thing about OO for me is that you tell objects to do things for you. You don't pull attributes out and make the decisions yourself (in a helper class or other).

So I agree with your assertion about option b). Since you require additional logic, there's no harm in performing an operation on the object whilst passing references to additional helper objects such that they collaborate. Whether you do this at the time of the operation itself, or pre-populate your order object with those collaborating entities is very much dependent upon your current situation.

Brian Agnew
Thanks Brian. Just to clarify the example I gave 'CanBeCancelledOnline' might be a requirement to enable/disable a 'cancel order' button on a form - so in this case I do need to 'pull attributes out and make the decisions yourself' (which I would argue does not go against the OO paradigm in many cases).
Nick
... Let us say (for example only) that for an order to determine whether it can be cancelled or not, it needs to know something about a customer contract. Again two options.a) an OrderBusiness class uses information (or logic) from both an Order and a Contract to determine whether the order can be cancelled. Or b) I implement order.CanBeCancelledOnline(Contract contract) and the logic remains in the Order class.I presume you would lean toward b) as the best approach?
Nick
If the order is related to a customer contract, then perhaps it has a reference to that contract implictly. So that's a third option (and the one I would prefer if valid)
Brian Agnew
Yes I guessed you might say that! If however - for the sake of this discussion - that there was no way of obtaining the Contract from the Order object would you still prefer option b)?
Nick
Yes. Absolutely. The intelligence is still in the Order object.
Brian Agnew