安全地重新初始化成员对象

时间:2017-04-23 13:56:17

标签: c# oop interface architecture camera

希望这是一个合适的问题,因为我知道这可能是相当普遍的,甚至是非常主观的。

我目前正在重构相机类。我完成后,我将重新使用服务类中的整体相机,但我遇到了一些问题。

相机类本身意味着是由制造商提供的相机API周围的面向对象的包装器(因此可以互换地使用多个相机实现)。从这一点开始,我将打电话给制造商的相机对象" CAM"。

我正在为当前的设计进行规划:

  • ICamera:包含获取图像的方法和属性,以及connect()/ disconnect()方法和连接/断开事件。
  • ISerialCamera:添加了串口对象的摄像机扩展。
  • ISerialPort:包含读/写串行的方法。

ICamera和ISerialPort实现都依赖于CAM。此外,当建立连接时,会创建一个新的CAM实例。这是我的问题所在:

  • 实例化ICamera。
  • Camera.Connect();
  • 发生错误通知
  • 已断开的ICamera。
  • 我再次连接相机(在内部生成新的CAM实例)。

现在用新的CAM实例重新实现串口对象是不好的做法?我问,因为对于面向对象的设计来说,这似乎是不合逻辑的举动。

例如,有人可能会使用我的串行相机对象并决定使用ISerialPort作为某个功能的参数(例如)。

如果我要重新验证我的串口对象,那么它们对串口的本地引用现在无效,并且串口的客户端将更难解决断开连接的问题。

虽然有些人可能认为这是可以接受的,但我宁愿尽可能直观和容易地使用我的相机对象。在我理想的解决方案中,ISerialPort引用将始终指向同一个实例,但串行端口将与新的CAM实例相关联。

我考虑以下解决方案:

  1. 由于串口实现特定于相机实现,我本可以为实现添加一个额外的方法,但接口,例如ISerialPort.Reinitialise(CAM),然后ICamera实现将能够将它的串口转换为实现类型(CAMSerialPort),使其能够调用新的Reinitialise()方法。

    < / LI>
  2. 完全删除串口对象。 ISerialCamera扩展了ICamera,但ISerialCamera直接包含读取/写入串行的方法,而无需添加串行端口对象。这有效,但我宁愿选择一个继承组合解决方案。如果可能的话,我想远离继承层次结构,我觉得它几乎推动我通过直接将更多功能直接绑定到单个对象来破坏单一的可重复性原则。

  3. 这些可以解决问题,但我不确定它是否会被视为广告实践,我不喜欢内部投射只是为了获取方法(但也许我&#39 ; m只是偏见)。

    对于解决此问题或对我的设计选择进行任何更改/添加的任何特定模式的一些有用提示将不胜感激。

    最后要说清楚,我需要客户端使用的接口尽可能通用,绝对没有声明特定于某种类型的相机实现及其内部(或缺少)API。

    编辑:一些额外的信息,以使其更清晰。

    • 获取图像并不需要串口(这就是为什么我选择了不能串行启用的ICamera)。
    • 串口是某些相机的功能,允许串行通信
    • 在我的使用案例中,相机是包含微处理器的更大硬件解决方案的一部分。串口就在那里我可以使用相机将读/写串口发送到微固件(而不是实际在相机上操作)。

    串行端口充当我的客户端计算机和在单独板上运行的固件之间的链接。

    此外,CAM API可能不提供断开连接通知,因此需要根据故障同步整个事件。我有一个串行监视器,定期轮询设备状态。

    • 当设备处于某些状态时,我想禁用采集。
    • 当串行读取失败时,我可以认为相机已断开连接。
    • 当设备状态启用但在读取发生之前进行采集(或在采集期间发生读取)时,我需要处理断开连接和中止采集。

    用例总结:

    • 获取图像(如果已启用并已连接)
    • 读取/写入固件串行(如果连接了相机)

1 个答案:

答案 0 :(得分:0)

我认为如果没有一些特定的代码示例和问题示例,这真的很难回答,但从我能够在这里收集到的一些内容中我可能会使用一些可能的架构替代方案。

首先 - 我认为你直觉 - 你可能不希望相机暴露camera.TakePhoto(serialPort); 界面。

您可以让ICamera表示相机的抽象,并且您始终要求用户指示将信号发送到哪个端口

camera.TakePhoto(); //throw  InvalidOperationException
camera.Connect(serialPort);
camera.TakePhoto(); //Ok

您可以强制var camera = serialPort.Connect(); 要求与串口连接

IDisposable

我的偏好是串口作为相机的工厂

ICameraConnection

您甚至可以将相机设为using(ICameraConnection camera = cameraPort.Connect()) { camera.TakePhoto(); } - 如果您将界面重命名为Form

,这会更直观
Form you want to open

这有点帮助。