我在设计我的程序的一部分时遇到了问题(不是一次编写它!)。如果不写小说,这很难解释,所以我会尽量简短。
基本上,我有一个程序可以从一个硬件读取/写入参数。目前,它通过Serial实现了这一目标,但最终,我希望通过USB使用FTDI芯片的.NET包装器进行此操作http://www.ftdichip.com/Projects/CodeExamples/CSharp.htm
我认为我的问题是,我知道我需要几层抽象,但我似乎无法知道在哪里绘制线条。首先,我不希望我的ReadParam()
,WriteParam()
和SendCommand()
函数位于我的主窗体类中。这似乎只是拼凑而成。显然他们应该在其他类中,我将实例化。我们暂时称之为Comm
。
第一个选项是,我可以创建一个接口,让我们说IComm
,让我的串口和USB口味都能实现。这样做的问题是,大部分代码都会在两种风格中重复,因为我有特殊的ReadReplyData()
和其他函数,它们在将串行数据返回到GUI之前对其进行预处理。 / p>
所以接下来的选择是让Comm成为一个中间类,它定义了一个接口ICommDriver
。 Comm
会实施私有ReadReplyData()
格式化功能,以及公开ReadParam()
,WriteParam()
和SendCommand()
功能,而ICommDriver
则会指定只有更简单的Read
和Write
函数。
除了两个曲折外,这一切似乎微不足道。一,我希望这显然是多头的,所以GUI不会挂起。所以我认为Comm
将使用BackgroundWorker
来执行所有读/写操作。此外,需要告诉Serial flavor要打开哪个COM端口(从GUI下拉列表),而USB风味则不然。那么我是否要创建界面的那一部分?
感谢大家的帮助,我几天来一直在编写/删除代码,试图找出正确的方法!
乔纳森
答案 0 :(得分:7)
我知道我想要几层 抽象,但我似乎无法知道 在哪里画线
这就是你的问题所在。这是一个根本上有缺陷的发展方法,正是导致这种瘫痪的原因。首先开发几个具体实现的味道。使用kludgy if type1 else type2
逻辑让他们在您的应用程序中工作。 然后返回并重构它们以分享共同的合同,共同基础,你有什么。 非常明显需要去哪里。
评论中有更多细节:
如果您在实现之间共享代码,则应使用抽象类。根据我的经验,最好将公共方法保持最终,并从公共方法中调用受保护的抽象方法,如下所示:
public interface IComm
{
void WriteParam(...);
}
public abstract class CommStandardBase : IComm
{
public void WriteParam(...)
{
DoWriteParam(...);
}
private void DoWriteParam(...)
{
CommonWrite1(...);
HandleWriteParam(...);
CommonWrite2(...);
}
protected abstract void HandleWriteParam(...);
private void CommonWrite1(...)
{
...
}
private void CommonWrite2(...)
{
...
}
}
让每个班级都自成一体。它应该是单实例,单线程,可以在工人和记者之间传递。
答案 1 :(得分:1)
关于您需要哪种接口,最终取决于您以及知道此应用程序如何在较低级别工作的人。我想回应关于在UI中使用您的实现的部分,以及使用BackgroundWorker关于Comm的评论。我建议反过来。 BackgroundWorker实际上是一个UI级别的组件....但是Comm更像是一个“中心”组件(就像企业应用程序中的业务对象)。您的UI应创建BackgroundWorker,然后创建Comm实例以执行所需的工作,并协调Comm中的任何事件以更新UI。如果您需要UI和BackgroundWorker在很长一段时间内进行通信,我建议您创建一些UI可以创建的数据传输对象,放入队列,并使用ManualResetEvent或AutoResetEvent线程句柄在UI之间进行通信线程和BackgroundWorker。这应该会给你一个更松散耦合的产品,允许你独立开发你的Comm类,可以显示它的任何类型的UI(可能允许你有WindForms,WPF,命令行,甚至可能是PowerShell客户端。)
答案 2 :(得分:1)
我在某种程度上处于VB.NET模式,所以这里......
Interface IComm
Function ReadParam()
Function WriteParam()
Function SendCommand()
End Interface
>
MustInherit Class CommBase
.... Load this up with the overideable
End Class
然后只需实现接口并继承基础。我也同意Rex M.请不要因松耦合而推得太远。