Класс Refactor, имеющий несколько методов с одинаковой сигнатурой - PullRequest
0 голосов
/ 02 мая 2018

У меня есть класс с несколькими методами, которые имеют одинаковую подпись:

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

Реализация этих методов отличается, очевидно, но я пытаюсь сделать это более твердым. Я получил долгий путь с шаблоном Composite, где класс Composite реализовал бы интерфейс IDoSomething ниже:

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);
        }
    }
}

Проблема в результате возврата. Это отличается для каждого звонка. Я мог бы изменить подпись на строку [], но это похоже на взлом. Есть идеи?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Проблема - результат возврата. Это отличается для каждого звонка.

Это, кажется, неправильное использование шаблона Composite. Основная идея Composite заключается в том, что вам все равно, работаете ли вы с Composite или с его компонентами, потому что они логически взаимозаменяемы.


Для иллюстрации скажем, у вас есть абстракция

interface IPainter
{
    double PaintedArea(double hours);
}

У вас есть куча реализаций -

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

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

И вот ключевая часть - если подумать, вашим клиентам может быть все равно, будут ли они нанимать одного художника или команду. Их волнует только то, что все их стены покрашены.

Так что вы можете сделать композит PainterCrew и заставить его работать как один художник -

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));
    }
}

Видите, вы не просто возвращаете набор отдельных результатов - вы агрегируете их осмысленным образом, чтобы со стороны вызывающей стороны не имело значения, работают ли они с Composite или с одной сущностью.

0 голосов
/ 02 мая 2018

Я не вижу, чего вы пытаетесь достичь, класс и метод выглядят хорошо. Вы можете использовать шаблон Decorator для цепочки методов, но, похоже, вам также нужно несколько результатов?

Если вам нужны одно и то же имя метода и подпись, вы можете использовать явную реализацию интерфейса, что не очень хорошая практика. Вы даже можете пойти очень грязным путем и использовать интерфейс с вашим именем метода и подписью. Получите интерфейсы разметки (что является шаблоном ANTI!). Реализуйте производные интерфейсы явно. Реализуйте базовый интерфейс, используя рефлексию на себя и вызывая все «другие» методы интерфейса ... но не делайте этого ради ... ну всего!

...