HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Use of the composite pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
usethepatterncomposite

Problem

Assume the following requirements:

Is it a good idea to use the Composite design-pattern for this, taking into account that there will be:

  • Only 1 TestPlan



  • a TestPlan can only have TestSequences



  • a TestSequence can only have Tests



  • a Test can only have Asserts



I've started coding using the Composite pattern but I got the feeling that this pattern cannot enforce the above rules.
Is my feeling correct and should I use another design (pattern) here?
Or is using the composite pattern here correct but is my implementation of it just wrong?

```
public abstract class TestElement
{
public TestElement(int id)
{
this.Id = id;
}

public virtual void Add(TestElement element)
{
throw new NotImplementedException();
}

public virtual void Remove(TestElement element)
{
throw new NotImplementedException();
}

public virtual IEnumerable GetElements()
{
throw new NotImplementedException();
}

public virtual TestElement GetElement(int index)
{
throw new NotImplementedException();
}

public string Id { get; private set; }

public abstract void Setup();

public abstract void Teardown();

}

public class TestPlan : TestElement
{
// Here TestElement should only be of type TestSequence
private IList Children = new List();

public TestPlan(int id)
: base(id)
{
}

public override void Add(TestElement element)
{
this.Children.Add(element);
}

public override void Remove(TestElement element)
{
this.Children.Remove(element);
}

public override TestElement GetElement(int index)
{
return this.Children.ElementAt(index);
}

public override IEnumerable GetElements()
{
return this.Children;
}

public override void Setup()
{
Console.WriteLine("Setup executed for TestPlan " + Id);
}

public override void Teardown()
{
Cons

Solution

I don't think this is an example of composite pattern. Composite is defined as


The Composite Pattern allows you to compose objects into tree
structures to represent part-whole hierarchies. Composite lets clients
treat individual objects and compositions of objects uniformly.

Main idea of Composite is to allow treating whole (several parts) as a individual part. I.e. when client asks Composite to do something, then it means that Composite will ask all it's Components to do same thing. But neither Setup nor Teardown methods of your Composite do not touch collection of TestElements. So, you simply have set of classes with some base class, but that is not Composite.

If you would like to treat TestSequence or TestPlan as a single Test then it would be a Composite. I.e. if you would add Run functionality to your base class (or interface)

public interface ITest
{
    void Run();
}


and TestSequence would run all it's tests:

public class TestSequence : ITest
{
    private IList tests = new List();

    public void Run()
    {
        Setup();
        foreach(var test in tests)
           test.Run();
        Teardown();
    }

    public void Setup()
    {
        Console.WriteLine("Setup executed for Test " + Id);
    }

    public void Teardown()
    {
        Console.WriteLine("Teardown executed for Test " + Id);
    }
}


Then TestSequence would be a Composite, because it's completely transparent for client whether it works with single part (Test) or with a whole (TestSequence, collection of Tests). Same with TestPlan - you can treat it as a single TestSequence. Thus you can treat TestSequence as single Test, then for client TestPlan can also be treated as single Test. Client can run TestPlan, and it will run all it's test sequences, which in their turn will run all tests.

Code Snippets

public interface ITest
{
    void Run();
}
public class TestSequence : ITest
{
    private IList<ITest> tests = new List<ITest>();

    public void Run()
    {
        Setup();
        foreach(var test in tests)
           test.Run();
        Teardown();
    }

    public void Setup()
    {
        Console.WriteLine("Setup executed for Test " + Id);
    }

    public void Teardown()
    {
        Console.WriteLine("Teardown executed for Test " + Id);
    }
}

Context

StackExchange Code Review Q#38981, answer score: 4

Revisions (0)

No revisions yet.