C# 定义采用不同参数的接口方法
我的应用程序使用连接到PC的测量仪器。我希望能够使用来自不同供应商的类似仪器 所以我定义了一个接口:C# 定义采用不同参数的接口方法,c#,.net,oop,C#,.net,Oop,我的应用程序使用连接到PC的测量仪器。我希望能够使用来自不同供应商的类似仪器 所以我定义了一个接口: interface IMeasurementInterface { void Initialize(); void Close(); } 到目前为止还不错。在测量之前,我需要设置仪器,这意味着不同仪器的参数非常不同。因此,我想定义一个方法,该方法采用可以具有不同结构的参数: interface IMeasurementInterface {
interface IMeasurementInterface
{
void Initialize();
void Close();
}
到目前为止还不错。在测量之前,我需要设置仪器,这意味着不同仪器的参数非常不同。因此,我想定义一个方法,该方法采用可以具有不同结构的参数:
interface IMeasurementInterface
{
void Initialize();
void Close();
void Setup(object Parameters);
}
然后,我会将对象投射到我需要的任何对象。这是要走的路吗?那可能行得通。另一种选择是在字典中传递参数。您最好创建一个抽象的“parameters”类,该类由每个不同的instruments参数扩展。。。e、 然后使用泛型来确保将正确的参数传递给正确的类
public interface IMeasurement<PARAMTYPE> where PARAMTYPE : Parameters
{
void Init();
void Close();
void Setup(PARAMTYPE p);
}
public abstract class Parameters
{
}
公共接口i测量,其中PARAMTYPE:参数
{
void Init();
无效关闭();
无效设置(p型);
}
公共抽象类参数
{
}
然后针对每个特定设备
public class DeviceOne : IMeasurement<ParametersForDeviceOne>
{
public void Init() { }
public void Close() { }
public void Setup(ParametersForDeviceOne p) { }
}
public class ParametersForDeviceOne : Parameters
{
}
公共类设备One:IMeasurement
{
public void Init(){}
公共void Close(){}
public void设置(参数fordeviceone p){}
}
公共类参数ordeviceOne:参数
{
}
在我看来,这种模式可能很有用,尤其是当你打算对你的应用程序进行单元测试时 如果您要处理甚至不止一种设备类型,那么控制器+设备接口分离(使用名称vlaue对进行通信)将是一个很好的解决方案
解耦
使用名称-值对可以将代码分离为设备+控制器+应用程序代码结构
示例代码
class DeviceInterface
{
void Initialize(IController & Controller);
void Close();
bool ChangeParameter(const string & Name, const string & Value);
bool GetParam(string & Name, string &Value );
}
创建每个设备实现时,应使用控制器的标识来创建,控制器可接受其命令并将其转换为实际设备命令
interface IController
{
Initialize(DeviceSpecific & Params);
Close();
bool ChangeParameter(string & Name, string & Value);
bool ChangeParams(string & Name[], string &Value []);
}
您的用户代码将如下所示
IController objController = new MeasurementDevice(MeasureParram);
DeviceInterface MeasureDevice = new DeviceInterface(objController);
string Value;
MeasureDevice.GetParam("Temperature", Value);
if (ConvertStringToInt(Value) > 80)
{
MeasureDevice.ChangeParameter("Shutdown", "True");
RaiseAlert();
}
DeviceInterface类应该做的就是将命令传递给控制器。控制器应负责设备通信
界面分离的优势
防止更改
这种解耦将允许您将应用程序代码与控制器隔离。设备中的更改不会影响您的用户代码
应用程序代码的可维护性
class DeviceInterface
{
void Initialize(IController & Controller);
void Close();
bool ChangeParameter(const string & Name, const string & Value);
bool GetParam(string & Name, string &Value );
}
另外,用户代码总是干净的,您只需要处理应用程序逻辑。但是,如果您定义了多个接口/创建了模板或泛型,并具有特定于控制器的多种类型的参数结构,那么您的代码中将包含大量依赖于设备的垃圾,这可能会损害可读性,并在设备/其参数发生更改时产生维护问题
易实施性
class DeviceInterface
{
void Initialize(IController & Controller);
void Close();
bool ChangeParameter(const string & Name, const string & Value);
bool GetParam(string & Name, string &Value );
}
您还可以将不同的控制器实现划分到自己的项目中。此外,您的应用程序还可以使用XML文件等以更动态的方式配置命令和响应,这些文件可以与控制器类一起提供,从而使整个应用程序在本质上变得更动态
现实生活
class DeviceInterface
{
void Initialize(IController & Controller);
void Close();
bool ChangeParameter(const string & Name, const string & Value);
bool GetParam(string & Name, string &Value );
}
该领域的领导者最新的生产控制器项目之一也以同样的方式工作。但是他们使用LON进行设备通信
LON?
控制器(比如空调/锅炉/风扇等)网络中使用的LON协议使用此概念与各种设备进行通信
因此,您所需要的只是一个接口,它可以与您的设备进行通信,然后使用LON将名称-值对发送给它。标准协议的使用还允许您与测量仪器之外的其他设备通话。如果您的设备使用LON,则可以使用LON的开源实现
如果您的设备不支持LON,那么您可能必须设计一些用户代码仍然在名称-值对上工作的东西,并且相反的接口将您的名称-值对转换为等效的对应COTROLL struct+,并以设备理解的方式与单个设备通信
希望这有用。这取决于您首先要如何获取参数。如果它们被存储在数据库表或某个配置文件中,并且只需要设置值,那么传入字典可能就可以了(尽管您确实会丢失类型安全性)。如果您的安装过程将稍微复杂一点,那么我会考虑将安装过程抽象一点,并执行双重调度(将CAST操作推到新的安装类)。像这样
public interface IMeasurementInterface
{
void Initialize();
void Close();
void Setup( IConfigurer config );
}
public interface IConfigurer
{
void ApplyTo( object obj );
}
public abstract ConfigurerBase<T> : IConfigurer where T : IMeasurementInterface
{
protected abstract void ApplyTo( T item );
void IConfigurator.ApplyTo(object obj )
{
var item = obj as T;
if( item == null )
throw new InvalidOperationException("Configurer can't be applied to this type");
ApplyTo(item);
}
}
公共接口iMeasureInterface
{
void初始化();
无效关闭();
无效设置(IConfigurer配置);
}
公共接口IConfiguer
{
无效应用程序(对象对象对象);
}
公共抽象配置数据库:IConfiguer,其中T:IMeasurementInterface
{
受保护的摘要无效申请(T项);
void IConfigurator.ApplyTo(对象对象对象)
{
var项目=作为T的obj;
如果(项==null)
抛出新的InvalidOperationException(“Configurer无法应用于此类型”);
ApplyTo(项目);
}
}
这样,您就不会弄乱您的度量类层次结构(或者不提供任何实现,并且假设所有实现都会做您想要的事情)。这还意味着您可以通过传入假(或模拟)测量设备来测试设置代码
如果设置过程需要处理私有或受保护的数据,那么您可以使IConfiguer的具体实现驻留在其相应的测量类中。我的软件必须这样做,因为我需要为金属切割机支持多种不同类型的运动控制器 您的界面具有ba