Hairy object tree problem

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

    #1

    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<Productchi ldren;

    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(Produc t product)
    {
    product.parent = this;
    this.children.A dd(product);
    }

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

    public List<ProductChi ldren
    {
    get { return this.children; }
    }

    public void Traverse()
    {
    Console.WriteLi ne(this.name);
    foreach (Product product in this.children)
    {
    product.Travers e();
    }
    }
    }

    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:



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

    public abstract class ComponentProduc t
    public class Product : ComponentProduc t
    public class CompositeProduc t : ComponentProduc t

    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.Child ren.Add(new Product(...));

    How do I prevent that?

    Many thanks,

    Gustaf



  • Pavel Minaev

    #2
    Re: Hairy object tree problem

    On Jul 10, 5:36 pm, Gustaf <gust...@algone t.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<Productchi ldren;
    >
        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(Produc t product)
        {
            product.parent = this;
            this.children.A dd(product);
        }
    >
        public Product Parent
        {
            get { return this.parent; }
            set { this.parent = value; }
        }
    >
        public List<ProductChi ldren
        {
            get { return this.children; }
        }
    >
        public void Traverse()
        {
            Console.WriteLi ne(this.name);
            foreach (Product product in this.children)
            {
                product.Travers e();
            }
        }
    >
    }
    >
    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.Child ren.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.Componen tModel.Collecti on<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 ...).

    Comment

    • Gustaf

      #3
      Re: Hairy object tree problem

      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

      Comment

      • Pavel Minaev

        #4
        Re: Hairy object tree problem

        On Jul 10, 6:50 pm, Gustaf <gust...@algone t.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 ProductComponen t { }

        class Product : ProductComponen t {
        List<ProductCom ponentcomponent s;
        }

        class ProductComponen tChoice : ProductComponen t {
        List<Productalt ernatives;
        }

        Comment

        Working...