C# 重构类设计以传达设计意图
我有以下的课堂设计。完整的代码在“”中提供。该代码工作正常,并解决了“”中提到的铸造问题 在C# 重构类设计以传达设计意图,c#,design-patterns,class-design,ooad,template-method-pattern,C#,Design Patterns,Class Design,Ooad,Template Method Pattern,我有以下的课堂设计。完整的代码在“”中提供。该代码工作正常,并解决了“”中提到的铸造问题 在RetailInvestmentReturnCalculator类中,GetInvestmentProfit()方法使用CalculateBaseProfit()抽象基类中的CalculateBaseProfit()方法。这一事实在课堂设计中并不明显 问题 如何重构此类设计以传达上述事实 防止此类设计错误的设计指南是什么 注:表示 我们所说的软件架构是什么意思?对我来说,架构(architecture)一
RetailInvestmentReturnCalculator
类中,GetInvestmentProfit()
方法使用CalculateBaseProfit()
抽象基类中的CalculateBaseProfit()方法。这一事实在课堂设计中并不明显
问题
如何重构此类设计以传达上述事实
防止此类设计错误的设计指南是什么
注:表示
我们所说的软件架构是什么意思?对我来说,架构(architecture)一词表达了系统核心元素的概念,即难以改变的部分。其余部分必须建立的基础< /P>
类图
摘要
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; }
}
公共抽象类投资返回计算器
{
#地区公众
公共双利润{get;set;}
公开摘要double GetInvestmentProfit();
#端区
#区域保护
受保护的双计算机系统
{
双倍利润=0;
如果(利润<5)
{
利润=利润*5/100;
}
其他的
{
利润=利润*10/100;
}
利润回报;
}
#端区
}
公共抽象类InvestmentReturnCalculator:InvestmentReturnCalculator其中T:IBusiness
{
公共T业务类型{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();
}
}
公共类RetailInvestmentReturnCalculator:InvestmentReturnCalculator
{
公共零售投资回报计算器(IRetailBusiness retail)
{
商业类型=零售;
//商业=新书店(100);
}
公共覆盖双GetInvestmentProfit()
{
ProfitElement=BusinessType.GrossRevenue;
返回CalculateBaseProfit();
}
}
ProfitElement
字段相当难看。我会将它作为InvestmentReturnCalculator
上的一个抽象属性,并在基类中实现它(而不是设置值)——这称为。那么您就不需要GetInvestmentProfit()
方法了
public abstract class InvestmentReturnCalculator
{
#region Public
public abstract double ProfitElement { get; }
#endregion
#region Protected
public double GetInvestmentProfit()
{
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 ProfitElement {get { return BusinessType.GrossRevenue;}}
}
公共抽象类投资返回计算器
{
#地区公众
公共摘要双重利润{get;}
#端区
#区域保护
公共双重投资利润()
{
双倍利润=0;
如果(利润<5)
{
利润=利润*5/100;
}
其他的
{
利润=利润*10/100;
}
利润回报;
}
#端区
}
公共抽象类InvestmentReturnCalculator:InvestmentReturnCalculator其中T:IBusiness
{
公共T业务类型{get;set;}
}
公共类RetailInvestmentReturnCalculator:InvestmentReturnCalculator
{
公共零售投资回报计算器(IRetailBusiness retail)
{
商业类型=零售;
//商业=新书店(100);
}
public override double ProfitElement{get{return BusinessType.GrossRevenue;}
}
如何从课程设计中不明显?使访问修饰符受保护
,而不是私有
,这一点很明显。更重要的是,这个方法GetInvestmentProfit
的名字不太好,因为它没有描述它所做的两件不同的事情。。。也许应该改名?setprofitelement和calculateprofit()
怎么样?@CharlesBretana感谢private
的想法。一个方法中的这两个独立的东西不就是需要重构的东西吗?一般来说,方法、类等应该做一件事,并且做得很好。这被称为单一责任原则(SRP)。这是一个很好的一般原则。然而,当您在堆栈中上下移动时,“一件事”的实际含义可能会随着抽象级别的变化而变化。在高层,这可能是“订购一本书”。向下几层,这可能意味着调整库存、将图书转移到发货、发送发票等。但在每一层,都应该有一个方法负责完成该抽象层的单个任务……很好的解决方案。然而,它是模板方法模式吗?我们在派生类(最终由基类调用)中重写属性
;不是方法
吗?派生类中ProfitElement缺少override
关键字。和getInvestmentProfile()
应该公开了
@Lijo,谢谢你的评论,修复了错误。关于您的第一条评论,我们正在重写getter,这是一个方法。属性只是一个围绕着这对方法的语法糖:getter+setter。