【问题标题】:Can I eliminate duplicate code for below derived classes and move to abstract base class我可以消除以下派生类的重复代码并移至抽象基类吗
【发布时间】:2018-10-08 01:21:02
【问题描述】:

我有一个抽象基类,开始一个所有派生类共有的timer

public abstract class BaseClass
{
    public virtual void Start() { _timer.Start(); }
}

现在我需要为每个派生类加载不同的 JSON 配置文件并创建文件,

public class DerivedClass1 : BaseClass
{
    private readonly List<config> configs = new List<config>();

    public DerivedClass1()
    {
        configs = JsonSettings.GetConfigurations(@"./Configurations/1.json");
    }
    public override void Start()
    {
        base.Start();

        foreach (var configuration in configs)
        {
            JsonSettings.CreateConfigFile(configuration);
        }
    }
}

public class DerivedClass2 : BaseClass
{
    private readonly List<config> configs = new List<config>();

    public DerivedClass2()
    {
        configs = JsonSettings.GetConfigurations(@"./Configurations/2.json");
    }
    public override void Start()
    {
        base.Start();

        foreach (var configuration in configs)
        {
            JsonSettings.CreateConfigFile(configuration);
        }
    }
}

我看到有很多代码在各种派生类中重复。

我可以移动这些代码以及abstract base 类还是有其他方法?

【问题讨论】:

  • 您的BaseClass 和派生类代表什么?它们的作用是什么?
  • 最佳实践是拥有一个单独的实用程序类实现,其中将包含这些重复的代码。并通过依赖注入将该类注入到您的新类中。 “偏好组合优于继承”
  • 我没有放完整的代码,但是缺少什么?
  • @Naruto,你能举个例子吗?
  • 当然!给我一分钟!

标签: c# inheritance


【解决方案1】:

我认为您可以将代码简化为:

public abstract class BaseClass
{
    protected virtual List<config> configs { get; set; } = new List<config>();
    public virtual void Start()
    {
        _timer.Start();
        foreach (var configuration in configs)
        {
            JsonSettings.CreateConfigFile(configuration);
        }
    }
}

public class DerivedClass1 : BaseClass
{
    public DerivedClass1()
    {
        configs = JsonSettings.GetConfigurations(@"./Configurations/1.json");
    }
}

public class DerivedClass2 : BaseClass
{
    public DerivedClass2()
    {
        configs = JsonSettings.GetConfigurations(@"./Configurations/2.json");
    }
}

【讨论】:

    【解决方案2】:
    public interface BaseClass
    {
        void Start();
    }
    
    public interface IBaseClassUtil
    {
        void Start();
        void setConfigs(List<config> configs);
    }
    
    public class BaseClassUtil : IBaseClassUtil
    {
        System.Timers.Timer _timer;
        public  List<config> _configs { get; set; } = new List<config>();
        public void Start()
        {
            _timer.Start();
            foreach (var configuration in _configs)
            {
                JsonSettings.CreateConfigFile(configuration);
            }
        }
    
        public void setConfigs(List<config> configs)
        {
            _configs = configs;
        }
    }
    public class DerivedClass1 : BaseClass
    {
        private IBaseClassUtil _baseUtility;
        public DerivedClass1(IBaseClassUtil baseUtility)
        {
            _baseUtility = baseUtility;
            _baseUtility.setConfigs( JsonSettings.GetConfigurations(@"./Configurations/1.json"));
        }
    
        public void Start()
        {
            _baseUtility.Start();
        }
    }
    
    public class DerivedClass2 : BaseClass
    {
        private IBaseClassUtil _baseUtility;
        public DerivedClass2(IBaseClassUtil baseUtility)
        {
            _baseUtility = baseUtility;
            _baseUtility.setConfigs(JsonSettings.GetConfigurations(@"./Configurations/2.json"));
        }
    
        public void Start()
        {
            _baseUtility.Start();
        }
    }
    

    这可能是过度设计的。或者可能不适合您当前的要求。 优点是

    1. 如果您希望将来对 IBaseClassUtil 有不同的实现,它会更容易

      1. 巨大的优势是这段代码是可测试的

    【讨论】:

      【解决方案3】:

      如果类仅在配置路径上有所不同,那么您只能有一个派生类将路径作为其 ctor 中的参数。

      public DerivedClass(string configurationPath)
      {
          configs = JsonSettings.GetConfigurations(configurationPath);
      }
      

      请注意,在您的架构中包含继承的决定有关代码重复,并且不向我们提供有关函数甚至类名称的任何信息(BaseClass 和 @ 987654323@ 没有任何意义。它们代表什么?它们的功能是什么?它们为什么相关?)您让我们无法真正帮助您进行设计。

      【讨论】:

        猜你喜欢
        • 2015-05-30
        • 2012-10-29
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        • 1970-01-01
        相关资源
        最近更新 更多