问题标签 [solid-principles]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
322 浏览

oop - 在尝试遵循 SOLID 原则时,我的班级设计有多精细?

我有一个名为 IRegistrationService 的客户端注册接口。这包含一个名为 Register 的方法,它通过类 RegistrationService 实现。例如,如果我想拥有 Delete、Update、Retrieve 的方法,我是否会为每个操作(例如 IDeletionService、IUpdateService、IRetrieveService)创建一个单独的接口,或者只是将所有方法放入 IRegistrationService。我问这个的原因是因为这是 SOLID 原则,尤其是 SRP 原则似乎要问的问题。

0 投票
10 回答
14503 浏览

oop - SOLID 与 YAGNI

我听到的关于在面向对象设计中不遵守SOLID原则的最常见论点之一是YAGNI(尽管争论者通常不这么称呼它):

“我可以将特征 X 和特征 Y 放在同一个类中。这很简单,为什么要麻烦添加一个新类(即复杂性)。”

“是的,我可以将我所有的业务逻辑直接放入 GUI 代码中,这样更容易、更快捷。这将永远是唯一的 GUI,而且不太可能出现重大的新需求。”

“如果在不太可能出现新需求的情况下,我的代码变得过于混乱,我仍然可以针对新需求进行重构。所以你的‘如果你以后需要……怎么办’的论点不重要。”

反对这种做法的最有说服力的论点是什么?我如何才能真正证明这是一种昂贵的做法,尤其是对于那些在软件开发方面没有太多经验的人。

0 投票
4 回答
636 浏览

c# - 使用“单一职责原则”强制我的容器有公共设置器

我正在努力按照 SOLID 原则进行设计。我发现,当您使用“单一责任原则”(SOLID 的 S)时,您通常必须在数据容器和数据处理器之间拆分类。例如,如果我有一个从 DB 读取的具有 5 个属性的类 person,而不是将所有内容都放在一个类中,我将创建一个带有属性的 Person 类和另一个从数据库读取该信息并创建 Person 的 PersonReader 类。

如果我这样做,我必须打开 Person 属性,以便 PersonReader 可以访问它们,但是与将所有内容放在黑盒中并使属性仅可读相比,我的封装更少。

我是否遗漏了什么,或者这是这个原则的一个缺点?

提前致谢

编辑:我已将人员编写器更改为人员阅读器,因为一开始不需要公开属性设置器。

0 投票
3 回答
61282 浏览

c# - 你能用一个好的 C# 例子来解释 Liskov 替换原则吗?

你能用一个很好的 C# 例子来解释 Liskov 替换原则(SOLID 的“L”)吗?如果真的可以。

0 投票
1 回答
98 浏览

c# - SOLID的依赖倒置原则中提到的“细节”这个词应该怎么定义?

来自维基百科:

该原则指出:

我能理解A。

但是我在(B)中为“详细信息”编写定义时遇到了问题。

如何定义术语定义?它究竟代表什么?

谢谢!

0 投票
2 回答
99 浏览

language-agnostic - 编程语言:开箱即用的易读性和可扩展性

