首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >相同接口不同的ctor实现

相同接口不同的ctor实现
EN

Stack Overflow用户
提问于 2017-07-20 09:53:37
回答 1查看 66关注 0票数 0

我有并且在接口ICalibrationToolsLoader

代码语言:javascript
复制
namespace Utilities.Interfaces
{
    public interface ICalibrationToolsLoader
    {            
        string GetDefaultIspFile(string selectedSensorType = null);
        IspSectionUiSettings GetIspSectionUiSettings();
        List<CalibrationGroup> GetCmcGroupOrder();            
    }
}

两个类实现了它。

代码语言:javascript
复制
public class Ipu6CalibraitionToolsLoader : ICalibrationToolsLoader
{
       private string _selectedSensorType;
       public Ipu6CalibraitionToolsLoader(string selectedSensorType)
       {
           _selectedSensorType = selectedSensorType;
           _ispSectionUiSettings = Serialization.DataContract.Deserialize<IspSectionUiSettings>(GetDefaultIspFile(_selectedSensorType));
            InitCmcOrder();
       }

       public string GetDefaultIspFile(string selectedSensorType = null)
       {
           string location = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
           string pathSuffix = null;
           switch ((IPU6SensorType)Enum.Parse(typeof(IPU6SensorType), selectedSensorType))
           {
               case IPU6SensorType.None:
                   break;
               case IPU6SensorType.Bayer:
                   pathSuffix = "IPUs\\IPU6\\IPU6DefaultsIspFile.xml";
                   break;
               case IPU6SensorType.MD:
                   pathSuffix = "IPUs\\IPU6\\IPU6MdDefaultsIspFile.xml";
                   break;                
               default:
                   throw new ArgumentOutOfRangeException("selectedSensorType", selectedSensorType, null);
            }

            if (pathSuffix != null)
            {
                string path = Path.Combine(location, pathSuffix);
                return path;
            }
            throw new Exception("missing defaultIspFileXml");
        }

    public void InitCmcOrder()
    {
        _cmcCalibrationToolsOrder = new List<CalibrationGroup>
        {
            CalibrationGroup.GeneralDataTools,
            CalibrationGroup.SensorAndModuleSettingsTools,
            CalibrationGroup.LateralChromaticAberrationTool,
        };
    }
}
代码语言:javascript
复制
public class Ipu4CalibraitionToolsLoader : ICalibrationToolsLoader
{
    public Ipu4CalibraitionToolsLoader()
    {
        _ispSectionUiSettings = Serialization.DataContract.Deserialize<IspSectionUiSettings>(GetDefaultIspFile());
        InitCmcOrder();
    }

    public string GetDefaultIspFile(string selectedSensorType = null)
    {
        string location = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        string pathSuffix = "IPUs\\Broxton\\IPU4DefaultsIspFile.xml";
        string path = Path.Combine(location, pathSuffix);
        return path;
    }

    public void InitCmcOrder()
    {
        _cmcCalibrationToolsOrder = new List<CalibrationGroup>
        {
            CalibrationGroup.GeneralDataTools,
            CalibrationGroup.SensorAndModuleSettingsTools,
            CalibrationGroup.LateralChromaticAberrationTool,
        };
    }
}

基本上,大多数函数是相同的,但是,像构造函数和GetDefaultIsp这样的函数需要有不同的实现。

我试图使用继承,但是在构造函数中调用一个虚拟函数是一个很大的否定。你能建议另一种方法吗?

有两个类使用相同的接口,但是有些方法应该有不同的实现吗?

我不希望有另一个像Init()这样的函数,它需要在构造函数之后被调用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-20 10:24:26

编辑:添加了IoC实现来解决您的问题!

IoC版本

在我看来,IoC解决方案要优雅得多,但在您不习惯IoC的情况下,维护起来可能要复杂一些。

由于plalx在评论中提出了这一建议,所以值得赞扬:D。

代码语言:javascript
复制
// There is no need for an interface anymore (but you can keep it of course)
public class IpuCalibrationToolsLoader
{
    private string _selectedSensorType;
    private string _ispSectionUiSettings;
    private List<CalibrationGroup> _cmcCalibrationToolsOrder;

    public IIspFileProvider Provider { get; private set; }

    // Notice the internal constructor. No one will be able to create an instance of IpuCalibrationToolsLoader out of your assembly except the factory
    internal IpuCalibrationToolsLoader(IIspFileProvider provider, string selectedSensorType = null)
    {
        this.Provider = provider;
        _selectedSensorType = selectedSensorType;

        _ispSectionUiSettings = Serialization.DataContract.Deserialize<IspSectionUiSettings>(provider.GetDefaultIspFile(_selectedSensorType));

        this.InitCmcOrder();
    }

    public void InitCmcOrder()
    {
        _cmcCalibrationToolsOrder = new List<CalibrationGroup>
        {
            CalibrationGroup.GeneralDataTools,
            CalibrationGroup.SensorAndModuleSettingsTools,
            CalibrationGroup.LateralChromaticAberrationTool,
        };
    }

    [..] // Since the Provider is exposed as a properties of your IpuCalibrationClassLoader, there is no need for defining the GetDefaultIspFile methods within this class
}

public interface IIspFileProvider
{
    string GetDefaultIspFile(string selectedSensorType = null);
}

