I know there is no "100% correct" way to design the following but any suggestions or shared opinions would be appreciated:
I want to create a Customer business entity. Should this Customer class only contain properties and simple validation or should it also contain all the business logic and CRUD functions Should I create a separate class called CustomerService that handles logic by passing around and working with the Customer entity
Example: How to add a new Customer
1) All domain logic in one Customer object.
Customer.Name = "Bla"
Customer.Save
OR
2) Customer object to hold properties and Service object to perform business logic.
Customer.Name = "Bla"
CustomerFactory.AddCusomer(Customer)
What are the pros and cons of each approach

OOP Design Question - Need an opinion...
Urban Terror target
xian_ve
I would call it a matter of programming style, and these two programming styles have very little in common. If you are more familiar with OOP - which means you are used to working with abstractions, interfaces, design patterns, immutable objects etc... then a single Customer class is the way you should go. If you are more accustomed to static functions performing operations on data structures, then you should use one class as a data structure and a second static class for logic.
"Persistence related code" simply refers to code having to do with storing and retrieving in-memory data to some form of persistent storage (a reational database, a file, an XML stream, etc...).
lushdog
Sreenath, since this thread attempts to address OOP I should mention that static methods are not really object-oriented, and therefore are harder to mock in tests and generally increase coupling. So I would rarely use static methods for this purpose, and I don't see how this should influence thread-safety...
Arnon, general perpose persistence code definitely should not be a part of the customer object. However, specific code related to persistence of a customer object belongs in the Customer class. O/R mappers assume all specific code having to do with persistence of a Customer resides in the external interface (Properties, Constructor) or can be extracted with reflection. This is not always the case and forcing a design to support this paradigm is a liability.
darklightred
The more I read and research this topic the more it seems to be just a matter of prefference. The OOP purists would tend to put all logic and properties in 1 Customer object. However, others might layer their design by having the Customer business logic in a separate class that manages the "the property only" customer business entity. I would imagine both approaches would work fine and get the job done.
One thing to clarify: Can someone give a real world example of "persistence related code". I am just starting to get involved in design patterns and the jargon throws me off sometimes.
LiamD
Are you planing to reuse these business entities via other services If the answer is "not right now" then you are over-engineering.
What is the nature of these services and how do "light" objects help reuse them
"Light" entity objects are not used in OOP - they are used in Procedural Programming. Microsoft's samples are good for evaluating Microsoft's techologies and class libraries and not as a reference to proper OOP/OOD.
Species2175
OK. But one argument I hear is that these business entities should be "light" if you plan on resusing via other services. Why pack them with domain specific logic if you want share them with other applications.
The reason I bring this up is that I've been looking at the Microsoft PetShop v4 application and it uses this approach.
Prabagarane
Well, I guess I was worried what would happen If I wanted to resuse a Business Object in a different application. Lets say a Customer object. The object would contain all the business logic for the CRM domain. Maybe this logic would not be needed in my Sales System Domain. However, I would want to resuse the Customer Object's properties such as Cust.Name, Cust.Address, etc. I would not need Cust.UpdateSeconadryAddress().
Maybe you are right and I am over thinking this a bit. Does my above example make any sense How would you deal with this situation
Thanks for your help.
Eyalrev
My two cents. Like I've read somewhere in these forums, "it depends" on what the requirements of the application are. In my own opinion, I try to find a common best practice that accomodates upscaling or downscaling and use that as much everywhere as possible.
The issue I see here is the balance between the size of the object in respect of the fact that you'll be moving it around the application. I think it should be as lean and mean as possible. The business logic can be packaged seperately in a services layer.
Here's an MSDN article that's been of help
http://msdn.microsoft.com/library/default.asp url=/library/en-us/dnbda/html/BOAGag.asp
Again, I think it depends on what works for you. It would be nice to go with an approach that's most easily maintainable. If the application needs to be scaled up/out will the current approach have to be trashed.
In closing, I use lean, mean data objects, just properties. Then I have data access components that do the basic database operations and then some. Simply These are the only components aware of multiple database platforms. Then, I have the services(the business logic). They do funky calculations, multiple data entity update within transactions etc.)
Regards,
Bisi Akintunde
AndyPham
Thats really a good explanation.
Could you please highlight on which approach is better the one having static methods or having instance method Considering thread safe in multi user application.
What I need is basically is CustomerFactory.AddCustomer(Customerobject). Suppose addcustomer method does not change customer object then which is better
Let me know. I am sure you have good answer for this.
Thanks,
Sreenath
Naveeeen
Which is exactly why persistence related code should not be a part of the customer object (also see my blog on Single Responsibility Principle)
You can use O/R mapping to externalize the specifics of the persistence that are related to the customer
Arnon
R-Cyclone-S
In object-oriented systems reuse is acheived by programming to an interface instead of programming to am implementation. Once the Sales System Domain is constructed an interface will be defined for what a Customer represents in the problem domain. This may very well be similar to the interface defined for Customer in the CRM domain but not identical, as you've mentioned.
With polymorphism and design patterns you can reuse the Customer class in both systems, encapsulate the common logic that is relevant to a Customer in both systems and still provide the minimal interface in both situations.
I still advise you to wait until you actually require this feature and not get out of your way trying to support it now. Experience shows it is a lot easier to accommodate unpredictable future requirements when you accept the fact that they are unpredictable and focus on the quality of implementation of the known requirements.
I can also advise you to try and move as much logic as you can into the Customer class and remove its exposed properties in the process, this is in order to remove duplication and coupling exposed properties entail.
WinFormsUser13232
Tadwick
Amimoller
This is a very interested topic. I would like to add my opinion. I may be wrong (because I am not an OOP expert).
I used to program with option 2, i.e. Customer Class does not contain any method and it is just a data mapper. The reason is that:
1. It is logically not correct to, say, delete itself (Customer.delete()) or add to itself (Customer.add()). It should be done by another class, e.g. CustomerCollection.
2. I usually create an interface called ICustomerMethod and use another class (e.g. SQLCustomerMethod) to implement this interface. I find it very flexible. If I change to back end database from MS SQL to Oracle, I just create another class (e.g. OracleCustomerMethod) implementing the same interface. In this way, we only need to change the data access logic and we do not need to change the business logic. (i.e. Customer and CustomerCollection classes).