关于架构:什么是自以为是的软件?

What is opinionated software?

我经常看到人们说某些软件"非常固执己见",或者微软倾向于写"非固执己见"的框架。这实际上意味着什么?


如果一个框架是固执己见的,它会锁定或引导你进入他们做事的方式。

例如:有些人认为模板系统不应该提供对用户定义的方法和函数的访问,因为这样会使系统打开返回原始HTML的大门。因此,一个固执己见的框架开发人员只允许访问数据结构。通过设计,软件限制并鼓励设计师按照他们的方式做事。

另一个例子(取自信号链接)是wiki。维基的设计者有很多意见。他们认为HTML对于人们来说太复杂了,所以他们想出了一个更自然的更新内容的方法。他们还把它从花哨的设计中剥离出来,因为他们觉得重点应该更多地放在内容上而不是设计上。

苹果在设计产品时有很强的见解。

非独立的软件设计更像Perl/PHP。它允许开发人员和信任开发人员做出正确的决策,并将更多的控制权交给他们。

我也会把微软放在非固执己见的专栏里。微软框架的一个好例子是:.NET。通过打开clr和specs,它向各种语言和实现风格打开了它。


固执己见的软件意味着基本上有一种方法(正确的方式™)来做事情,并尝试以不同的方式来做,这将是困难和令人沮丧的。另一方面,以正确的方式进行工作™可以使软件开发变得非常容易,因为您必须做出的决策数量减少,并且软件设计者集中精力使软件工作的能力增加。如果你的问题能很好地映射到解决方案上,那么固执己见的软件可以很好地使用。解决问题中那些没有映射到所提供工具的部分可能是一种真正的痛苦。这里的一个例子是RubyonRails。

另一方面,非固执己见的软件给用户(开发人员)留下了很大的灵活性。它并没有禁止一种解决问题的方法,但提供了灵活的工具,可用于以多种方式解决问题。这样做的缺点是,由于工具非常灵活,因此开发任何解决方案都可能相对困难。更多的解决方案可能需要由用户(开发人员)手工编码,因为框架没有提供足够的帮助。你还必须更多地考虑如何提供解决方案,而那些平庸的开发人员最终可能会得到比他们购买一些固执己见的软件更差的解决方案。Perl可能是非固定化软件的经典例子。

我的理想是一个非固执己见的框架,但有着强烈的惯例。我将把ASP.NET MVC放在这个类别中。实际上,所有软件在某种程度上都是固定的(尽管可能不是Perl)。MVC在选择模型时有很强的约定,但提供了许多不同的方法来解决这些约定中的问题。其中一些方法甚至可能破坏模型。然而,按照在这样一个框架中制定的惯例正确使用是一种真正的乐趣。


基本上,软件是按照作者认为的方式工作的,而不是试图取悦每个人。这意味着很多人不会喜欢它,但是那些喜欢它的人会喜欢它。

Rails可能是一个固执己见的框架的典型例子:你按他们的方式做事,一切都很顺利。如果你不这样做,你会很痛苦的。但这没关系——如果你不想按他们的方式做事,你就不想使用Rails。


为了平衡起见,我将提供一个(相当固执己见的)描述,它对固执己见的方法更有利(与其他一些答案相反)。

固执己见的框架提供了一条"黄金之路",对于大多数人和大多数场景(在作者看来),这应该是最佳实践。

然而,这并不一定意味着锁定。这意味着它可能需要一些额外的努力来做不同的事情。

不那么固执己见的框架提供了许多不同的选择,由您决定。

固执己见的框架通常可以从开发人员身上卸下重生方向盘的负担,或者一次又一次地重新思考同一个问题,从而有助于集中精力解决手头的实际问题。

在开源世界中,您可以找到许多固执己见但相互竞争的框架,因此您仍然有选择。你只需要选择你自己的黄金之路。


DR:

  • 固执己见:例如Ruby on Rails。有一种特别喜欢的方式来做事情,你会得到很多支持。做其他事情是很困难的,或者对于某些系统来说是不可能的(卡桑德拉想到了)。
  • 不固定:例如Perl 5。你可以做任何你喜欢的事,任何你喜欢的方式,任何风格。所有样式都是同样开放、有效和受支持的。

固执己见的软件是以这样一种方式构建和设计的:它使以某种方式做事情变得容易。它更倾向于某些设计模式。在这个过程中,很难偏离软件开发的风格。另一种说法是,它倾向于"约定胜过配置"。也就是说,由于软件采用了许多配置方面,因此配置选项非常有限。一旦理解了这些假设,固执己见的软件通常能够更快地掌握。

另一方面,非软件化的软件很少有假设。因此,非软件化的软件/软件开发框架往往具有许多配置选项。开发人员通常必须对软件的各个方面做出许多决定。通常,会开发各种工具,以便更容易地处理这些巨大的选项。例如VisualStudio.NET for .NET,Eclipse IDE,Java等。固执己见的软件通常需要比固执己见的软件更长的时间来掌握。


很多人将ASP.NET MVC作为一个"非本地化"的框架来引用,我只是想谈谈这个问题。

确实,ASP.NET MVC并不要求太多;您可以使用任何您喜欢的持久性解决方案,无论是LINQ to SQL、ADO.NET实体、NHibernate等。

另一方面,MVC框架倾向于"约定胜过配置",引用PhilHaack的话,他强烈建议遵循预先定义的模式来定位控制器、视图、模型和其他代码。虽然你可以改变这种行为,但随波逐流更容易,对大多数人来说,这样做没有问题。

同样围绕着ASP.NET MVC的还有很多固执己见的人,我发现这会导致很多偏颇的教程,它们坚持覆盖,例如单元测试和依赖注入;我完全赞成良好的测试和分离关注点,但我确实感觉到这些主题会在覆盖更有用的基础之前稍微被压下一点。反恐精英。

在这里,我必须承认,在这些领域中,框架本身完全可以采用您想要的任何单元测试解决方案,以及您想要使用的任何依赖注入和模拟框架,因此我想这提供了另一个灵活性的例子,甚至在单元测试的"圣经抨击"中,等等。似乎还在继续。


它是一个框架中实现的约定的数量和已经做出的决定的数量。

例如,如果有5种(或更多)不同的方式将表单数据提交给控制器操作(在ASP.NET MVC中就是这样),则框架看起来相当"不固执己见"——这取决于您的决定!

但是,如果框架只允许(通过直接禁用其他方式,或通过强烈鼓励)一种方式执行该操作(Fubu MVC就是这样),那么您可以说框架已经做出了决定,从而使框架具有了自己的观点。


您现在将看到的例子是ASP.NET MVC框架。它具有惊人的可扩展性,但这在某些方面是它的崩溃,它没有肉。要进行数据访问吗?你得自己写。想要Ajax吗?同上。

然而,由于它具有高度的可扩展性,如果您在它之上构建,那么您可以将它转换为一个固执己见的框架。这就是类似mvcontrib的做法,它们为您提供了具体的操作方法,这意味着您需要编写更少的代码。

这确实意味着,如果你想打破这种观点,通常要做的工作要比你正在做的普通版本多。不过,这是一个80/20的场景。如果你正确地选择了自己的观点框架,你将只想在20%的时间里摆脱这些观点,而在其他80%的时间里,你将有很高的效率。