Click here to Skip to main content
15,881,967 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,

I tried to look for a solution on this on Code Project, but found none. So if this question has been asked before, please point me in the right direction.

Ok, so I am trying to implement a Composite Design Pattern structure using C# in VS2010.

Firstly, what I'm using the design pattern for is not important, but what I am curious about is VS2010 an its Class Diagrams that it generate from my structure.

I created an abstract Component Class and have the Composite Class inheriting from that. I also have the Leaf Class inheriting from the abstract Component Class.

For a simple aggregation between Component and Composite, one can use an ArrayList, but I opted for a generic list
C#
List<Component> component
. So now I can use a method
C#
public void addChild(Component childComponent)
to add children to my Composite. This works and is cool. But I noticed (when generating a class diagram in VS2010) that there is no arrow (aggregation) pointing to my Component Class from Composite. An aggregation does exist through the use of my
List<Component> component
.

If I then continue and draw an aggregation from Composite to Component, the following code is generated in my Composite Class:

C#
public Component Component
{
    get
    {
        throw new System.NotImplementedException();
    }
    set
    {
    }
}


So, finally my question: How would you use this generated code with a List<t>. Is it even necessary to worry about this?

Thanks in advance.
Posted
Updated 12-Jul-11 2:46am
v2
Comments
PJ du Preez 12-Jul-11 8:50am    
Thanks Tarun... couldn't get why it didnt do this for me...
PJ du Preez 12-Jul-11 9:30am    
So ACTUALLY what I'm asking is, can you use a generic list as a property and how?
#realJSOP 12-Jul-11 11:02am    
Yes - a property can represent ANY object that can be instantiated, including a generic List. Why would you think otherwise?

Your design seems fine for a simple composite pattern, and using a generic List<basetype> for the composite node is the right way to go. If the diagram tool doesn't understand it, use a better one (like a pen and piece of paper? ;)).
 
Share this answer
 
Comments
PJ du Preez 12-Jul-11 10:08am    
hehehe, i like your answer. I also think that is what's happening here. The code generated from ArgoUML's diagram is spot on, except for the ArrayList (replaced with List<Component> in my final design) being generated by the aggregation, but the same design in VS2010 gives me different code.

thanks.
If it's abstract, you can't use it the way you're doiing it. You MUST derive a new class from it, like so:

C#
public class MyComponent : Component
{
  // You MUST override all pure virtual (abstract) methods in this class
}

Then you can do this :

C#
public class MyComponentCollection : List<MyComponent>
{
}
MyComponentCollection myComponents = new MyComponentCollection();
myComponents.Add(...);


or this:

C#
List<MyComponent> myComponents = new List<MyComponent>;
myComponents.Add(...);


I prefer the first usage example because it's cleaner on the codemonkey side.

EDIT (after comment) =======================

In order to create a collection of Component-based objects, the collection must contain objects that are derived from an object derived from component (because it's abstract). My suggestion is to either create an interface, or change Component to not be abstract. You could also consider changing the addChild method to accept an Object instead of a Component. Then, you wouldn't need to make Component abstract.
 
Share this answer
 
v3
Comments
PJ du Preez 12-Jul-11 9:05am    
Thanks,

I see what you mean but I never meant for Component to be instantiated. I derive Composite from Component so that I can use public void addChild(Component childComponent) to add a Composite as a child (and eventually a Leaf).

I was curios about why the Class Diagram generates code that is not a collection (because a Composite can have many children of type Component ie Component composite = new Composite())

I ArgoUML for example, the generated code will give you an ArrayList. Is the code generated by VS2010 a better way to aggregate the two classes?

EDIT (after comment) =======================

Composite IS derived from Component... it is the Composite Design Pattern. using Component as the type that is passed to addChild allows for a recursive structure so that you can add more Component children to your Composite, which could be Leaf\Composite objects.

http://en.wikipedia.org/wiki/Composite_pattern so that we are on the same page.

what happens in VS2010 is that the aggregation between Component and Composite is removed when using anything other than the generated property (which can only hold 1 (one) object instead of a collection of objects). But when you draw an aggregation from the Composite to Component, the above mentioned code is generated. Is there a way of using a List<t> together with a properties getters\setters to add a value to the List<t> and retrieve a specific value from the List<t>?
#realJSOP 12-Jul-11 11:01am    
Technically, Composite can't have a collection of Component types (because Component is abstract). It can only have a collection of derived types. I don't think you can get there from here without doing what I recommended above, which is to put your required methods into an interface, and NOT make Component abstract.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900