I have an object with a large number of fields. A bunch of these fields can be logically grouped and are actually named that way via prefixes (i.e. in a “Project” object there are fields ProjectManagerFirstName, ProjectManagerLastName, etc).
From your experience should these groupings be broken out into their own objects?
It kinda depends. The short answer - at least from me - is that I'd do it. If there's any chance that the group of properties will be re-used anywhere, then obviously the answer is yes. Outside of that, I find that taking those properties and grouping them into a "value object" can be very useful. If nothing else, it helps to simplify the property names, and it shows the user of the main object that the properties are related. Plus, you can isolate any business rules in relation to those properties - but if you have properties outside of this "value object" that depend on one or more of its properties, that makes the idea less attractive.
Some people complain that it makes your object graph deeper (i.e. more complex) for no real gain. But I don't see it that way.
It can make your data-access code a little more complicated, depending on how your database is structured. Basically, your DP_ methods on your main object have to constitute and populate these "value objects", and pull their values out for sending back to the database. It's not so bad if, in your example, your "ProjectManager" data is in a separate table from the other data - then they basically become standard child objects. But if all the data is in one table, then you have to develop a scheme to pass data in and out. But that's not that difficult.
Thanks Scott! Yeah, it seemed like it would make sense to break them out.
2 follow ups:
1)I'm building a web app right now. I can see data binding being a little painful with asp.net's limited implementation. Have you ever built a web app with a model that had these "deeper" graphs? How did you handle the two way binding?
2) I'm not too worried about the data-access. As you mentioned it should be relatively straight forward. But I'm a little worried about some gotcha's in the UI usability. Any heads up on some pain area's created by this logical simplification would be a real help. For example, have you run into any difficulties with broken rules being spread across the object graph instead of just having to look at one object (the parent)?
Well - data binding can affect what you do here. Objects like these won't bind under the parent BindingSource, so if you expect to show the data all in one big group, creating these "value objects" could turn out to be a pain.
(BTW, I got the term "value object" from a patterns book. Under the technical definition given there, these aren't value objects - value objects are more like structures. But grouping these properties into a single object, of which there will only ever be one associated with its parent, is closer to the "value object" concept than the "child object" concept to me. Money is a typical "value object" concept - an object with value and currency properties. It never exists by itself - it will always be the child of some other object - but it encapsulates an idea. I realize you could say the same thing about a standard child object, but you'd never have a "Money" table in your database.)
Anyway - if you plan on binding to these objects, then they do have to be CSLA-style child objects. They would have their own BindingSource, and your binding techniques - ASP.NET or otherwise - are the same. Of course, that means you have to follow the parent/child binding techniques, which makes things a little more complicated, especially if you have multiple value objects.
If you also have rules that span objects, then you may want to discard the grouping idea. You can certainly write custom rules that span objects, but now you're beginning to create a situation that is making your life harder, not easier. Your business layer exists in part to help your UI get the job done, not make it artificially harder. Plus, if you have to write a bunch of custom rules because you have dependent properties that span objects - well, that's code you probably wouldn't have to write if you just flattened your hierarchy.
Typically, the reason I make these objects is because the properties can be completely encapsulated with their appropriate business rules, thus forming a "logical whole" that is probably separated in the UI in some fashion anyway. And I have written some code in my base WinForms form class that mostly manages the parent/child thing for me, so I don't have to think much about it. This makes life easier for me - but you wouldn't have a similar situation in an ASP.NET app, because data binding is done differently there.
In reference to your other question, while 2.0's two-way binding is certainly an improvement over 1.1, I don't use it on the web apps I do write. Perhaps it's just a level of inexperience with it, but I still find it pretty finicky, and not much better than writing my own code. I know that Rocky has written classes to help (i.e. DataMapper), but I have seen so many messages in so many forums (including this one) regarding issues just with making two-way ASP.NET binding work that I avoid it. It also doesn't help that my main area of web focus at work is still a .NET 1.1 web app, though that will change soon.
I know the same situation happened when WinForms data binding was first introduced. ASP.NET binding is just behind the curve. Maybe it will get better (or already has - I haven't had much of a chance to dig into 3.5 yet.) But even knowing that, whether you use CSLA objects or not, ASP.NET's data-binding techniques are still rather primitive, IMHO.
In ASP.Net 1.x I used Rick Strahl's original idea of deriving each control and adding code to it. He improved it a lot in 2.0 using Extender Controls. This saves you from subclassing and gives you 2 way databinding plus some other benefits.
Thanks for all the info! It does seem like databinding is going to affect what I do here (wish I was using win forms *sad face*). I agree, it does seem like asp.net binding is behind the curve. I feel like I spend a ton of time on tedious infrastructure stuff that should "just work".
Thanks for the heads up. Yeah, I like that control. I'm using it now actually. I wish it had a more strongly typed experience but how can I complain. Rick = the man for releasing that.
Copyright (c) Marimer LLC