У меня есть следующий класс дизайн. Полный код доступен в «How to achieve this functionality using Generics?». Код прекрасно работает и решает проблему литья, упомянутую в «Refactoring Code to avoid Type Casting»Рефакторинг класс дизайна для передачи намерений дизайна
В RetailInvestmentReturnCalculator
классе метод GetInvestmentProfit()
использует CalculateBaseProfit()
метод, присутствующий в InvestmentReturnCalculator
абстрактного базового класса. Этот факт не проявляется в дизайне класса.
ВОПРОС
- Как реорганизовать этот дизайн класса передать вышеупомянутый факт?
- Что такое руководство по дизайну, которое предотвратит подобные ошибки дизайна?
Примечание: Martin Fowler: Is Design Dead? говорит
Что мы подразумеваем под архитектуру программного обеспечения? Для меня термин архитектура передает понятие основных элементов системы, которые трудно изменить. Основа, на которой остальные должны быть построены
Class Diagram
Аннотация
public abstract class InvestmentReturnCalculator
{
#region Public
public double ProfitElement { get; set; }
public abstract double GetInvestmentProfit();
#endregion
#region Protected
protected double CalculateBaseProfit()
{
double profit = 0;
if (ProfitElement < 5)
{
profit = ProfitElement * 5/100;
}
else
{
profit = ProfitElement * 10/100;
}
return profit;
}
#endregion
}
public abstract class InvestmentReturnCalculator<T> : InvestmentReturnCalculator where T : IBusiness
{
public T BusinessType { get; set; }
}
Бетон
public class RetailInvestmentReturnCalculator : InvestmentReturnCalculator<IRetailBusiness>
{
public RetailInvestmentReturnCalculator(IRetailBusiness retail)
{
BusinessType = retail;
//Business = new BookShop(100);
}
public override double GetInvestmentProfit()
{
ProfitElement = BusinessType.GrossRevenue;
return CalculateBaseProfit();
}
}
Как это не видно из дизайна класса? Создание модификатора доступа 'protected', а не' private', делает это очевидным. Что еще более важно, возможно, этот метод «GetInvestmentProfit» не имеет хорошего названия, поскольку он не описывает ДВА отдельных вещей, которые он делает ... Возможно, его нужно переименовать? как насчет 'SetProfitElementAndCalculateProfit()'? –
@CharlesBretana Спасибо за 'частную идею. Разве это не 'ДВА отдельных вещей' в методе, который нужно реорганизовать? – Lijo
Обычно методы, классы и т. Д. Должны делать ОДНУ вещь и делать это хорошо. Это называется принципом единой ответственности (SRP). И это очень хороший общий принцип. Однако, когда вы перемещаетесь вверх и вниз в стеке, то, что на самом деле означает «ОДИН ВЕЩЬ», может измениться по мере изменения уровня абстракции. На высоком уровне это может быть «Заказать книгу». Несколько слоев вниз, это может означать корректировку инвентаря, перенос книги на отправку, отправку счета и т. Д. Но на каждом уровне один метод должен отвечать за выполнение одной задачи на этом уровне абстракции ... –