oop - 耦合 - 除了更改方法签名或返回类型之外,更改一个模块如何影响另一个模块?

标签 oop design-patterns interface dependencies language-agnostic

在高耦合环境中,更改一个模块会影响另一个模块。好的,但我看不出这怎么可能(除了更改方法签名或返回类型)?

好吧,如果我改变一个类,那么它只能在以下情况下破坏其他类中的代码:

  • 如果我突然改变了一个方法的返回类型——那么我将不得不去另一个类并修复类型的不匹配。
  • 如果我更改方法签名 - 那么我将不得不转到所有依赖类并在调用更改的方法的任何地方更改方法参数。

  • 出于同样的原因,依赖抽象(接口(interface))是很好的,这样我们就可以保证定义的方法会在那里。

    除此之外,更改一个类还能如何影响另一个依赖类?

    最佳答案

    即使这被标记为“Java”,我也会给出一个更广泛的答案。

    耦合用模块 A 在使用模块 B 时做出的假设来表示。模块 A 做出的假设越多,它与模块 B 的耦合就越多。

    一个模块的 API 基本上是它的消费者可以做出的一组假设。返回类型或方法签名只是编译器可以验证的假设。

    例如,SimCity was coupled with Windows 3.x memory allocator .内存分配器有一个契约(Contract),说你可以假设 X、Y 和 Z,就是这样。不能假设任何其他行为。但 SimCity 假设了这一点,因此,他们无法更改 Windows 95 中的内存分配器(嗯,不是在 SimCity 执行时)。

    显然这不是有意的耦合——任何关于模块超出其接口(interface)的假设都应该是无意的,但这仍然是一个假设。

    其他示例包括:

  • 一个密码哈希 API,它告诉它的消费者哈希算法是什么。然后,消费者可能会将散列密码的长度硬编码到数据库模式中,这意味着只有在数据库迁移之后才能将其更改为具有更长散列的更安全算法。
  • 每个使用 protobuf 的人不仅与它的 API 耦合,还与它的有线格式耦合。如果 Google 想要更改有线格式,它将破坏生产者或消费者尚未升级的所有部署。
  • 如果你使用例如GCC's GNU Compiler Extensions然后你加上GCC。如果您想(或必须)使用另一个编译器,您最好希望它们也恰好实现相同的扩展。
  • 每个程序都与它的编程语言耦合。例如,如果 Oracle 想要更改 Java 以使函数重载是不可能的,例如由于某些 100 年才出现一次的致命设计错误,所有 Java 程序都将停止编译。
  • 如果你编写一个 POSIX 程序,你依赖于 POSIX 的实现。如果您的 POSIX 程序使用 POSIX basename(3) , 但是你的实现 breaks its semantics , 那么你的程序在这个实现上不起作用(GNU 引入了一个兼容性宏来避免这种情况)。
  • 关于oop - 耦合 - 除了更改方法签名或返回类型之外,更改一个模块如何影响另一个模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58820466/

    相关文章:

    java - "Passing arguments"通过 ThreadLocal 好吗?

    javascript - Javascript 中的静态变量只设置一次

    c# - 我的 DAL 应该返回 Person 还是 Datatable?

    oop - 同时拥有抽象类和接口(interface)有什么好处吗?

    java - 什么是基于接口(interface)的框架?

    c++ - 不要在类内部使用类成员函数

    c# - 如果你想确保所有的方法和属性都被实现,你用什么

    networking - Sidecar与Ambassador和Adapter模式的区别

    c# - 在客户端和服务器端实现接口(interface)

    c# - 如何在 C# 的集合中保存不同类型的对象?