Design: Create a child object or no?

Design: Create a child object or no?

Old forum URL: forums.lhotka.net/forums/t/2677.aspx


MarkHildreth posted on Wednesday, April 11, 2007

Hi.

First of all, thanks for this framework and the community build upon it. Without having even made a post I've already learned a good amount about CSLA.NET, as well as .NET in general, C#, and object-oriented design. I have chosen to start using CSLA.NET as a branch in my low-traffic company, with plans to perhaps in the future replace the existing intranet site to contain all ASP.NET and CSLA.NET.

Second, please bear with me as I go through my teething phase. I hope to in the future be able to give back to the community :P

I guess I'm having trouble getting away from "coding for reuse", as has constantly been talked about. Hopefully you can provide me with some insight on the correct implementation.

I am writing a Bug-tracking program (to use to build up my CSLA.NET skills first, nothing for the company yet). Each "Bug" has the following attributes:

Most of the fields are self-explanatory (I've used a "NameValueList" for severity), but Status is not simply Open/Close boolean. Instead, it's a series of different values, and each value is then either open or closed. I've placed whether it's considered open or closed in parenthesis.

While going through the process of making a list of bugs (or doing any other class for a use case) my initial reaction was to use the NameValueList for the status. That meant, however, that whether the status is open or closed means it would be simply a string/int pair. Next idea was to make a new object that encapsulated all the Status info into a class as a ReadOnly business object, and have any Bug class use an object of that class as a member. I believe that that, too, is incorrect.

Now I'm going on having the Bug business object I'm working on have it's own Status value which uses a NameValueList. The actual boolean value of _open will be determined through the SQL statement in the data access area of the Bug class. The sql will do a simple join of the tables so that the _open member variable is actually read from the database in the Bug class.

I guess my first question is: Am I on the right track with this thought process? The problem I see is when I change my status. Right now, I would have two members of the Bug class:

Since I'm tying the idea of status and open together, it would seem to me that I've done something wrong, as since the status would change I would have to do a lookup on the database to determine what I should change _open to. Although I don't think that would be that big of a deal, I'd like to avoid it.

RockfordLhotka replied on Wednesday, April 11, 2007

NVLB exists to simplify the common case where you have name/value pairs. In your case, it sounds like you have a name/value/value scenario, and so NVLB isn't so useful.

But that's OK. NVLB is merely a ReadOnlyListBase that contains a list of ReadOnlyBase objects, where the ROB objects are pre-designed to contain only a name and value.

You can create your own ROLB/ROB where your ROB child objects contain name, description value and open/closed value.

MarkHildreth replied on Wednesday, April 11, 2007

RockfordLhotka:

NVLB exists to simplify the common case where you have name/value pairs. In your case, it sounds like you have a name/value/value scenario, and so NVLB isn't so useful.

But that's OK. NVLB is merely a ReadOnlyListBase that contains a list of ReadOnlyBase objects, where the ROB objects are pre-designed to contain only a name and value.

You can create your own ROLB/ROB where your ROB child objects contain name, description value and open/closed value.



Thanks for the quick response.

But would I want to make it a child object to the Bug class? I probably should have mentioned this, but the statuses are One Status -> Many Bugs, so while i want to be able to have a bug change what status it is, I don't want it to be able to change what available Statuses there are, which I believe is what a child object would do. To dip into the database, I have a table of bugs, and each one has an id that is a key to a record in the Status table. If I implement the Status as a child object, and want to change the status of a bug, I would have to change something in status object, which is read-only.

In this case, I'm thinking I would still use a NVLB, but create a StatusInfo object in replace of the typical string, and I could use a property in Bug such as...

Bug.cs:

[Serializable()]
    public class Bug : BusinessBase<Bug>,
        IHoldsSeverity,
        IHoldsStatus
    {
        #region Business Methods

...

        private int _status = StatusList.DefaultStatus();

...

       public bool IsOpen
        {
            [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
            get
            {
                CanReadProperty(true);
                return StatusList.GetList().Value(_status).IsOpen;
            }
        }
...
}

Would this make sense?


Note: I originally had "return StatusList.GetStatus(_status).IsOpen;" for the emboldened line, but I've fixed it. I then proceeded to "fix" it about three more times :P

RockfordLhotka replied on Wednesday, April 11, 2007

For things like name/value lists the “whether to make it a child” rule goes like this:

 

If the list of options does not vary object-to-object then it should be global (probably cached), not a child of each object.

 

If the list of options varies based on the state of each object, then it should be a child of each object. In this case you’ll typically expose the list of options as an instance property of the object so the UI can get the properly-filtered list from the current object. Also, the object can then use that property-filtered list for validation or other internal uses. Finally, the object can encapsulate the process of refreshing the list based on changes to the object’s state that would invalidate the current list of values.

 

Rocky

MarkHildreth replied on Thursday, April 12, 2007

RockfordLhotka:

For things like name/value lists the “whether to make it a child” rule goes like this:

 

If the list of options does not vary object-to-object then it should be global (probably cached), not a child of each object.

 

If the list of options varies based on the state of each object, then it should be a child of each object. In this case you’ll typically expose the list of options as an instance property of the object so the UI can get the properly-filtered list from the current object. Also, the object can then use that property-filtered list for validation or other internal uses. Finally, the object can encapsulate the process of refreshing the list based on changes to the object’s state that would invalidate the current list of values.

 

Rocky



Makes sense. Thanks!

Edit:

For posterity, in the end I made the list as a global NameValueList, but with my own Status class that inherited from ReadOnlyBase as the value instead of the typical string. This was fine until I tried binding the list to the dropdown box, where I had to make sure to override the ToString() function in the status class. This would return the description so that the combo box values would fill up correctly.

Copyright (c) Marimer LLC