Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重构类设计以传达设计意图_C#_Design Patterns_Class Design_Ooad_Template Method Pattern - Fatal编程技术网

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。