/ / Jaki wzorzec projektowy dla funkcji, które dają ten sam wynik, ale przyjmują inne parametry? - c #, oop, wzorce projektowe

Jaki wzorzec projektowania dla funkcji, które dają ten sam wynik, ale przyjmują różne parametry? - c #, oop, wzorce projektowe

Odziedziczyłem nieco ponad 1000 linii spaghettikod. Mogę rozłożyć to na kilkanaście metod, z których każda tworzy obiekt FinancialTransactionObject, ale przyjmuje różne daty, kwoty i inne parametry, aby utworzyć transakcję.

Moje przeczucie podpowiada mi, żebym uczynił każdą metodę własną klasą. Mogę więc mieć kilkanaście klas dziedziczących z klasy bazowej lub interfejsu z 1 metodą:

abstract FinancialTransactionObject Calculate();

i przenieś parametry do konstruktorów lubuczynić je własnością publiczną. Konstruktorzy oznaczają, że nie mogę ponownie użyć mojej instancji i za każdym razem muszę tworzyć nowy obiekt. Właściwości oznaczają, że konsumujący kod może zapomnieć o ich ustawieniu. Pozostawienie parametrów w każdej metodzie daje mi po prostu kilkanaście metod w oddzielnych plikach i nie jest zorientowane obiektowo.

Wydaje się, że często pojawia się odmiana tego problemu. Czy istnieje dobry, spójny, ogólnobranżowy wzorzec projektowy, aby sobie z tym poradzić?

Odpowiedzi:

0 dla odpowiedzi № 1

To naprawdę brzmi dla mnie jak Wzór gościa.

Tak więc podstawową ideą wzorca odwiedzających jest dynamiczna zmiana zachowania w zależności od typu implementacji.

Będziesz potrzebował 2 głównych rzeczy:

  1. IVisitable z Accept metoda z rozszerzeniem IVisitor jako parametr.
  2. IVisitor z wieloma Visit metody dla każdego wdrożenia z IVisitable

Zacznę od numeru 2.To (w twoim przypadku) będzie interfejs, który zawiera wszystkie implementacje twojej metody obliczeniowej (dla każdej z klas, o których wspomniałeś, które chcesz utworzyć). Zadzwońmy do ciebie Visitor i Visit metody Calculator i Calculate. Wtedy będziesz miał:

interface ICalculator
{
FinancialTransactionObject Calculate(Element1 element);
FinancialTransactionObject Calculate(Element2 element);
FinancialTransactionObject Calculate(Element3 element);
.
.
}

Wtedy pierwsza część - wszystkie klasy elementów odziedziczą klasę bazową Element, które zostaną wdrożone IVisitable. A potem coś takiego:

abstract class Element
{
public FinancialTransactionObject result { get; private set; }

protected void Accept(ICalculator calculator)
{
this.result = calculator.Calculate(this);
}
}

W efekcie otrzymasz coś takiego:

var calculator = new Calculator(); //this is the class that implements the interface
var el1 = new Element1();
var el2 = new Element2();

el1.Accept(calculator);
el2.Accept(calculator);

Wtedy oczywiście na podstawie implementacji Twoje obiekty el będą miały swoje wartości wynikowe.

Nie jestem pewien, czy jest to najlepsze rozwiązanie twojego problemu (jeśli w ogóle takie istnieje), ale wydaje mi się, że jest to to, którego szukasz. Mam nadzieję, że to pomoże.

PS: Myślałem o nazewnictwie IVisitable do ICalculatable ale to zabrzmiało dziwnie :)