问题
I'm writing an application that has Reactor and Zone objects. Each Reactor has a variable number of zones, and stores them in a private field called _zones.
In turn, each Zone must know to which Reactor does it belong, so it stores a pointer to its reactor in a private field. I assign this field by passing a reactor object into the Zone constructor.
Here is the sample code:
Public Class Reactor
Private _zones As New List(Of Zone)
End Class
Public Class Zone
Private _reactor As Reactor
Public Sub New(ByVal reactor As Reactor)
_reactor = reactor
End Sub
End Class
My question is: since each Zone needs to have a reactor passed to its constructor, which of this two approaches do you consider to be better:
Create Zones only with a method in Reactor.
Public Class Reactor Private _zones As New List(Of Zone) Public Sub CreateZone() _zones.Add(New Zone(Me)) End Sub End Class
Create zones and them add them to the reactor
Public Class Reactor Private _zones As New List(Of Zone) Public Sub AddZone(ByVal z As Zone) _zones.Add(z) End Sub End Class
I suppose that the chosen option depends on the concrete case, but I would like to know if one of these options is considered generally as a best practice. Also, any experience about similar cases would be very useful.
Thanks!
回答1:
I would say that the first option is preferred. The problem with the second approach is that it would be possible to create a Zone
, giving it reactorA
in its constructor, but then add it to reactorB
. Or, you could add the same Zone
to two different Reactor
objects. You could of course add error-checking for that and throw an exception in the case of a mismatch, but as long as the design requires the parent/child relationship, you'll never be likely to be in a position where you need to create a Zone
, but you don't have access to its Reactor
. As long as you're likely to always have access to the Reactor
when you need to create the Zone
, then there's no reason not to encapsulate it all by putting the "create" method in the Reactor
class.
For instance, I have created a grid object, which defines a grid table to be printed to a page or to the screen. It contains a list of rows and the rows each contain a list of cells. The rows need a reference back to their grid and the cells need a reference back to their row. So, I simply implemented it in a way where you tell the grid that you want to add a row and give it the size, like this:
myGrid.Rows.Add(100)
And the Add
method returns the Row object, so you can get it easily like this:
Dim row As GridRow = myGrid.Rows.Add(100)
row.PenWidthTop = 1
This design works very well for that particular situation. Since it's very unlikely that I'll ever need to create a row in a place where I won't already have a reference to the parent grid, it makes it nice and easy to work with.
If you ever do run into a situation where you need to be able to create Zone
objects independently, and then add them to the Reactor
later, you could always add that as a secondary option. There's nothing about the first method which precludes you from adding the second method at a later time. For instance, you could make it so that Zone
objects allow themselves to be creates without a parent Reactor
, and then, when they are added to the Reactor
, the Reactor
can set a property on the Zone
to tell it who it's parent Reactor
is. You could have the ParentReactor
property on the Zone
class throw an exception if you try to change it after it's been already set before, like this:
Public Class Zone
Public Sub New()
End Sub
Public Sub New(parentReactor As Reactor)
_parentReactor = parentReactor
End Sub
Private _parentReactor As Reactor
Public Property ParentReactor As Reactor
Get
Return _parentReactor
End Get
Set(value As Reactor)
If _parentReactor IsNot Nothing Then
Throw New Exception("This zone has already been added to a Reactor")
End If
_parentReactor = value
End Set
End Property
' ...
End Class
来源:https://stackoverflow.com/questions/21308881/parent-creating-child-object