鲍勃叔叔的“坚实的关联性”

2020-10-20 00:27:39

多年来,对坚实原则的了解一直是我们招聘程序的标准部分。应聘者被要求对这些原则有很好的工作知识。然而,最近我们的一位经理不再编写太多代码,他质疑这样做是否明智。他的观点是,开放-封闭原则不再非常重要,因为我们编写的大多数代码都不是包含在大型整体中,对小型微服务进行更改既安全又容易。利斯科夫替代原则早已过时,因为我们不再像20年前那样关注继承。我认为我们应该考虑Dan North对Solid的立场--“只需编写简单的代码。”

这些坚实的原则与90年代(甚至在此之前)一样,在今天仍然具有现实意义。这是因为软件在所有这些年里没有改变太多--这是因为自从1945年图灵为电子计算机编写了第一行代码以来,软件就没有改变太多。软件仍然是IF语句、WHILE循环和赋值语句-序列、选择和迭代。

每一代新一代都喜欢认为他们的世界与上一代有很大的不同。每一代人在这一点上都是错误的;这是每一代人在下一代到来时都会学到的东西,告诉他们一切都发生了多么大的变化。<;咧嘴笑>;

把因为同样的原因而改变的东西聚集在一起。将因不同原因而改变的事情分开。

很难想象这一原则与软件无关。我们不会将业务规则与GUI代码混为一谈。我们不会将SQL查询与通信协议混为一谈。我们将因不同原因更改的代码分开,以便对一个部分的更改不会破坏其他部分。我们确保由于不同原因更改的模块不会有使它们纠缠在一起的依赖项。

微服务不能解决这个问题。您可以创建一个错综复杂的微服务,或者如果您混合了因不同原因而更改的代码,则可以创建一组错综复杂的微服务。

丹·诺斯的幻灯片完全没有抓住这一点,让我相信他根本不理解这个原理。他对SRP的回答是“编写简单的代码”(或者说他是在讽刺,这一点我了解丹的可能性要大得多)。我同意。SRP是我们保持代码简单的方法之一。

在所有的原则中,任何人都会质疑这一原则的想法让我对我们行业的未来充满了恐惧。当然,我们希望创建无需修改即可扩展的模块。您能想象在一个没有设备独立性的系统中工作吗?在这个系统中,写入磁盘文件与写入打印机、屏幕或管道有着根本的不同。我们是否希望看到语句是否散布在代码中以处理所有的小细节?

或…。我们想把抽象概念和详细概念分开吗?我们是否希望将业务规则与GUI、微服务通信协议和数据库的任意行为隔离开来?我们当然知道!

再说一次,丹的幻灯片完全搞错了。当需求改变时,只有部分现有代码是错误的。现有的大部分代码仍然是正确的。我们希望确保我们不必仅仅为了让错误的代码再次工作而更改正确的代码。丹的回答是“编写简单的代码”。再说一次,我同意。而且,具有讽刺意味的是,他是对的。简单的代码既是开放的,也是封闭的。

使用接口的程序不能被该接口的实现所混淆。

人们(包括我)犯了一个错误,认为这是关于继承的。但事实并非如此。它是关于子类型的。接口的所有实现都是接口的子类型。所有的鸭子类型都是隐含接口的子类型。而且,基接口的每个用户,无论是声明的还是隐含的,都必须就该接口的含义达成一致。如果实现使基类型的用户感到困惑,则IF/Switch语句将激增。

这个原则是关于保持抽象的清晰和定义良好。不可能相信这是一个过时的概念。

丹在这个主题上的幻灯片是完全正确的;他只是没有抓住原则的要点。简单代码是维护清晰的子类型关系的代码。

保持界面小,这样用户就不会最终依赖于他们不需要的东西。

我们仍然使用编译语言。我们仍然依赖修改日期来确定哪些模块应该重新编译和重新部署。只要这是真的,我们就必须面对这样一个问题:当模块A在编译时而不是在运行时依赖于模块B时,对模块B的更改将强制重新编译和重新部署模块A。

这个问题在静态类型的语言(如Java、C#、C++、GO、SWIFT等)中尤其严重。动态类型的语言受到的影响要小得多,但仍然不能幸免。Maven和Leiningen的存在就是证明。

丹关于这个话题的幻灯片可以证明是错误的。如果客户端在修改其中一个方法时必须重新编译和重新部署,那么它们确实依赖于它们没有调用的方法。就目前而言,丹关于这一原则的最后一点是正确的。是的,如果您可以将具有两个接口的类分割为两个单独的类,则最好这样做(SRP)。但这样的分离往往是不可行的,甚至是不可取的。

依赖于抽象的方向。高级模块不应依赖于低级详细信息。

很难想象没有大量使用这一原则的体系结构。我们不希望我们的高级业务规则依赖于低级细节。我希望这是非常明显的。我们不希望为我们赚钱的计算受到SQL、低级验证或格式化问题的污染。我们希望将高级抽象与低级细节隔离开来。这种分离是通过仔细管理系统内的依赖项来实现的,以便所有源代码依赖项,特别是那些跨越体系结构边界的源代码依赖项,都指向高级抽象,而不是低级细节。

在每种情况下,Dan的幻灯片都以:只要编写简单的代码就可以了。这是个好建议。然而,如果说岁月教会了我们什么的话,那就是简单性需要原则指导下的纪律。正是这些原则定义了简单性。正是这些规则约束了程序员生成倾向于简单性的代码。

把事情搞得一团糟的最好办法就是告诉每个人“简单一点”,不要给他们进一步的指导。