VB.NET初学者设计问题

发布于 2024-10-12 18:57:10 字数 1237 浏览 1 评论 0原文

VB.NET、VS 2010、.NET 4

你好,

我已经编写了一个应用程序。我发现它充满了循环引用。我想重写部分代码以改进其设计。我已经阅读了有关分层编程的内容,并希望为我的应用程序实现类似的东西。

背景:我的应用程序是工业机器的控制程序。它解析一个配方(来自 Excel 文件),其中包含各种连接设备的计时信息和设定点。设备主要分为三种类型:大多数通过 Beckhoff 端子连接并通过 TwinCAT(Beckhoff 的伪 PLC 软件)进行通信,另外两种是 RS-232 设备,每种设备具有不同的通信协议。我可以通过 Beckhoff 提供的 .NET API 与 Beckhoff 设备进行通信。我已经为两个 RS-232 设备编写了解析器类。 Beckhoff 设备有些是输入,有些是输出;有些是数字的,有些是(伪)模拟的。

我认为我的问题是,在编写应用程序时,我试图将自己的注意力集中在 OOP 上,所以我随意地创建了类,而没有清楚地了解它们的层次结构。在某些时候,我尝试做我认为正确的事情,比如创建一个“Device”类,该类由“TwinCatDevice”类和“Rs232Device”类继承。但后来我把所有的通信代码都塞到了这些类中。

我现在正在尝试创建一些通信模块(例如,UtilTwinCat、UtilRs232),其中包含“连接”、“断开”、“读取”、“写入”等抽象方法。然后我尝试重写我的“ Device”类和子类使用这些模块,因此它们不必包含任何(有时是冗余的)通信代码。

这是我的问题:为每种类型的通信类型创建单独的类是一个好的设计吗?即,我应该有“TwinCatReadOnlyDigital”、“TwinCatReadOnlyAnalog”、“TwinCatWriteOnlyDigital”、“TwinCatWriteOnlyAnalog”、“TwinCatReadWriteDigital”、“TwinCatReadWriteAnalog”、“Rs232ReadOnlyDigital”等吗?或者也许是一些接口,如 IReadOnly、IWriteOnly、IDuplex?

这似乎不是正确的方法,因为我想象擅长编程的人不会最终为每种可能性提供十亿个不同的类。有什么方法可以在运行时有选择地在类上实现接口吗?我认为这是一个愚蠢的问题......我仍在努力思考为什么人们会使用界面。我正在寻找一些关于如何解决此类设计问题的基本见解。具体来说,如果您有很多略有不同的“事物”,那么创建大量略有不同的类的最佳方法是吗?

预先非常感谢, Brian

编辑:我只是想补充一点,要明确的是,参数已知的设备数量是有限的,因此为我需要的所有类型编写类会很简单。我只是想知道是否有更好的方法。

VB.NET, VS 2010, .NET 4

Hello,

I've written an application. I've discovered that it is full of circular references. I would like to rewrite portions of my code to improve its design. I have read about tiered programming and want to implement something like it for my application.

Background: My application is a control program for an industrial machine. It parses a recipe (from an Excel file) which contains timing information and setpoints for the various attached devices. There are three main types of devices: Most are connected through Beckhoff terminals and communicate via TwinCAT (Beckhoff's pseudo-PLC software) and two are RS-232 devices, each with a different communication protocol. I can communicate with the Beckhoff devices via a .NET API provided by Beckhoff. I have written parser classes for the two RS-232 devices. Some of the Beckhoff devices are inputs, some are outputs; some are digital, some are (pseudo-)analog.

I think my problem is that I was trying to wrap my head around OOP while writing the application so I created classes willy-nilly without a clear idea of their hierarchy. At some points, I tried to do what I thought was right by, say, making a "Device" class which was inherited by, say, a "TwinCatDevice" class and a "Rs232Device" class. But then I just stuffed all of the communication code in those classes.

What I'm trying now is creating some communication modules (e.g., UtilTwinCat, UtilRs232) that contain abstract methods like "Connect", "Disconnect", "Read", "Write", etc. Then I'm trying to rewrite my "Device" class and subclasses to use these modules so they don't have to contain any of the (sometimes redundant) communication code.

Here's my question: Would it be good design to create separate classes for each type of communication type? i.e., should I have, say, "TwinCatReadOnlyDigital", "TwinCatReadOnlyAnalog", "TwinCatWriteOnlyDigital", "TwinCatWriteOnlyAnalog", "TwinCatReadWriteDigital", "TwinCatReadWriteAnalog", "Rs232ReadOnlyDigital", etc? Or perhaps some interfaces like IReadOnly, IWriteOnly, IDuplex?

This seems like it can't be the right approach in that I imagine someone who is good at programming wouldn't end up with a billion different classes for every eventuality. Is there some way I could selectively implement an interface on a class at run time? I think that's a stupid question... I'm still trying to wrap my head around why one would use an interface. I'm looking for some basic insight on how to grapple with this type of design problem. Specifically, if you have a lot of "things" that differ slightly, is the best approach to create lots of classes that differ slightly?

Thanks a lot in advance,
Brian

Edit: I just wanted to add, to be clear, there is a finite number of devices whose parameters are known, so it would be straightforward to write classes for all the types I'd need. I just wonder if there's a better approach.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌辣 2024-10-19 18:57:10

对于任何具体答案来说,这些信息实际上还不够,但让我提出一些建议。

“我仍在尝试理解为什么人们会使用界面。”

主要是因为这样您就可以“对接口进行编程”,也就是说您不必关心您是否正在使用 Beckhoff 或 RS-232 设备 - 您只关心您可以向其发送数据。只是为了明确一点:接口包含实现。实现接口的类承诺为接口的功能提供具体的实现。

  • IWriteOnly 和 IDuplex 使用两个接口代替 IReadOnly:IWriteable 和 IReadable(或任何有意义的名称)。双工类将实现这两​​个接口。
  • 策略或更可能的模板方法模式可能会帮助您处理略有不同的类。甚至可能是简单的子类化,但请记住,通常有更简单、更好的解决方案。
  • 不要重复自己(DRY):尝试为每一段逻辑找到一个且唯一的位置。
  • 多个类共享的功能应该驻留在超类或实用程序类中。

此外,更具体的问题将带来更具体的答案:)

That's not really enough information for any concrete answers, but let me make a few suggestions.

"I'm still trying to wrap my head around why one would use an interface."

Mainly because then you can "program to the interface", that is you needn't care if you're working with a Beckhoff or an RS-232 device - you only care that you can send data to it. Just to make it clear: interfaces don't contain implementations. Classes implementing an interface promise to provide concrete implementations for the functions of the interface.

  • Instead of IReadOnly, IWriteOnly and IDuplex use two interfaces: IWriteable and IReadable (or whatever names make sense). Duplex classes will implement both interfaces.
  • The Strategy or more likely the Template method patterns may help you with the slightly different classes. Maybe even simple subclassing, but keep in mind that there's often a simpler, nicer solution.
  • Don't repeat yourself (DRY): try to find one and only one place for every piece of logic.
  • Functionality shared by several classes should reside in a superclass or utility classes.

Also, more concrete questions will result in more concrete answers :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文