First, concerning to the design pattern itself. The composite you have implemented isn't the same as the GOF Composite. You have made some kind a variant form of that. (I think this isn't what you expect.)
Second, the top level type Element
(GOF -> Component) must not be an interface type, but it should be, since the derivations should (normally) come up with their own implementation. At least the top level type should be abstract. By using this approach, the sub classes don't need to maintain a list of references to the top level or ist parent type.
Just a pseudo source example:
abstract class Element
{
protected int basicActivityIdx; //GET - S[101], GS80 [102] etc PUT - AW[201], S[202], PD80[203] etc..
protected string basicActivityName;
protected Element(int idx, string name)
{
this.basicActivityIdx = idx; //GET - S[101], GS80 [102] etc PUT - AW[201], S[202], PD80[203] etc..
this.basicActivityName = name;
}
public abstract void addChild(Element child);
public abstract void doSthOperation();
// TODO -> Define further operations ...
}
// Maybe you won't need this. It just tells you that the current node doesn't have any children
class Leaf : Element{
public void Leaf(int idx, string name) : base(idx, name){}
public void addChild(Element child){
throw new SystemException("A leaf isn't allowed to have children!");
}
public void doSthOperation(){
Console.WriteLine("I am the last node in the hierarchy!");
}
}
class Activity : Element
{
private List<Element> children;
public void Activity(int idx, string name) : base(idx, name)
{
this.children = new List<Element>();
}
public void addChild(Element child){
this.children.add(child);
}
public void doSthOperation(){
Console.WriteLine("I am a concreate instance of Activity!");
}
}
class SubActivity : Activiy{
// This implementation doesn't have to maintain a list of top level elements, since its base class already is doing this!
public void SubActivity(int idx, string name) : base(idx, name) { }
public void addChild(Element child){
base.addChild(child);
// Or implement its own behavior how children are added to the list.
// Maybe you want to add any specific data to the the attached child here.
}
public void doSthOperation(){
Console.WriteLine("I am a concreate instance of SubActivity!");
}
}
A further example which may suite your needs more, since a SubSystem
must not be a Factory
and a Factory
must not be a Facility
:
// With this approach the element can never be a pure abstract class (interface)!
// The benefit of this version, in contrast to the previous one, is that the design
// of the software can be easily adapted to the real worlds structure, since it is defined
// dynamically, instead of staticaly like in the example above.
abstract class Element
{
protected int id; //GET - S[101], GS80 [102] etc PUT - AW[201], S[202], PD80[203] etc..
protected string name;
// This instance itself maintains a list of self references
protected List<Element> children;
protected Element(int id, string name)
{
this.children = new List<Element>();
this.id = idx; //GET - S[101], GS80 [102] etc PUT - AW[201], S[202], PD80[203] etc..
this.name = name;
}
public void addChild(Element child){
this.children.add(child);
}
public virtual void doSthOperation(){
Console.WriteLine("I am the element instance itself!");
}
// TODO -> Define further operations ...
}
// Maybe you won't need this. It just tells you that the current node doesn't have any children
class Leaf : Element{
public void Leaf(int id, string name) : base(id, name){}
public void addChild(Element child){
throw new SystemException("A leaf isn't allowed to have children!");
}
public void doSthOperation(){
Console.WriteLine("I am the last node in the hierarchy!");
}
}
class Facility : Element
{
public void Facility(int id, string name) : base(id, name)
public void doSthOperation(){
Console.WriteLine("I am a concreate instance of Faciltiy!");
}
}
class Factory : Element{
public void Factory(int id, string name) : base(id, name) { }
public void doSthOperation(){
Console.WriteLine("I am a concreate instance of Factory!");
}
}
class SubSystem : Element{
public void SubSystem(int id, string name) : base(id, name) { }
public void doSthOperation(){
Console.WriteLine("I am a concreate instance of SubSystem!");
}
}