Link to home
Create AccountLog in
Avatar of p_love
p_love

asked on

Can a class maintain a shared collection of its own instances

Hi,

Can a class (say Person) maintain a shared collection of instances of all Person objects created (maybe an array called Persons).

i.e. Whenever a Person instance is created, it adds itself to the Persons collection which is a shared member and accessible to all of the created person instances?

I wonder if you could do it as part of the constructor, but the instance doesnt exist at that point....

Hope this makes sense.

p_love
Avatar of p_love
p_love

ASKER

What I mean is is this feasible, or how can it be created:

Class Person
    Shared Persons as New Collection

    Sub New()
        ....initialise here
        Persons.Add Me
    End Sub

End Class

or there abouts
There are a couple of ways to do it for you.

Create a person factory e.g. and let that class create the person for you (and copy an instance to the persons class while doing it, with the new person added to it already)

or make the persons class a singleton.
and just add an instance to it while creating your person (actually i like the first solution better)

Avatar of Mike Tomlinson
You've answered your own question p_love!...that's exactly how to do it.

Try this out to prove to yourself that each instance is beind added to the ArrayList

Public Class Form1
    Inherits System.Windows.Forms.Form

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim p As New Person("Person" & Person.Persons.Count + 1)
        Dim i As Integer
        Debug.WriteLine("Person Instances: " & Person.Persons.Count)
        For i = 0 To Person.Persons.Count - 1
            Debug.WriteLine(i & ": " & Person.Persons(i).Name)
        Next
    End Sub


    Public Class Person
        Public Shared Persons As New ArrayList

        Public Name As String

        Public Sub New(ByVal Name As String)
            Me.Name = Name
            Person.Persons.Add(Me)
        End Sub

    End Class

End Class
Although it may be feasible, I certainly wouldn't do it that way--it's so self referential.

Bob
ASKER CERTIFIED SOLUTION
Avatar of PockyMaster
PockyMaster
Flag of Netherlands image

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Bob and PockyMaster...

Can you two give a technical reason why the approach I posted is bad?  I have used that same construction in a flocking AI application where each instance of a class basically represents a "sheep" that moves based upon the collective "center of mass" of all the sheep in the flock.  Each sheep must have knowledge of the all the other sheep (instances of the same class) so that it can make a decision as to how it should move.  The app literally ran for hours on end without any of the sheep being garbaged collected and when the app was shut down it properly released its resources.
You might try an observer pattern to that one.

http://www.dofactory.com/Patterns/PatternObserver.aspx

The pattern will take care of updating a lot of observers (all of your sheep ) in case one of your sheep changes

And about your question....
First of all.. there are many ways to solve a problem, but there are ways that a lot of people use, and therefor a lot of times considered the way to go.

But you might consider the following:
At the moment you're exposing a Persons collection in your Person class.
Since .NET decides the type of your collection based on the first element in your collection, it could contain whatever.
So to be a little more on the safe side, you might implement a AddPerson method.
You might see the confusion arising here... A AddPerson method on a Person class? Adding a person to a person?
Apart from pregnancy that's a weird way to go.
So from OO point of view, the implementation could be a little confusing in some cases, doesn't mean that it will not compile or run.

When I want to find a list of persons, I will not look for the object in a person, but will look at a higher level.
Ok, a person might hold a reference to it, but I think the list should be kept outside.
Actually, the shared mechanism keeps it seperated, but under the same classifier.
Which in my humble opinion is not a lucky choice.
Fair enough.  Thanx for the discussion...  =)
P love, was this any good for you?
Avatar of p_love

ASKER

Hi PockyMaster,

I like the Factory implementation.  I guess you are creating a Factory singleton, but isnt this introducing a lot of coupling.  Also, there is nothing stopping a person creating a Person instance and passing in any old CPersonList instance.  By having the collection associated with the Person class itself, and the constructor of the Person class explicitly being responsible for adding each created instance to its own collection, arent you simplifying the design, reducing coupling, and leaving the Person class responsible for itself?

Also could you explain:

  Return DirectCast(_arPersons.ToArray(GetType(CPerson)), CPerson())

Thanks everybody
Well, it all comes down to taste and good/bad practises. I like the design patterns way to do it (which actually just is a collection of best practises).

Your version is simpler, but again my previous arguments will apply to that, think it's a matter of pro/cons.

The directCast I use to convert the internal arraylist to an Array of CPerson,
so I will introduce a little more type-safety here.