问题标签 [design-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 投票
4 回答
1891 浏览

asp.net - SOLID 原则或无 SOLID

我正在继续开发 ASP.NET 应用程序(基于 Web 表单),其中以前的开发人员没有遵循良好的面向对象设计原则,即 SOLID(http://www.remondo.net/solid-principles-csharp-interface-隔离/)。我读过这样的帖子:长期持有的、不正确的编程假设

问题是很多类的内聚性低并且耦合度很高,而且很多类没有单一的职责(它们有很多)。我的具体问题是:我应该开始遵循 SOLID 原则,还是继续通过 tweeking 开发并在课程中添加更多内容?过去我一直尝试遵循 SOLID 之类的原则,但我所说的应用程序非常庞大和复杂。我是唯一从事这个项目的开发人员。

目前完全重写是不可能的,但有朝一日是可能的。

更新 15/07/2012 到目前为止,我发现 SOLID 是一种设计原则,而 GRASP 是一种设计模式,这可能更适合 MVC 而不是页面控制器类型的应用程序。根据此链接,模拟对象也可能更适合 MVC:http ://www.asp.net/mvc/tutorials/older-versions/overview/asp-net-mvc-overview 。根据迄今为止的响应,遵循 SOLID 原则始终是一种很好的做法。然而,到目前为止的答案并不推荐基于表单的应用程序的设计模式。

0 投票
6 回答
2267 浏览

c# - 一个非常常见的 C# 模式,它打破了一个非常基本的 OOP 原则

这是一个非常简单的问题,我仍然很不安:

为什么现在广泛接受一个类通过访问器方法返回对其私有成员的引用?这不是完全破坏了封装原则吗?如果可以,那为什么不把会员公开!?

编辑我正在考虑的情况是这样的

现在 ev 的状态通过传递性发生了变化,因为它的成员 abuseMe 的状态发生了变化。

在 DDD 的上下文中,如果对象是聚合根,这是不行的。我引用

只允许外部对象保存对根的引用。对内部成员的瞬态引用只能在单个操作中使用。因为根控制着访问,所以它不会被内部结构的改变弄得措手不及。

[领域驱动设计,埃里克·埃文斯]

... 二传手 schmetters ...

0 投票
2 回答
55 浏览

oop - 在值空间中允许多个“无值”值

我在我的所有域中使用字符串类型作为我的 Id 属性。例如:

这里没有技巧。null代表一个“无价值”的值,当一个新的 Person 被创建并且在它被持久化之前,Id将保持null

现在有一个讨论来增强“无值”空间并说null,空字符串和空白字符串都是“无值”值。

即检查实体是否是新的而不是做:if (person.Id == null)它将成为if (string.IsNullOrWhiteSpace(person.Id))

在我看来,这是一种气味或违反设计原则的行为,但我不知道是哪一种。

问题:这个决定违反了哪个(如果有的话)设计原则(决定允许不仅仅是null代表无价值的价值)?

(我认为它应该类似于奥卡姆剃刀原理或熵或 KISS,我只是不确定)

0 投票
2 回答
154 浏览

asp.net-mvc - MVC:重置密码属于服务层或实际实体

我对 MVC 比较陌生,并且刚刚遇到了一些预先存在的代码。

我们有一个 UserService,它主要包含 CRUD 操作,也许还有一两个业务逻辑操作——所有这些都是我们的控制器所需要的。它封装了上下文和成员资格。

我正要实现 ResetPassword 操作,但不知道在哪里实现;是在 UserService 还是在 User Entity 实现它。


用户服务

这将导致我的控制器成为:

对比

用户

这将导致我的控制器成为:

推荐哪种方法?

0 投票
1 回答
204 浏览

oop - 设计模式建议:图形 -> 计算

我有一个域模型,保存在一个数据库中,它代表一个图。图由通过分支连接的节点(例如 NodeTypeA、NodeTypeB)组成。两个通用元素(节点和分支将具有属性)。图将被发送到计算引擎。要执行计算,必须像这样初始化引擎(简化伪代码):

最后计算如下:

我只是想知道,是否有任何相关的设计模式,这有助于使用良好的设计原则实现上述目标。我希望这是有道理的。任何反馈将不胜感激。

0 投票
2 回答
449 浏览

design-patterns - Liskov 替换原则是否也适用于实现接口的类?

LSP 声明类应该可以替代它们的基类,这意味着派生类和基类在语义上应该是等价的。

但是 LSP 是否也适用于实现接口的类?换句话说,如果一个类实现的接口方法在语义上与用户期望的不同,这是否会被视为违反 LSP?

谢谢

0 投票
1 回答
700 浏览

rest - 一个restful api的设计理念和最佳实践

我有幸重新设计我们的主要项目公共 api。最初的目标是制作一个宁静的 api,[在添加了许多额外的功能之后] 最终成为了 rest/json-rpc 不匹配。

所以,是时候重新思考和重新设计了。但是我需要一些关于如何解决一些更复杂操作的想法。

基本的CURD操作已经实现并且工作正常。

每个资源都由分层 slug 访问:

还添加了语言环境和输出格式:

好的,现在到棘手的部分:

项目中的基本资源类似于具有标题和子节点的文件夹。“文件夹”可以有子文件夹和项目。

将新文件夹或项目添加到文件夹的最佳做法是什么?

需要 PUT/PATCH 来更新有关文件夹的信息,而不是将资源链接到它?需要 POST 来创建新文件夹。

再补充一点,区分文件夹到文件夹和项目到文件夹链接操作的最佳做​​法是什么。请记住,链接可以并且将有另一个名称,然后是目标。类似于 POSIX 系统中的符号链接。

我的想法是(对现有资源):

反过来呢?取消链接?

但这是一个好的设计还是稍后会回到我身边?

0 投票
1 回答
943 浏览

c# - “加载格式保存数据”的设计模式

我需要完成一些事情,比如从 xls 源(ole db)加载数据,根据输出文件的规范对其进行格式化,合并已处理的字段,然后将其保存到 csv。

如何处理必须属于某种类型的多个数据字段?以某种方式格式化 - 等等。

我很难为这个问题抽象类结构。

哪种设计模式最适合我?

0 投票
0 回答
340 浏览

content-management-system - 更好的内容管理系统的设计原则

可能问题对你来说太简单了。但很多时候我觉得这很复杂。每个人都会以自定义 cms 开始他们的网站,然后转移到 Wordpress、Drupal、Joomla 或类似的东西。

我曾经寻找更好的书籍或博客文章,其中包含为 cms 做出的设计决策,以使其可以扩展。一些我觉得很有趣的书是

  1. PHP 5 CMS 框架开发
  2. Pro Zend 框架 CMS

很高兴看到您是否遇到过此类书籍,或者您是否推荐过任何其他书籍。我不只是在寻找 PHP,而且我有兴趣阅读任何类型的书籍,这将帮助我建立下一个博主。

让我感兴趣的事情是

  1. 博主
  2. 德鲁帕花园
  3. 棒棒哒

和类似的东西。

谢谢

0 投票
3 回答
1323 浏览

c# - 哪些做法可以防止使用 IEnumerable 的意外延迟执行作为论据?

有一些与此类似的问题涉及正确的输入和输出类型。我的问题是什么好的做法、方法命名、选择参数类型或类似的东西可以防止延迟执行事故?

这些是最普遍的,IEnumerable这是一种非常常见的参数类型,因为:

  • 遵循稳健性原则 “在你所做的事情上保守,在你接受别人的事情上自由”

  • 广泛用于Linq

  • IEnumerable在集合层次结构中处于较高位置并且早于较新的集合类型

但是,它也引入了延迟执行。现在我们可能在设计方法(尤其是扩展方法)时出错了,因为我们认为最好的想法是采用最基本的类型。所以我们的方法看起来像:

危险显然是当我们将上述函数与惰性混合在一起时Linq,它非常容易受到影响。

更大的编辑:

重新打开这个:对语言功能的批评没有建设性 - 但是要求良好的实践是 StackOverflow 的亮点。更新了问题以反映这一点。

这里有一个很大的编辑:

澄清上述行 - 我的问题不是关于第二个表达式没有得到评估,严重的是没有。程序员都知道。我担心的是Shuffle到目前为止实际执行查询的方法。查看第一个查询,没有执行任何操作。现在类似地,在构造另一个 Linq 表达式(应该稍后执行)时,我们的自定义函数正在玩破坏游戏。换句话说,如何让调用者知道Shuffle并不是他们在 Linq 表达式的那个点想要的那种功能。我希望重点是回家。道歉!:)虽然它就像检查方法一样简单,但我在问你们通常如何进行防御性编程..

上面的例子可能没有那么危险,但你明白了。那是某些(自定义)函数不适合Linq延迟执行的想法。问题不仅与性能有关,还与意想不到的副作用有关。

但是像这样的函数可以通过以下方式发挥作用Linq

如您所见,这两个函数都 take IEnumerable<>,但调用者不知道这些函数是如何反应的。那么你们在这里采取的一般警告措施是什么?

  1. 适当地命名我们的自定义方法,以便它为调用者提供一个好兆头或不好的想法Linq

  2. 惰性方法移动到不同的名称空间,并将Linq-ish 保留到另一个名称空间,以便它至少给出某种想法?

  3. 不接受IEnumerableas 参数来immediately执行方法,而是采用更派生的类型或具体类型本身,从而IEnumerable单独留给惰性方法?这给调用者增加了执行可能未执行的表达式的负担?这对我们来说是很有可能的,因为外部Linq世界我们几乎不处理IEnumerables,而且大多数基本的集合类ICollection都至少实现了。

还是别的什么?我特别喜欢第三个选项,这就是我想要的,但我想在此之前得到你的想法。即使是优秀的程序员,我也看到了很多代码(有点像扩展方法!) ,他们在方法Linq中接受IEnumerable并对其执行或类似的操作。ToList()我不知道他们如何应对副作用。

编辑:在投反对票和回答之后,我想澄清一下,这不是程序员不知道 Linq 是如何工作的(我们的熟练程度可能在某种程度上,但那是另一回事),而是很多函数都是写的那时linq算进去了。现在将立即执行的方法与 Linq 扩展方法链接起来很危险。所以我的问题是,程序员是否遵循一般准则,让调用者知道从 Linq 端使用什么,不使用什么?它更多的是关于防御性编程,而不是如果你不知道使用它,那么我们就无能为力!(或者至少我相信)..