Singleton/Abstract Factor issue

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pete the Perplexed Programmer

    #1

    Singleton/Abstract Factor issue

    Consider the following problem (which I state with a simple example,
    but it corresponds to a real problem that I'm facing): Junior loves
    pets, and that's fine with Mom and Dad, as long as he only has no more
    than one of any given species.

    Now, how can I use a Singleton to restrict Junior from having too many
    pets?

    +----------------+
    + ----->| << abstract >> |<-----+
    | | Animal | |
    | +----------------+ |
    | | | |
    | +----------------+ |
    | | | |
    | | Speak() | |
    | | \ | |
    | +-----\----------+ |
    | \ |
    | <<abstract>> |
    +-----+ +-----+
    | Dog | | Cat |
    +-----+ +-----+

    So, we could implement our Speak() methods like this:

    For Dog:

    Overrides Sub Speak()
    Console.WriteLi ne("Arf!")
    End Sub

    For Cat:

    Overrides Sub Speak()
    Console.WriteLi ne("Meow!")
    End Sub

    The problem I'm facing is this: how do I restrict the creation of Dog and Cat
    classes while avoiding redundant code. I mean, it's easy simple to implement
    each class as separate singletons, but that's going to get old after a while
    if I also have to create a Hampster, a Parrot, a Mouse, a Rat, a Guinea Pig, etc.

    I started working with an Abstract Factory--or something like it:

    +----------------------+
    | << abstract >> |
    | AnimalCreator |
    +----------------------+
    | m_objAnimal: Animal |
    +--->+----------------------+
    | | Create(): Animal |
    | +----------------------+
    | /|\
    | |
    +------------------+ |
    | DogCreator | |
    +------------------+ |
    | Create(): Animal | |
    +------------------+ |
    |
    +------------------+ |
    | CatCreator | |
    +------------------+------+
    | Create(): Animal |
    +------------------+

    (Animal, Dog, and Cat as above)

    Problem is: I wanted to use a static variable (AnimalCreator. m_objAnimal) to store a reference
    to a single instance of each animal. Little did I know (until the code behaved incorrectly)
    that a single instance of m_objAnimal is shared by all classes derived from AnimalCreator.

    So, what's a good way around this problem?

    The code follows at the end of this message.

    Pierre the Perplexed Programmer


    Imports Microsoft.Visua lBasic
    Imports System
    Imports System.Collecti ons

    Public MustInherit Class Animal

    Public MustOverride Sub Speak()

    End Class

    Public Class Dog
    Inherits Animal

    Public Overrides Sub Speak()
    Console.WriteLi ne("Arf!")
    End Sub
    End Class

    Public Class Cat
    Inherits Animal

    Public Overrides Sub Speak()
    Console.WriteLi ne("Meow")
    End Sub
    End Class

    Public MustInherit Class AnimalCreator

    Protected Shared m_objAnimal As Animal

    Public MustOverride Function Create() As Animal

    End Class

    Public Class DogCreator
    Inherits AnimalCreator

    Public Overrides Function Create() As Animal
    If m_objAnimal Is Nothing Then
    m_objAnimal = New Dog
    End If
    Return m_objAnimal
    End Function
    End Class

    Public Class CatCreator
    Inherits AnimalCreator

    Public Overrides Function Create() As Animal
    If m_objAnimal Is Nothing Then
    m_objAnimal = New Cat
    End If
    Return m_objAnimal
    End Function
    End Class

    Public Class Test
    Public Shared Sub Main()
    Dim objDogCreator As AnimalCreator = New DogCreator()
    Dim objCatCreator As AnimalCreator = New CatCreator()

    Dim objDog As Animal = objDogCreator.C reate()
    Dim objCat As Animal = objCatCreator.C reate()

    objDog.Speak()
    objCat.Speak()

    Console.ReadLin e()
    End Sub

  • Jon Shemitz

    #2
    Re: Singleton/Abstract Factor issue

    Pete the Perplexed Programmer wrote:[color=blue]
    >
    > Consider the following problem (which I state with a simple example,
    > but it corresponds to a real problem that I'm facing): Junior loves
    > pets, and that's fine with Mom and Dad, as long as he only has no more
    > than one of any given species.
    >
    > Now, how can I use a Singleton to restrict Junior from having too many
    > pets?[/color]

    This strikes me as overkill. Why not just maintain a list of the Type
    of each pet? Then, whenever Jr is thinking of adding a new pet, you
    can just see if the PetTypeList.Con tains( PossibleNewPet. GetType() ).

    --

    Midnight Beach is Jon Shemitz, a freelance programmer and author. Jon offers software consulting and contract services, and recently finished his 2nd book - .NET 2.0 for Delphi Programmers.

    Comment

    • Alon Fliess

      #3
      Re: Singleton/Abstract Factor issue

      Jon Shemitz <jon@midnightbe ach.com> wrote in message news:<4268200D. 7BECF72B@midnig htbeach.com>...[color=blue]
      > Pete the Perplexed Programmer wrote:[color=green]
      > >
      > > Consider the following problem (which I state with a simple example,
      > > but it corresponds to a real problem that I'm facing): Junior loves
      > > pets, and that's fine with Mom and Dad, as long as he only has no more
      > > than one of any given species.
      > >
      > > Now, how can I use a Singleton to restrict Junior from having too many
      > > pets?[/color]
      >
      > This strikes me as overkill. Why not just maintain a list of the Type
      > of each pet? Then, whenever Jr is thinking of adding a new pet, you
      > can just see if the PetTypeList.Con tains( PossibleNewPet. GetType() ).[/color]

      O.K, you want to have a singleton behavior for many classes with no
      redundant code. To do that let's first define Singleton: A single
      object instance class that has a global access and it is known to all.
      There are two classic singleton implementations : 1) declare all the
      methods as "static" (shared) and put the class constructor as private.
      2) Control the object creation, and let only one instance to be
      creating (private constructor, static member to hold the instance, and
      static access method to that specific instance).
      To make many objects singleton you need to control their creation and
      you need to give them a well known access. You may use a repository (a
      collection) that will hold your singleton instance. The repository
      will be implemented as a classic singleton. Each of your singleton
      class should have a private constructor (control creation). In each of
      the singleton class static constructor, register the unique instance
      in the repository (give it a name, so client will be able to query
      your object by name). When ever a client needs the instance, he will
      go to the repository and ask for that instance using the name you gave
      for your instance. The CLR class loader will load your class as soon
      as the client asks for it, then the static constructor will do its
      magic and the client will get that instance.

      Alon Fliess

      Comment

      Working...