Self referencing object

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Macka

    Self referencing object

    A few pieces of information first:

    * I have a class called Folder which represents a row of data in a
    database table. The data access side of things is not an issue.

    * The table has a parent column which references itself (ie. Adjacency
    or parent/child model)

    * I have a public property called 'Parent' which returns me a new
    reference to a Folder instance containing the data of the parent row.
    eg.

    public Folder Parent {
    get {

    //if the parent is available
    if (_iParent > 0) {

    //create a new instance of the folder object referring to the
    parent
    _parent = new Folder(_iParent );
    }

    return _parent;

    }

    }

    * This means that I am able to access the current folders parent's,
    parent's name like this (folder is an instance of Folder):

    folder.Parent.P arent.Name;


    Firstly, am I on the right track? Is this the recommended way to build
    a self referencing class? Is there a design pattern which covers this
    off ?

    Secondly, Folder is an abstract concept. In practise I will actually
    be dealing with an ImageFolder or a UserFolder. I'd like to make
    Folder an abstract class, then create these other classes which can
    inherit from Folder. The problem is that when I'm referencing the
    Parent property, I need to be returning a new instance of the
    ImageFolder/UserFolder rather than Folder.

    Hope this makes sense!

    Cheers,

    macka.
  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: Self referencing object

    Macka,

    I believe you are on the right track with this. As long as you don't
    continuously return a new folder instance, getting an instance the first
    time you are using (for the limit of your operations, that is), you should
    be fine.

    As for the abstract class, you will just have your Parent property
    return a type of the abstract class. As long as the abstract class has the
    properties that are shared among the derived classes, you will be fine (like
    the name property). Just create the appropriate instance and then return
    it, the derived class will be cast up automatically to the base class.

    Hope this helps.


    --
    - Nicholas Paldino [.NET/C# MVP]
    - nicholas.paldin o@exisconsultin g.com

    "Macka" <jay@mcguinness .co.uk> wrote in message
    news:f179d948.0 309170748.191b9 c9@posting.goog le.com...[color=blue]
    > A few pieces of information first:
    >
    > * I have a class called Folder which represents a row of data in a
    > database table. The data access side of things is not an issue.
    >
    > * The table has a parent column which references itself (ie. Adjacency
    > or parent/child model)
    >
    > * I have a public property called 'Parent' which returns me a new
    > reference to a Folder instance containing the data of the parent row.
    > eg.
    >
    > public Folder Parent {
    > get {
    >
    > //if the parent is available
    > if (_iParent > 0) {
    >
    > //create a new instance of the folder object referring to the
    > parent
    > _parent = new Folder(_iParent );
    > }
    >
    > return _parent;
    >
    > }
    >
    > }
    >
    > * This means that I am able to access the current folders parent's,
    > parent's name like this (folder is an instance of Folder):
    >
    > folder.Parent.P arent.Name;
    >
    >
    > Firstly, am I on the right track? Is this the recommended way to build
    > a self referencing class? Is there a design pattern which covers this
    > off ?
    >
    > Secondly, Folder is an abstract concept. In practise I will actually
    > be dealing with an ImageFolder or a UserFolder. I'd like to make
    > Folder an abstract class, then create these other classes which can
    > inherit from Folder. The problem is that when I'm referencing the
    > Parent property, I need to be returning a new instance of the
    > ImageFolder/UserFolder rather than Folder.
    >
    > Hope this makes sense!
    >
    > Cheers,
    >
    > macka.[/color]


    Comment

    • iceman

      #3
      Re: Self referencing object

      You could look for the Singleton pattern.
      There's a taste of it in your way of coding the Parent property.

      Fred


      Comment

      • james

        #4
        Re: Self referencing object

        Macka,

        FYI, this is called either a 'Reflexive Relationship' or 'Recursive
        Relationship'

        Such a layout provides a tree structure, and if you remember CSCI 201
        yours would be a n-ary tree so you can use recursion for all your
        traversal methods. Bottom most elements are leaf nodes, top most
        elements are root nodes ...

        JIM


        "Macka" <jay@mcguinness .co.uk> wrote in message
        news:f179d948.0 309170748.191b9 c9@posting.goog le.com...[color=blue]
        > A few pieces of information first:
        >
        > * I have a class called Folder which represents a row of data in a
        > database table. The data access side of things is not an issue.
        >
        > * The table has a parent column which references itself (ie. Adjacency
        > or parent/child model)
        >
        > * I have a public property called 'Parent' which returns me a new
        > reference to a Folder instance containing the data of the parent row.
        > eg.
        >
        > public Folder Parent {
        > get {
        >
        > //if the parent is available
        > if (_iParent > 0) {
        >
        > //create a new instance of the folder object referring to the
        > parent
        > _parent = new Folder(_iParent );
        > }
        >
        > return _parent;
        >
        > }
        >
        > }
        >
        > * This means that I am able to access the current folders parent's,
        > parent's name like this (folder is an instance of Folder):
        >
        > folder.Parent.P arent.Name;
        >
        >
        > Firstly, am I on the right track? Is this the recommended way to build
        > a self referencing class? Is there a design pattern which covers this
        > off ?
        >
        > Secondly, Folder is an abstract concept. In practise I will actually
        > be dealing with an ImageFolder or a UserFolder. I'd like to make
        > Folder an abstract class, then create these other classes which can
        > inherit from Folder. The problem is that when I'm referencing the
        > Parent property, I need to be returning a new instance of the
        > ImageFolder/UserFolder rather than Folder.
        >
        > Hope this makes sense!
        >
        > Cheers,
        >
        > macka.[/color]


        Comment

        • jay mcguinness

          #5
          Re: Self referencing object

          Thanks for the prompt reply :)

          If I make the class abstract then I will no longer be able to create a
          new instance of the class when the Parent property is called.

          ie. this line will prevent the class from compiling.

          _parent = new Folder(_iParent );

          Do you think therefore I should implement the Parent property in the
          ImageFolder/UserFolder classes instead? It just seems a shame as the
          code is identical for all Folder Types!



          Cheers,

          macka.

          *** Sent via Developersdex http://www.developersdex.com ***
          Don't just participate in USENET...get rewarded for it!

          Comment

          • Nicholas Paldino [.NET/C# MVP]

            #6
            Re: Self referencing object

            macka,

            This is where a class factory pattern is helpful. Basically, you will
            have a method that will take some sort of parameter which then based on that
            parameter (or parameters) will create the appropriate instance of the type
            and then return a reference to the common base instance that all the derived
            types share.


            --
            - Nicholas Paldino [.NET/C# MVP]
            - nicholas.paldin o@exisconsultin g.com

            "jay mcguinness" <developersdex@ mcguinness.co.u k> wrote in message
            news:Oh5lpgTfDH A.2400@TK2MSFTN GP11.phx.gbl...[color=blue]
            > Thanks for the prompt reply :)
            >
            > If I make the class abstract then I will no longer be able to create a
            > new instance of the class when the Parent property is called.
            >
            > ie. this line will prevent the class from compiling.
            >
            > _parent = new Folder(_iParent );
            >
            > Do you think therefore I should implement the Parent property in the
            > ImageFolder/UserFolder classes instead? It just seems a shame as the
            > code is identical for all Folder Types!
            >
            >
            >
            > Cheers,
            >
            > macka.
            >
            > *** Sent via Developersdex http://www.developersdex.com ***
            > Don't just participate in USENET...get rewarded for it![/color]


            Comment

            • Jay B. Harlow [MVP - Outlook]

              #7
              Re: Self referencing object

              macka,
              I would have a Factory Method in Folder to return the correct folder type.

              _parent = Folder.Create(_ iParent);

              Where Folder.Create is a static function that knows based on _iParent to
              create either a ImageFolder or UserFolder. This of course assumes giving the
              ID you know which type of Folder to create.

              Martin Fowler's book "Patterns of Enterprise Application Architecture" has a
              couple of mapping patterns that may be helpful here.

              Details of books I've written, and those in my signature series


              Hope this helps
              Jay

              "jay mcguinness" <developersdex@ mcguinness.co.u k> wrote in message
              news:Oh5lpgTfDH A.2400@TK2MSFTN GP11.phx.gbl...[color=blue]
              > Thanks for the prompt reply :)
              >
              > If I make the class abstract then I will no longer be able to create a
              > new instance of the class when the Parent property is called.
              >
              > ie. this line will prevent the class from compiling.
              >
              > _parent = new Folder(_iParent );
              >
              > Do you think therefore I should implement the Parent property in the
              > ImageFolder/UserFolder classes instead? It just seems a shame as the
              > code is identical for all Folder Types!
              >
              >
              >
              > Cheers,
              >
              > macka.
              >
              > *** Sent via Developersdex http://www.developersdex.com ***
              > Don't just participate in USENET...get rewarded for it![/color]


              Comment

              • jay mcguinness

                #8
                Re: Self referencing object

                Thanks for all your help guys.

                I've created a static factory method called Create which returns an
                appropriate instance, based on a parameter (sFolderType):

                //Class Factory method returns instance of appropriate class
                private static Folder Create(int iParent, char sFolderType) {

                Folder newfolder = null;

                switch (sFolderType) {

                //return a new instance of the image folder
                case 'I' :
                newfolder = new ImageFolder(iPa rent);
                break;

                //return a new instance of the user folder
                case 'U' :
                newfolder = new UserFolder(iPar ent);
                break;
                }

                return newfolder;

                }

                This works fine, but what if in the future someone adds an additional
                FolderType (say EmailFolder)?

                I am able to guarantee that a single hierarchy will contain only ONE
                folder type. ie. the Parent of an ImageFolder will always be an
                ImageFolder.

                Rather than have to modify the switch statement in the abstract class
                (which would seem to go against OO principles), I would like the Factory
                method to be able to return an instance of the calling class.

                Any ideas ?

                Cheers,

                Macka.




                *** Sent via Developersdex http://www.developersdex.com ***
                Don't just participate in USENET...get rewarded for it!

                Comment

                • Jay B. Harlow [MVP - Outlook]

                  #9
                  Re: Self referencing object

                  Macka,[color=blue]
                  > I am able to guarantee that a single hierarchy will contain only ONE
                  > folder type. ie. the Parent of an ImageFolder will always be an
                  > ImageFolder.[/color]
                  Wait a minute. Hang on. Think about this ;-)

                  You have a base class called Folder, that has a property called Parent. You
                  have derived classes called ImageFolder & UserFolder.

                  ImageFolder.Par ent will always return ImageFolders while UserFolder.Pare nt
                  will always return UserFolders. While the Parent property itself is of type
                  Folder?

                  Correct?

                  I would not a Factory Method Pattern in that case, I would use a Template
                  Method Pattern. (OK the Template Method would be a factory method, however
                  the Template Method Pattern is the dominate pattern).

                  The "Create" method would be a template method that the base class uses to
                  call into the derived classes that returns new objects of the correct type.

                  public Folder Parent {
                  get {
                  if (_iParent > 0) {
                  _parent = Create(_iParent );
                  }
                  return _parent;
                  }
                  }

                  protected abstract Folder Create(int iParent);

                  Then in the derived classes.

                  class UserFolder
                  virtual Folder Create(int iParent)
                  {
                  return New UserFolder(iPar ent);
                  }

                  class ImageFolder
                  virtual Folder Create(int iParent)
                  {
                  return New ImageFolder (iParent);
                  }
                  [color=blue]
                  > Rather than have to modify the switch statement in the abstract class
                  > (which would seem to go against OO principles)[/color]
                  Its how this type of factory methods need to work, for details see the
                  "Replace Constructor with Factory Method" refactoring. (you need the book
                  for the full details).



                  Look at the Image.FromFile and Image.FromStrea m methods. Based on the type
                  of the underlying file/stream they return a different type of concrete Image
                  object.

                  Hope this helps
                  Jay

                  "jay mcguinness" <developersdex@ mcguinness.co.u k> wrote in message
                  news:Od7L7kcfDH A.956@TK2MSFTNG P09.phx.gbl...[color=blue]
                  > Thanks for all your help guys.
                  >
                  > I've created a static factory method called Create which returns an
                  > appropriate instance, based on a parameter (sFolderType):
                  >
                  > //Class Factory method returns instance of appropriate class
                  > private static Folder Create(int iParent, char sFolderType) {
                  >
                  > Folder newfolder = null;
                  >
                  > switch (sFolderType) {
                  >
                  > //return a new instance of the image folder
                  > case 'I' :
                  > newfolder = new ImageFolder(iPa rent);
                  > break;
                  >
                  > //return a new instance of the user folder
                  > case 'U' :
                  > newfolder = new UserFolder(iPar ent);
                  > break;
                  > }
                  >
                  > return newfolder;
                  >
                  > }
                  >
                  > This works fine, but what if in the future someone adds an additional
                  > FolderType (say EmailFolder)?
                  >
                  > I am able to guarantee that a single hierarchy will contain only ONE
                  > folder type. ie. the Parent of an ImageFolder will always be an
                  > ImageFolder.
                  >
                  > Rather than have to modify the switch statement in the abstract class
                  > (which would seem to go against OO principles), I would like the Factory
                  > method to be able to return an instance of the calling class.
                  >
                  > Any ideas ?
                  >
                  > Cheers,
                  >
                  > Macka.
                  >
                  >
                  >
                  >
                  > *** Sent via Developersdex http://www.developersdex.com ***
                  > Don't just participate in USENET...get rewarded for it![/color]


                  Comment

                  • jay mcguinness

                    #10
                    Re: Self referencing object

                    Thanks very much Jay.

                    I've got it all working and it looks lovely :)

                    One thing though, in the derived classes, the 'Create' methods needed to
                    be marked as override rather than virtual.

                    Does that sound right?

                    If I don't do this the compiler complains :

                    "A member 'ImageFolder.Cr eate(int)' marked as override cannot be marked
                    as new or virtual"


                    Cheers,

                    Macka.

                    *** Sent via Developersdex http://www.developersdex.com ***
                    Don't just participate in USENET...get rewarded for it!

                    Comment

                    • Jay B. Harlow [MVP - Outlook]

                      #11
                      Re: Self referencing object

                      Macka,[color=blue]
                      > One thing though, in the derived classes, the 'Create' methods needed to
                      > be marked as override rather than virtual.[/color]
                      Doh!

                      Ya know when you normally do more VB.NET then C# and you type C# off the top
                      of your head without verifying the specific syntax. :-(

                      In truth I was trying to demonstrate the Template Method concept and not the
                      actual syntax. So you are correct I should have used override (I knew that
                      too).

                      Glad it works
                      Jay

                      "jay mcguinness" <developersdex@ mcguinness.co.u k> wrote in message
                      news:%23NNfNuff DHA.3248@tk2msf tngp13.phx.gbl. ..[color=blue]
                      > Thanks very much Jay.
                      >
                      > I've got it all working and it looks lovely :)
                      >
                      > One thing though, in the derived classes, the 'Create' methods needed to
                      > be marked as override rather than virtual.
                      >
                      > Does that sound right?
                      >
                      > If I don't do this the compiler complains :
                      >
                      > "A member 'ImageFolder.Cr eate(int)' marked as override cannot be marked
                      > as new or virtual"
                      >
                      >
                      > Cheers,
                      >
                      > Macka.
                      >
                      > *** Sent via Developersdex http://www.developersdex.com ***
                      > Don't just participate in USENET...get rewarded for it![/color]


                      Comment

                      Working...