-1

I have a class with multiple methods that have the same signature:

string MethodA(int id);
string MethodB(int id);
string MethodC(int id);

The implementation of these methods differs obviously, but I'm trying to make this more SOLID. I got a long way with Composite pattern, where a Composite class would implement the IDoSomething interface below:

public Interface IDoSomething
{
   string DoSomething(int id);
}

public class CompositeClass : IDoSomething
{
    private readonly IEnumerable<IDoSomething> somethings;
    public CompositeClass(IEnumerable<IDoSomething> somethings)
    {
        this.somethings = somethings;
    }

    public string DoSomething(int id)
    {
        foreach (var s in somethings)
        {
            return s.DoSomething(id);
        }
    }
}

Problem is the result to return. This is different for each call. I could change the signature to string[] but that seems like a hack. Any ideas?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
stefjnl
  • 732
  • 3
  • 14
  • 31
  • 1
    Perhaps a more concrete example would help. It's difficult to know what you're trying to do if you use names like `MethodABC` and `DoSomething`. – Isaac Hildebrandt May 02 '18 at 11:23

2 Answers2

3

I don't see what you are trying to achive, the class and method looks good. You can use a Decorator pattern to chain methods, but it seems you need several results as well?

If you want the same method name and signature, you can use explicit interface implementation, which is not really a good practice. You can even go the really dirty way and use an interface with your Methodname and signature. Derive markup interfaces (which is an ANTI pattern!). Implement the derived interfaces explicitly. Implement the base interface by using reflection on yourself and invoking all the "other" interface methods... but don't do that for sake of... well everything!

Jaster
  • 8,255
  • 3
  • 34
  • 60
  • thanks for your answer. Having a class with three methods that all have the same signature, it seemed like the class was eligible for some refactoring. And by refactoring to a Composite I got a long way, until the return value. Ill leave the class as it is then :) – stefjnl May 02 '18 at 11:39
1

Problem is the result to return. This is different for each call.

This seems to be an improper use of the Composite pattern. The general idea behind the Composite is that you don't care whether you work with a Composite or any of its constituents, because they are logically interchangeable.


To illustrate, say you have an abstraction

interface IPainter
{
    double PaintedArea(double hours);
}

You have a bunch of implementations --

class DiligentPainter : IPainter
{
    double PaintedArea(double hours) => hours * 100;
}

class LazyPainter : IPainter
{
    double PaintedArea(double hours) => hours * 20;
}

And here is a key part -- come to think of it, your clients may not care whether they hire a single painter or a crew. They only care that all their walls are painted.

So your can make a composite PainterCrew and make it work as a single painter --

class PainterCrew : IPainter
{
    readonly IEnumerable<IPainter> painters;

    PainterCrew(IEnumerable<IPainter> painters)
    {
        this.painters = painters;
    }

    double PaintedArea(double hours)
    {
        return this.painters.Sum(p => p.PaintedArea(hours));
    }
}

See, you are not just returning a collection of individual results -- you are aggregating it in a meaningful way, so that it doesn't matter from the caller's side whether they are working with a Composite or a single entity.