Self referencing object

M

Macka

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.Parent.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.
 
N

Nicholas Paldino [.NET/C# MVP]

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.
 
I

iceman

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

Fred
 
J

james

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
 
J

jay mcguinness

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.
 
N

Nicholas Paldino [.NET/C# MVP]

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.
 
J

Jay B. Harlow [MVP - Outlook]

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.

http://www.martinfowler.com/books.html#eaa

Hope this helps
Jay
 
J

jay mcguinness

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(iParent);
break;

//return a new instance of the user folder
case 'U' :
newfolder = new UserFolder(iParent);
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.
 
J

Jay B. Harlow [MVP - Outlook]

Macka,
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.
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.Parent will always return ImageFolders while UserFolder.Parent
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(iParent);
}

class ImageFolder
virtual Folder Create(int iParent)
{
return New ImageFolder (iParent);
}
Rather than have to modify the switch statement in the abstract class
(which would seem to go against OO principles)
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).

http://www.refactoring.com/catalog/replaceConstructorWithFactoryMethod.html

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

Hope this helps
Jay
 
J

jay mcguinness

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.Create(int)' marked as override cannot be marked
as new or virtual"


Cheers,

Macka.
 
J

Jay B. Harlow [MVP - Outlook]

Macka,
One thing though, in the derived classes, the 'Create' methods needed to
be marked as override rather than virtual.
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top