2

I know that it is poor programming and architecture when you have a class object that is only to be used in one place. But I've also been warned about creating an object that is all powerful and that can do too much. So how do I break this down? Here is an example of what I mean - please don't take these things literal as this is only an example.

Anyway I have an object that I am working with which is rather complex. A lot of information is stored in this object and it can perform much manipulation on the data. So, let's call this object Earth.

Public Class Planet
Private _population As UInteger = 0
Public ReadOnly Property Population() As UInteger
    Get
        Return _population
    End Get
End Property

Public Overridable Sub CreatePerson(Optional ByVal numberOfPeople As Integer = 1)
    _population += numberOfPeople
End Sub
End Class

Simple enough so far. But I could go on and on with the many things that object could possibly perform. So, in order to keep things from getting too complex I broke down "activites" that would happen during the day and during the night by creating two other Objects: Day and Night (these two are not shown). So now I have an updated Planet class.

Public Class Planet

Private _population As UInteger = 0

Private _day As New Day
Private _night As New Night

Public ReadOnly Property Day() As Day
    Get
        Return _day
    End Get
End Property

Public ReadOnly Property Night() As Night
    Get
        Return _night
    End Get
End Property

Public ReadOnly Property Population() As UInteger
    Get
        Return _population
    End Get
End Property

Public Overridable Sub CreatePerson(Optional ByVal numberOfPeople As Integer = 1)
    _population += numberOfPeople
End Sub

End Class

Now, these two classes - Day and Night - will never be used outside of the Planet class. Is this a good way to organize my methods and attributes for this "parent" class Planet? How else would I neatly organize similar?

I've read about refactoring but I don't think this helps my case. I like the idea that I can call on an Planet object like this: Earth.Night.BlowUpMoon.

James A Mohler
  • 11,060
  • 15
  • 46
  • 72
Adam Beck
  • 1,271
  • 2
  • 14
  • 25

3 Answers3

2

Think in terms of discoverability. If someone else were to use your object would they know that they have to go to a specific time of day to blow up the moon, which is the same as BirthdayCard.September25th.Send()? Any by "someone else" I also include you in 6 months. Are you organizing for the sake of organizing or are you putting similar methods and properties together in a way that makes sense?

Chris Haas
  • 53,986
  • 12
  • 141
  • 274
  • I am definitely adding methods and properties in a way that makes sense but I wanted to make sure this is a good design. I feel like I'm missing something because I was once told don't create an object if its only going to be used in one place. I'm starting to think that doesn't make sense but I also see that using an object to organize might be bad design technique. – Adam Beck Jul 13 '11 at 18:24
  • In .Net everything is an object so you create one-time objects all the time. But I think you mean a class, right? Download Reflector and examine the .Net framework itself and you'll see plenty of private classes within a parent class that are used to just store related properties. `System.Uri` has 2 classes, 1 structure and 6 enums that are private to the class. Using your sample above, I personally would not think that a `Night` object would be able to `BlowUpMoon()`, I just don't see the relationship. – Chris Haas Jul 13 '11 at 18:54
2

Although your example is contrived, this situation is common practive in Domain Driven Design. Your Planet class would be an aggregate - a root object that manages its own internal entities. Outside the aggregate boundary all interaction is via the root aggregate object.

Martin
  • 39,569
  • 20
  • 99
  • 130
1

Refactor your class and split it to several smaller classes, each with a single responsibility. It doesn't matter that each of them will only be used once - the code will still be better, easier to understand, and far more testable.

ripper234
  • 222,824
  • 274
  • 634
  • 905