[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Can a class maintain a shared collection of its own instances

Posted on 2006-03-24
11
Medium Priority
?
268 Views
Last Modified: 2010-04-23
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
0
Comment
Question by:p_love
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 1

Author Comment

by:p_love
ID: 16281997
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
0
 
LVL 14

Expert Comment

by:PockyMaster
ID: 16283686
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)

0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16284015
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
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 96

Expert Comment

by:Bob Learned
ID: 16286250
Although it may be feasible, I certainly wouldn't do it that way--it's so self referential.

Bob
0
 
LVL 14

Accepted Solution

by:
PockyMaster earned 1000 total points
ID: 16288059

you might think about it like this:


Public Class CPersonFactory

    Private Shared _instance As CPersonFactory
    Private Shared _personList As CPersonList

    Public Function CreatePerson(ByVal sName As String) As CPerson
        Dim newPerson As New CPerson(sName, _personList)
        _personList.addPerson(newPerson)

        Return newPerson
    End Function

    Private Sub New()
        _personList = New CPersonList
    End Sub

    Public Shared Function GetInstance() As CPersonFactory
        If _instance Is Nothing Then
            _instance = New CPersonFactory
        End If

        Return _instance
    End Function
End Class


Public Class CPerson
    Private _sName As String
    Private _PersonList As CPersonList
    Public Sub New(ByVal sName As String, ByVal PersonList As CPersonList)
        _sName = sName
        _PersonList = PersonList
    End Sub

    Public ReadOnly Property Name() As String
        Get
            Return _sName
        End Get
    End Property

    Public ReadOnly Property PersonList() As CPerson()
        Get
            Return _PersonList.Persons
        End Get
    End Property
End Class

Public Class CPersonList
    Private _arPersons As ArrayList

    Public Sub New()
        _arPersons = New ArrayList
    End Sub

    Public Sub addPerson(ByVal person As CPerson)
        _arPersons.Add(person)
    End Sub
    Public ReadOnly Property Persons() As CPerson()
        Get
            If _arPersons.Count = 0 Then
                Return Nothing
            Else
                Return DirectCast(_arPersons.ToArray(GetType(CPerson)), CPerson())
            End If
        End Get
    End Property

End Class

and then call it like :
 Dim pf As CPersonFactory = CPersonFactory.GetInstance()
        Dim pers1 As CPerson = pf.CreatePerson("myPerson")
        Dim pers2 As CPerson = pf.CreatePerson("myOtherPerson")

'just an example to get your persons
        Dim allPersons() As CPerson = pers2.PersonList


Your factory in this case will make sure the personlist will stay alive
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16288346
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.
0
 
LVL 14

Expert Comment

by:PockyMaster
ID: 16290759
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.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 16291093
Fair enough.  Thanx for the discussion...  =)
0
 
LVL 14

Expert Comment

by:PockyMaster
ID: 16355890
P love, was this any good for you?
0
 
LVL 1

Author Comment

by:p_love
ID: 16356284
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
0
 
LVL 14

Expert Comment

by:PockyMaster
ID: 16357640
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.

0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses
Course of the Month20 days, 13 hours left to enroll

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question