473,427 Members | 1,785 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,427 software developers and data experts.

Hairy object tree problem

I'm working on an object model that will represent trees of products, where one product may contain others (components of a product). Each product needs to keep track of its parent and child products. That far it seems I'll only need one class:

public class Product
{
private string name;
private Product parent;
private List<Productchildren;

public Product(string name)
{
this.name = name;
this.parent = null;
this.children = new List<Product>();
}

public string Name
{
get { return this.name; }
}

public void AddChild(Product product)
{
product.parent = this;
this.children.Add(product);
}

public Product Parent
{
get { return this.parent; }
set { this.parent = value; }
}

public List<ProductChildren
{
get { return this.children; }
}

public void Traverse()
{
Console.WriteLine(this.name);
foreach (Product product in this.children)
{
product.Traverse();
}
}
}

But there's another requirement: there may be several variants of each product. So in addition to having children, any product in the tree is potentially a collection of alternative products! This requirement seem to complicate the model a great deal. When looking for a solution, I found the Composite design pattern:

http://en.wikipedia.org/wiki/Composite_pattern

If I understand it right, I'd need three classes:

public abstract class ComponentProduct
public class Product : ComponentProduct
public class CompositeProduct : ComponentProduct

I'd appreciate comments on whether this is a good solution in my case, or whether there's an obvious and simple solution that eludes me.

Also, the way I implement Children above has a serious flaw. The calling method gets access to all the members of the List<class, which makes it possible to side-track the AddChild() method, by adding children like this:

myProduct.Children.Add(new Product(...));

How do I prevent that?

Many thanks,

Gustaf

Jul 10 '08 #1
3 1270
On Jul 10, 5:36*pm, Gustaf <gust...@algonet.sewrote:
I'm working on an object model that will represent trees of products, where one product may contain others (components of a product). Each product needs to keep track of its parent and child products. That far it seems I'llonly need one class:

public class Product
{
* * private string name;
* * private Product parent;
* * private List<Productchildren;

* * public Product(string name)
* * {
* * * * this.name = name;
* * * * this.parent = null;
* * * * this.children = new List<Product>();
* * }

* * public string Name
* * {
* * * * get { return this.name; }
* * }

* * public void AddChild(Product product)
* * {
* * * * product.parent = this;
* * * * this.children.Add(product);
* * }

* * public Product Parent
* * {
* * * * get { return this.parent; }
* * * * set { this.parent = value; }
* * }

* * public List<ProductChildren
* * {
* * * * get { return this.children; }
* * }

* * public void Traverse()
* * {
* * * * Console.WriteLine(this.name);
* * * * foreach (Product product in this.children)
* * * * {
* * * * * * product.Traverse();
* * * * }
* * }

}

But there's another requirement: there may be several variants of each product. So in addition to having children, any product in the tree is potentially a collection of alternative products! This requirement seem to complicate the model a great deal. When looking for a solution, I found the Composite design pattern:
I'm not sure I follow you. How does the fact that "there may be
several variants of each product" leads to "any product in the tree is
potentially a collection of alternative products"? From your original
class definition, this is not the case - each product is a product in
itself (in any case), and then it also contains a collection of other
products. I don't see what composite pattern would buy you here, since
you don't have to differentiate leaf and non-leaf nodes.

Can you elaborate on what exactly you mean by "several variants of
each product"?

Also, the way I implement Children above has a serious flaw. The calling method gets access to all the members of the List<class, which makes it possible to side-track the AddChild() method, by adding children like this:

myProduct.Children.Add(new Product(...));

How do I prevent that?
You expose your own collection rather than List<T>. The simplest way
is to create an inner class inside Product that extends
System.ComponentModel.Collection<T>, and override InsertItem/
RemoveItem/SetItem/ClearItems to set/reset Parent as objects are added/
removed to the tree. Once you do that, you should also make Parent.set
private so that the client cannot add a product to a collection, and
then change its Parent to something else entirely (or, alternatively,
you will need to write similar logic for Parent.set - it would have to
remove the product from its parent, and then add it to the new parent
- but that's trickier, because you'll need to guard against recursion
when Parent.set calls Add which calls Parent.set ...).
Jul 10 '08 #2
Pavel Minaev wrote:
Can you elaborate on what exactly you mean by "several variants of
each product"?
Okay, variant wasn't the best word, because it implies the variant is subordinate to some default product. Let's say alternative instead.

Imagine a car product, with child products for chassis, wheels and so on. One day, the researchers come up with a whole new gear stick knob. The new knob is compatible with the old one, so now there are two alternative knobs as children to the gear stick product. They are mutually exclusive. If the whole gear stick is product A, and the stick is product B, the knob would be product C *or* D. Both B and the collection (C|D) are children of A.

Gustaf
Jul 10 '08 #3
On Jul 10, 6:50*pm, Gustaf <gust...@algonet.sewrote:
Imagine a car product, with child products for chassis, wheels and so on.One day, the researchers come up with a whole new gear stick knob. The newknob is compatible with the old one, so now there are two alternative knobs as children to the gear stick product. They are mutually exclusive. If the whole gear stick is product A, and the stick is product B, the knob wouldbe product C *or* D. Both B and the collection (C|D) are children of A.
It seems that your original class models this just fine - you'd have
one instance for A, containing a reference to an instane of B, and
another reference to instance of either C or D. On the other hand, if
you want to encode information about alternatives, then you can
introduce a class hierarchy for that (similar to, but not quite as,
Composite):

abstract class ProductComponent { }

class Product : ProductComponent {
List<ProductComponentcomponents;
}

class ProductComponentChoice : ProductComponent {
List<Productalternatives;
}
Jul 10 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Thomas Baier | last post by:
Hi there, I've written a simple tree class and want to make a function that shows a full tree with all its nodes. My problem is that I do not know how to get the name of an object. I'd like to...
0
by: Olivier Jullian | last post by:
Hi, I'm new to .NET and am trying to take advantage of the object structure while accessing relational databases. I started a small project for managing "projects". Here is a description of...
6
by: Gernot Frisch | last post by:
I want to have a class that provides 2 methods with the same name (do1, do2) that cann be called from a function (Fkt) but Fkt does not know/care about it's type. class base { public:...
6
by: Luke | last post by:
Here is my emails to Danny Goodman (but probably he is very busy so he didn't answered it). First email(simple): Subject: JavaScript Arrays " We all know the array can act like HashMap, but is...
0
by: muralidharan | last post by:
WebForm1.aspx Code: <%@ Register TagPrefix="ComponentArt" Namespace="ComponentArt.Web.UI" Assembly="ComponentArt.Web.UI" %> <ComponentArt:TreeView id="TreeView1" Height="520"...
1
by: RickDee | last post by:
Let me explain what I would like to do. I have created my own object which is able to execute or do something. Now I created a few instances of that object and put them in the tree view. There...
5
by: wbekker | last post by:
Hi, I'm searching for a good pattern for the following problem: In a large object tree, all object implement a property called IsDirty. That flag is set when a property is modified. If a child...
5
by: devendraC | last post by:
I have a Composite object (written in C++) which represents a XML tree. I need to design for adding/merging two composite objects. To make it more clear, I have following two XML tree which...
2
by: cpup22 | last post by:
I'm new to visual basic but have been playing around with extending the treenode functionalities. I found out how to make it so that after a user clicks on a node in a tree a windows object such as...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.