public class Ipu6FileProvider : IIspFileProvider
{
    public string GetDefaultIspFile(string selectedSensorType = null)
    {
        string location = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        string pathSuffix = null;
        switch ((IPU6SensorType)Enum.Parse(typeof(IPU6SensorType), selectedSensorType))
        {
            case IPU6SensorType.None:
                break;
            case IPU6SensorType.Bayer:
                pathSuffix = "IPUs\\IPU6\\IPU6DefaultsIspFile.xml";
                break;
            case IPU6SensorType.MD:
                pathSuffix = "IPUs\\IPU6\\IPU6MdDefaultsIspFile.xml";
                break;
            default:
                throw new ArgumentOutOfRangeException("selectedSensorType", selectedSensorType, null);
        }

        if (pathSuffix != null)
        {
            string path = Path.Combine(location, pathSuffix);
            return path;
        }
        throw new Exception("missing defaultIspFileXml");
    }
}

public class Ipu4FileProvider : IIspFileProvider
{
    public string GetDefaultIspFile(string selectedSensorType = null)
    {
        string location = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        string pathSuffix = "IPUs\\Broxton\\IPU4DefaultsIspFile.xml";
        string path = Path.Combine(location, pathSuffix);
        return path;
    }
}

public static class IpuCalibrationToolsLoaderFactory
{
    public static IpuCalibrationToolsLoader GetIpu4CalibrationToolsLoader()
    {
        return new IpuCalibrationToolsLoader(new Ipu4FileProvider());
    }

    public static IpuCalibrationToolsLoader GetIpu6CalibrationToolsLoader(string selectedSensorType)
    {
        return new IpuCalibrationToolsLoader(new Ipu6FileProvider(), selectedSensorType);
    }
}

继承版本

下面是使用抽象类的版本。抽象类是不能实例化的类。它只保存一些代码:

代码语言:javascript
复制
public abstract class BaseCalibrationToolsLoader : ICalibrationToolsLoader
{
    public BaseCalibrationToolsLoader()
    {
        // put here the shared constructor code
        _cmcCalibrationToolsOrder = new List<CalibrationGroup>
        {
            CalibrationGroup.GeneralDataTools,
            CalibrationGroup.SensorAndModuleSettingsTools,
            CalibrationGroup.LateralChromaticAberrationTool,
        };
    }

    public List<CalibrationGroup> GetCmcGroupOrder()
    {
        // Put here the shared code among the two implementation
    }

    // As the implementation is different, you declare the method abstract so you only implement it in the concret classes
    public abstract string GetDefaultIspFile(string selectedSensorType = null);
}

现在,您可以创建从抽象类派生的具体实现:

代码语言:javascript
复制
public class Ipu4CalibraitionToolsLoader : BaseCalibrationToolsLoader 
{
    public Ipu4CalibraitionToolsLoader ()
        : base() // <- call the protected constructor
    {
        // put here the specific implementation constructor code
        // notice that the constructor of the abstract class will **ALWAYS** be call before this code
        _ispSectionUiSettings = Serialization.DataContract.Deserialize<IspSectionUiSettings>(GetDefaultIspFile());
    }

    // The GetCmcGroupOrder is already implemented, nothing to do about it

    // With the sealed keyword, the method cannot be overriden in another class
    public sealed override void GetDefaultIsp(string selectedSensorType = null)
    {
        // put here the concrete implementation for Ipu4
    }
}

public class Ipu6CalibraitionToolsLoader: BaseCalibrationToolsLoader 
{
    public Ipu6CalibraitionToolsLoader(string selectedSensorType)
        : base() // <- call the protected constructor
    {
        // put here the specific implementation constructor code
        // notice that the constructor of the abstract class will **ALWAYS** be call before this code
        _selectedSensorType = selectedSensorType;
        _ispSectionUiSettings = Serialization.DataContract.Deserialize<IspSectionUiSettings>(GetDefaultIspFile(_selectedSensorType));
    }

    // The GetCmcGroupOrder is already implemented, nothing to do about it

    // With the sealed keyword, the method cannot be overriden in another class
    public sealed override void GetDefaultIsp(string selectedSensorType = null)
    {
        // put here the concrete implementation for Ipu6
    }
}

对于抽象构造函数,您可以在抽象类中定义一个虚拟方法,并在具体实现中调用它,以便共享代码的一部分:

代码语言:javascript
复制
public abstract class BaseCalibrationToolsLoader : ICalibrationToolsLoader
{
    [..]

    // By using the virtual keyword, you allow your method to be overriden in the derived classes
    public virtual void PartiallySharedMethod()
    {
        // Shared implementation
    }

    [..]
}

在具体实施中:

代码语言:javascript
复制
public class Ipu4CalibraitionToolsLoader : BaseCalibrationToolsLoader 
{
    [..]

    public override void PartiallySharedMethod()
    {
        // Unlike in the constructor, you can call the base method whenever you want.
        // Some specific code can came here
        base.PartiallySharedMethod();
        // And other specific code can also came here
    }

    [..]
}

public class Ipu6CalibraitionToolsLoader: BaseCalibrationToolsLoader 
{
    [..]

    public override void PartiallySharedMethod()
    {
        // Unlike in the constructor, you can call the base method whenever you want.
        // Some specific code can came here
        base.PartiallySharedMethod();
        // And other specific code can also came here
    }

    [..]
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45211297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档