跳至页脚内容
Iron Academy Logo
C# 应用程序
C# 应用程序

其他类别

C#接口松散耦合 — 通过Tim Corey(第16课)解释

Tim Corey
44m 47s

在课程"C#应用从头到尾"的第16课中,Tim Corey继续构建创建锦标赛表单,但真正的学习目标远不止连接按钮和列表框。 随着Tim完成表单的连接,他在C#中引入了一个核心软件设计概念:用于松耦合的接口。 这节课显示接口不仅仅是一个抽象的学术概念,而是一个实用的工具,用于解决WinForms应用程序中的实际问题。

在这篇文章中,我们深入研究Tim Corey如何解释接口,为什么使用它们,以及它们如何帮助避免紧耦合。 所有的解释、推理和结论都直接来自Tim的演练,使用他的流程、术语和脚本中的示例。

连接表单很简单 — 正确连接它们并不简单

在1:18,Tim开始连接创建奖品和创建团队的UI元素。 他立即指出,这一步可以感觉很吓人,不是因为调用另一个表单很难,而是因为正确获取数据时人们通常会犯错误。

Tim解释说,挑战不是打开另一个表单——那部分很简单。 挑战是如何在不造成长期设计问题的情况下,让一个表单回到另一个表单。 这是定义合同而不是依赖关系开始重要的地方。

紧耦合的诱惑

大约在1:34,Tim明确指出一个常见错误:直接把创建锦标赛表单与创建奖品表单联系在一起。 在这种方法中,一个类确切地知道它在与哪个其他类交谈。

Tim解释这会导致紧耦合,意味着表单直接依赖于彼此。 如果一个表单更改,另一个表单会受到影响。 如果程序的另一个部分后来想要同样的功能,它不能重用它。

他强调,尽管这可能编译并工作,但这不是一个良好的长期设计选择,尤其是在更大的系统或专业环境中。

在编写代码之前考虑步骤

在2:02,Tim停下来,写下步骤而不是直接进入编写代码。 他列出:

  1. 调用创建奖品表单

  2. 返回一个PrizeModel

  3. 将其添加到选定的奖品列表中

Tim解释,先写下步骤有助于避免逻辑错误,并使代码的意图清晰。 这种结构化思维在引入接口后变得尤为重要,因为接口定义了必须发生的事情,而不是如何发生。

引用类型以及为何返回值并非总是必要的

大约在4:56时,Tim解释了模型传递的一个重要细节。 他提醒观众,他们正在传递地址,而不是对象的副本。

当通过数据连接器保存奖品时,模型已经填充了其ID。 Tim指出重新返回模型通常是不必要的,因为实例已经被修改。

这进一步说明了为何接口不用于盲目地移动数据——它们用于显示完成和责任,而不是重复。

首先传递模型为何是个坏主意

在6:42,Tim讨论了将PrizeModel传入表单构造函数以便两个表单共享同一实例的想法。

他解释了为何在实际使用中失败:如果用户取消表单,您的列表中会出现一个空的或无效的奖品。Tim展示了仅因为两个类可以共享实例数据并不意味着它们应该这样做。

这个时刻进一步强调了接口定义行为而不是数据存储的概念。

直接传递调用表单更加糟糕

大约在7:46,Tim谈到了另一种常见方法:将整个创建比赛表单传入创建奖品表单并调用如SavePrize的公共方法。

Tim解释说这更糟糕的原因是:

  • 奖品表单现在确切知道哪个类在调用它

  • 其他不相关的类无法复用奖品表单

  • 这个类被限定于一个用例

他明确指出这是紧耦合,而这是我们要避免的。

介绍作为契约的接口

在9:01,Tim引入了解决方案:一个接口。

他使用interface关键字创建了一个新的接口,并命名为IPrizeRequester。 Tim提醒观众,接口:

  • 不是一个类

  • 不包含具体方法

  • 用于定义契约

该接口包含一个方法:

  • PrizeComplete(PrizeModel model)

Tim解释说这方法定义了必须发生的事情,而不是如何发生。

接口成员和责任

在9:40,Tim解释道,无论谁实现这个接口,都同意支持该方法。 接口默认拥有公共成员,它不声明实例数据。

这是Tim明确指出接口定义能力而不是存储的地方。 实现类决定在调用方法时要做什么。

传递接口类型而不是类

在10:19,Tim 修改了创建奖品表单构造函数以接受一个IPrizeRequester而不是具体表单。

他解释说这意味着:

  • 会有人调用表单

  • 表单不知道那是谁

  • 唯一的要求是调用者实现了接口

这就是实际中的松耦合。奖品表单依赖于接口类型,而不是特定的类。

存储接口实例以供以后使用

在11:06,Tim在类级别存储接口实例。 他解释说构造函数参数仅在构造函数内部存在,除非存储它们。

这允许奖品表单随后从按钮单击事件内调用PrizeComplete。

回调实现类

在11:49,Tim展示了关键时刻:

callingForm.PrizeComplete(model);

他解释说奖品表单现在回调用实现接口的人,并传达说:

"我完成了,这是完成的模型。"

只有在此调用之后,表单才关闭。 这确保只有在创建成功时才添加奖品。

在比赛表单中实现接口

在13:29,Tim切换到创建比赛表单并实现接口。

在13:58,他解释了this关键字,将其描述为当前实例——内存中的实际对象。 通过传递this,表单在通过接口契约移交其地址。

多个接口,一个类

在18:41,Tim介绍了第二个接口:ITeamRequester。

他解释说,虽然一个类只能继承一个基类(比如Form),但它可以实现多个接口。 这允许单个类支持多个不相关的行为,而无需多重继承。

Tim强调接口不带入代码——它们只定义必需的方法。

模式、一致性和错误检测

靠近42:08,Tim反思为何使用模式很重要。 重复相同的基于接口的结构使漏掉的步骤显而易见且调试更容易。

Tim鼓励写下东西,使用一致的模式,而不是试图将一切都放在脑海中。 据他说,好的设计不是关于完美,而是关于清晰性、结构性以及使未来的更改更容易。

结论

在第16课中,Tim Corey使用一个真实的WinForms用例来展示接口如何实现松耦合。 而不是依赖于抽象的例子,他展示了接口如何:

  • 定义契约

  • 解耦类

  • 支持单个类中的多个接口

  • 防止紧耦合

  • 提高长期的灵活性

到课程结束时,应用程序不仅可以工作——它被结构化为支持成长、重用和清晰。 Tim的方法使接口在真实世界的C#开发中感觉务实、有目的和必不可少。

要完整、端到端地应用这些接口和松耦合概念,请观看完整的第16课视频,其中每一步都在工作中的C#应用程序内实现、测试和完善。

Hero Worlddot related to C#接口松散耦合 — 通过Tim Corey(第16课)解释
Hero Affiliate related to C#接口松散耦合 — 通过Tim Corey(第16课)解释

分享您的所爱,赚取更多收入

您为使用 .NET、C#、Java、Python 或 Node.js 的开发人员创建内容吗?将您的专业知识转化为额外收入!

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我