rdrunner wrote:
Hello....
I belong to the "other" crowd... I think you should "allow" invalid data inside your BO, but your BO must be able to let the GUI know that it is in an invalid state. If you inform the GUI on whats requiered for a new Person to be valid, then you are coupling the GUI very tightly to the BO and you will have a very hard time to get databinding to work.
Bi-directional databinding is made more difficult, absolutely. I'm fine with that condition, I don't mind writing a few extra lines on my UI to call methods instead of using an automated bidirectional databinding.
That being said another approach would be to use DTOs which are created by your BOs and accepted by your BOs. You could then use those methods there to tell if you entered invalid values. So in other words transient objects which are never persisted can be in invalid states, but not persistent business objects.
rdrunner wrote:
How about a "Person" object, and a mandatory LastName propperty?
If you create a new Person, you MUST Supply a Name... So by your rule you cannot do "new Person()" since that would lead to an object in an invalid state.
Yup, you got it, accept a name in the constructor or factory.
rdrunner wrote:
If the Object knows itself that a LastName is requiered, then you can prevent the saving of the object. So my Objects support an IsValid property, and to save an object you dont call session.Save(obj), but obj.update() (So the Object can throw an exception if the save fails, or is not possible due to broken constrains)
So what if you loaded an object from the data store, changed the last name to be blank and then flushed? Maybe you check in other methods as well and throw exceptions? Does that even work? If the session stays open every flush will try to perform this operation. You need to clear out the session after a failure like this. What if at flush only some objects are invalid? Does everything get rolled back? Must it be in a transaction? How do you handle this? Saving a single object is relatively simple, but complex operations can become, well complex.
I certainly don't want to trust UI code to verify the state of the object. Then I need to get into issues with my NHibernate code. But I don't want my business object to know it uses NHibernate. Therefore the only way to verify that the business object is valid when it is saved, is to have it ensure it is always valid.
Plus what if you set the last name to blank then call another method? What does that method do? Objects in invalid states can cause lots of downstream problems with methods that may be called prior to saving or updating.