SOLID 开发理念的两个出色结果是
- 易读
性 - 项目生命周期内的可扩展性
(http://en.m.wikipedia.org/wiki/Solid_(object-orientated_design)

尽管 SOLID 是一组与语言无关的设计思想,但某些语言天生就比其他语言更好地支持这些思想。开箱即用或经过各种自定义后,您认为哪种语言最适合既易于阅读又易于扩展功能?

先发制人的偏见和激战的一些定义:

  • 易读性:理解代码的思考量与代码量成正比:(amount_think-energy / amount_code) 相当恒定,并且在最佳情况下尽可能低。
  • 可扩展性:添加 X 数量的功能需要更改代码或与 X 成比例的代码添加(amount_added_functionality / amount_added_code)是相当恒定的,并且在最佳情况下尽可能高。

鼓励提供支持信息和教程。欢迎使用代码片段。

0 投票
2 回答
404 浏览

.net - 我是否正确理解 DI/IoC?

我目前正在尝试了解使用 IoC 容器的好处并熟悉 DI。我已经开始使用 StructureMap,因为它看起来相当简单但功能强大。

我想验证我对这些概念的理解是否正确。让我们假设应用程序中有以下基本类(为简洁起见省略了细节):

首先,依赖倒置原则指出,由于 OrderService 是一个“高级”模块,它不应该依赖于任何较低级别的实现细节,它应该只引用这些类并能够要求它们做他们的事情而不必知道在做什么,消费代码应该负责创建这些预配置的模块并将其交给它。是对的吗?因此,DI 使这些类保持松散耦合,因此它们不必知道调用该依赖项的方法的确切方式,只需知道它被调用并做它需要做的任何事情——OrderService 不关心存储库是否正在查询 XML,或者使用 NHibernate 或 EF 甚至原始数据集;它只知道它可以调用存储库,告诉它找到一个 ID 为 42 的订单,存储库就会知道该做什么。

我的理解也是,一个 IoC 容器,在这种情况下是 StructureMap,它提供了一个好处,它不会强迫我们确保我们手动创建所有这些依赖项并将它们传递进来。例如,一个普通应用程序的 Main 方法使用上面的代码可能有:

加上所有的新闻来设置它,这真是令人作呕;即使我创建了变量,它仍然很丑。使用 IoC 容器让我避免了所有这些,在 StructureMap 的情况下,它会变成:

这更清洁,更易于维护,如果我正在编写单元测试,我只需将具体类替换为 Mock 即可。简而言之,它的好处是它把所有东西都解耦到我什至不需要关心的地方(在调用代码中,即)一个特定的类依赖什么,我可以使用容器创建一个并让它做确保消费代码只知道它需要什么——例如,在一个真实的应用程序中,如果控制器正在调用服务,它不需要知道存储库、计算器或规范,它只需要知道使用OrderService 对订单做一些事情。

这个理解正确吗?在那张纸条上,有几件事我还不确定:

  1. 如果您决定使用 IoC 容器,它是否意味着在应用程序中的任何地方都可以使用,仅在您需要解决许多反向依赖项的地方,还是仅在消费者中使用?例如,在 OrderRepository 中,如果我使用具体的实现并新建一个 Order;此类是否也会使用 StructureMap 来获取订单?这可能是一个有点傻的问题,但我看到的所有 DI/IoC 示例都只关注在消费客户端(例如网页)中使用它,而从未涉及在其他地方使用它。这似乎是一种全有或全无的方法:如果您要使用 IoC 容器,那么它会在任何地方使用;new SomeObject();在这种情况下,您实际上是将任何调用替换为ObjectFactory.GetInstance<ISomeObject>();

  2. 无论是否需要使用 DI/IoC 或类似模拟它的东西,让每个类(当然,在可能的情况下)都从接口派生是好还是坏?我见过许多代码示例,其中每个不是内置类的类背后都有一个接口,虽然我可以看到这样做的好处和可能的未来证明,但我认为遵循 TDD 或 BDD 可能是一个使用这些方法的因素通常会告诉您是否需要类的接口,但是我见过并与许多人交谈过,无论是否使用 TDD,都认为您永远不应该将对象的类型定义为具体的类;它应该总是是作为底层类型的接口或抽象类。这似乎是“不必要的复杂性”代码气味的一个案例,更不用说违反 YAGNI 了。

0 投票
1 回答
406 浏览

design-patterns - SOLID 原则 - 澄清

可能的重复:
开放/封闭原则

我可以理解打开/关闭原则表明

这里的开和关是什么意思?

0 投票
5 回答
17565 浏览

javascript - 根据 SOLID 编写 JavaScript

有没有人在开发 JavaScript 时使用过 SOLID 编程原理(或其任何部分)?

我刚刚开始阅读它,但似乎找不到任何人将它用于 JS。我发现易于实施/使用的唯一部分是“单一责任原则”。

我正在寻找的是使用这些原则的文章或示例。是否有任何争论为什么不应该使用某些部分?

例如,“接口隔离原则”表示“许多客户端特定接口优于一个通用接口的概念”。

但是据我所知,JS 中没有接口之类的东西(如果可以的话,那就太好了)。

0 投票
3 回答
71 浏览

oop - OO 设计:将数据从 A 类复制到 B

牢记 SOLID 原则和可测试性,考虑以下情况:

您有 A 类和 B 类,它们具有一些重叠的属性。您想要一个方法,将公共属性从 A 类复制和/或转换到 B 类。该方法在哪里?

  1. A 类作为 B GetAsB() ?
  2. B类作为构造函数B(A输入)?
  3. B 类作为方法 void FillWithDataFrom(A input)?
  4. C类作为静态方法B ConvertAtoB(A source)?
  5. ???