我有并且在接口ICalibrationToolsLoader
namespace Utilities.Interfaces
{
public interface ICalibrationToolsLoader
{
string GetDefaultIspFile(string selectedSensorType = null);
IspSectionUiSettings GetIspSectionUiSettings();
List<CalibrationGroup> GetCmcGroupOrder();
}
}两个类实现了它。
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,
};
}
}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()这样的函数,它需要在构造函数之后被调用。
发布于 2017-07-20 10:24:26
编辑:添加了IoC实现来解决您的问题!
IoC版本
在我看来,IoC解决方案要优雅得多,但在您不习惯IoC的情况下,维护起来可能要复杂一些。
由于plalx在评论中提出了这一建议,所以值得赞扬:D。
// 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);
}
}继承版本
下面是使用抽象类的版本。抽象类是不能实例化的类。它只保存一些代码:
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);
}现在,您可以创建从抽象类派生的具体实现:
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
}
}对于抽象构造函数,您可以在抽象类中定义一个虚拟方法,并在具体实现中调用它,以便共享代码的一部分:
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
}
[..]
}在具体实施中:
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
}
[..]
}https://stackoverflow.com/questions/45211297
复制相似问题