Наследявах малко над 1000 линии спагетикод. Мога да я разложим на десетина метода, всеки от които създава FinancialTransactionObject, но взема различни дати, суми и други параметри, за да създаде своята транзакция.
Моето черво ми казва да направя всеки метод свой собствен клас. Така че мога да имам дузина класове наследени от базов клас или интерфейс с 1 метод:
abstract FinancialTransactionObject Calculate();
и преместете параметрите или към конструктори илида ги превърне в обществени свойства. Конструкторите означават, че не мога отново да използвам моя инстанция и трябва да създавам нов обект всеки път. Свойствата означават, че консумиращият код може да забрави да ги зададе. Оставянето на параметрите на всеки метод само ми дава дузина методи в отделни файлове и не се чувствам обектно ориентиран.
Изглежда, че вариацията на този проблем се появява често. Има ли добър, последователен, индустриален дизайн, който да се справи с него?
Отговори:
0 за отговор № 1Това наистина звучи като мен Модел на посетителите.
Така че основната идея на модела на посетителя е да промени поведението динамично в зависимост от вида на изпълнението.
Ще ви трябват 2 основни неща:
IVisitable
сAccept
метод, имащIVisitor
като параметър.IVisitor
с много хораVisit
методи за всяко изпълнение наIVisitable
Ще започна от номер 2. Това (във вашия случай) ще бъде интерфейс, който има всички реализации на вашия изчислителен метод (за всеки от класовете, които споменахте, които искате да създадете). Нека ви позвъни Visitor
и Visit
методи Calculator
и Calculate
, След това ще имате:
interface ICalculator
{
FinancialTransactionObject Calculate(Element1 element);
FinancialTransactionObject Calculate(Element2 element);
FinancialTransactionObject Calculate(Element3 element);
.
.
}
Тогава първата част - всички класове елементи, ще наследи базов клас Element
, която ще се прилага IVisitable
, И тогава нещо като:
abstract class Element
{
public FinancialTransactionObject result { get; private set; }
protected void Accept(ICalculator calculator)
{
this.result = calculator.Calculate(this);
}
}
Ще завършите с нещо като:
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);
След това, разбира се, въз основа на изпълнението, вашите обекти на Ел, ще имат своите резултати.
Аз не съм сигурен, че това е най-доброто решение за вашия проблем (ако има такива), но ми се струва като онази, която търсите. Надявам се това да помогне.
PS: Мислех, че именувам IVisitable
да се ICalculatable
но звучи странно :)