《架构整洁之道》:Chap11. DIP: THE DEPENDENCY INVERSION PRINCIPLE DIP:依赖反转原则

The Dependency Inversion Principle (DIP) tells us that the most flexible systems are those in which source code dependencies refer only to abstractions, not to concretions. 依赖反转原则(DIP)主要想告诉我们的是,如果想要设计一个灵活的系统,在源代码层次的依赖关系中就应该多引用抽象类型,而用具体实现。 In a statically typed language, like Java, this means that the use, import, and include statements should refer only to source modules containing interfaces, abstract classes, or some other kind of abstract declaration. Nothing concrete should be depended on. 也就是说,在 Java 这类静态类型的编程语言中,在使用 use、import、include 这些语句时应该只引用那些包含接口、抽象类或者其他抽象类型声明的源文件,不应该引用任何具体实现。 ...

March 14, 2024

《架构整洁之道》:Chap10. ISP: THE INTERFACE SEGREGATION PRINCIPLE ISP:接口隔离原则

The Interface Segregation Principle (ISP) derives its name from the diagram shown in Figure 10.1. “接口隔离原则(ISP)”这个名字来自图 10.1 所示的这种软件结构。 The Interface Segregation Principle In the situation illustrated in Figure 10.1, there are several users who use the operations of the OPS class. Let’s assume that User1 uses only op1, User2 uses only op2, and User3 uses only op3. 在图 10.1 所描绘的应用中,有多个用户需要操作 OPS 类。现在,我们假设这里的 User1 只需要使用 op1,User2 只需要使用 op2,User3 只需要使用 op3。 Now imagine that OPS is a class written in a language like Java. Clearly, in that case, the source code of User1 will inadvertently depend on op2 and op3, even though it doesn’t call them. This dependence means that a change to the source code of op2 in OPS will force User1 to be recompiled and redeployed, even though nothing that it cared about has actually changed. ...

March 13, 2024

《架构整洁之道》:Chap9. LSP: THE LISKOV SUBSTITUTION PRINCIPLE LSP:里氏替换原则

In 1988, Barbara Liskov wrote the following as a way of defining subtypes. 1988 年,Barbara Liskov 在描述如何定义子类型时写下了这样一段话: What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.1 ...

March 12, 2024

《架构整洁之道》:Chap8. OCP: THE OPEN-CLOSED PRINCIPLE OCP:开闭原则

The Open-Closed Principle (OCP) was coined in 1988 by Bertrand Meyer.1 It says: 开闭原则(OCP)是 Bertrand Meyer 在 1988 年提出的,该设计原则认为: A software artifact should be open for extension but closed for modification. 设计良好的计算机软件应该易于扩展,同时抗拒修改。 In other words, the behavior of a software artifact ought to be extendible, without having to modify that artifact. 换句话说,一个设计良好的计算机系统应该在不需要修改的前提下就可以轻易被扩展。 This, of course, is the most fundamental reason that we study software architecture. Clearly, if simple extensions to the requirements force massive changes to the software, then the architects of that software system have engaged in a spectacular failure. ...

March 11, 2024

《架构整洁之道》:Chap7. SRP: THE SINGLE RESPONSIBILITY PRINCIPLE SRP:单一职责原则

Of all the SOLID principles, the Single Responsibility Principle (SRP) might be the least well understood. That’s likely because it has a particularly inappropriate name. It is too easy for programmers to hear the name and then assume that it means that every module should do just one thing. SRP 是 SOLID 五大设计原则中最容易被误解的一个。也许是名字的原因,很多程序员根据 SRP 这个名字想当然地认为这个原则就是指:每个模块都应该只做一件事。 Make no mistake, there is a principle like that. A function should do one, and only one, thing. We use that principle when we are refactoring large functions into smaller functions; we use it at the lowest levels. But it is not one of the SOLID principles—it is not the SRP. ...

March 10, 2024

《架构整洁之道》:Part3. DESIGN PRINCIPLES 设计原则

Good software systems begin with clean code. On the one hand, if the bricks aren’t well made, the architecture of the building doesn’t matter much. On the other hand, you can make a substantial mess with well-made bricks. This is where the SOLID principles come in. 通常来说,要想构建一个好的软件系统,应该从写整洁的代码开始做起。毕竟,如果建筑所使用的砖头质量不佳,那么架构所能起到的作用也会很有限。反之亦然,如果建筑的架构设计不佳,那么其所用的砖头质量再好也没有用。这就是 SOLID 设计原则所要解决的问题。 The SOLID principles tell us how to arrange our functions and data structures into classes, and how those classes should be interconnected. The use of the word “class” does not imply that these principles are applicable only to object-oriented software. A class is simply a coupled grouping of functions and data. Every software system has such groupings, whether they are called classes or not. The SOLID principles apply to those groupings. ...

March 9, 2024

The Importance of SOLID Design Principles

Author: Stephen Watts SOLID is a popular set of design principles that are used in object-oriented software development. SOLID is an acronym that stands for five key design principles: single responsibility principle, open-closed principle, Liskov substitution principle, interface segregation principle, and dependency inversion principle. All five are commonly used by software engineers and provide some important benefits for developers. The SOLID principles were developed by Robert C. Martin in a 2000 essay, “Design Principles and Design Patterns,” although the acronym was coined later by Michael Feathers. In his essay, Martin acknowledged that successful software will change and develop. As it changes, it becomes increasingly complex. Without good design principles, Martin warns that software becomes rigid, fragile, immobile, and viscous. The SOLID principles were developed to combat these problematic design patterns. ...

April 19, 2023

里氏替换原则Liskov substitation principle

为什么叫里氏替换原则? 里氏替换原则在SOLID这五个设计原则中是比较特殊的存在:如果违反了里氏替换原则,不只是降低软件设计的优雅性,很可能会导致Bug。 里氏替换原则译自Liskov substitution principle。Liskov是一位计算机科学家,也就是Barbara Liskov,麻省理工学院教授,也是美国第一个计算机科学女博士,师从图灵奖得主John McCarthy教授,人工智能概念的提出者。 Robert Martin在《敏捷软件开发:原则、模式与实践》一书中对原论文的解读:子类型(subtype)必须能够替换掉他们的基类型(base type)。这个是更简明的一种表述。 违背 LSP 原则的一个简单示例 一个非常明显地违背 LSP原则的示例就是使用 RTTI(Run Time Type Identification)来根据对象类型选择函数执行。 void DrawShape(const Shape& s) { if (typeid(s) == typeid(Square)) DrawSquare(static_cast<Square&>(s)); else if (typeid(s) == typeid(Circle)) DrawCircle(static_cast<Circle&>(s)); } 正方形和长方形,违背原则的微妙之处 很多情况下对 LSP 原则的违背方式都十分微妙。设想在一个应用程序中使用了 Rectangle 类,描述如下: public class Rectangle { private double _width; private double _height; public void SetWidth(double w) { _width = w; } public void SetHeight(double w) { _height = w; } public double GetWidth() { return _width; } public double GetHeight() { return _height; } } 违反里氏替换原则的危害 当我们违反了这一原则会带来有一些危害:反直觉。期望所有子类行为是一致的,但如果不一致可能需要文档记录,或者在代码跑失败后涨此知识;不可读。如果子类行为不一致,可能需要不同的逻辑分支来适配不同的行为,徒增代码复杂度;不可用。可能出错的地方终将会出错。 ...

April 19, 2023

整理和总结我自己的软件架构知识体系

最近开始整理自己实际项目中用到的和可能用到的软件架构体系,我打算每种架构都好好写文章,并且根据自己的实际情况定制出相应的架构,我还希望把他编写成一个codesmith模板,可以实现自动化代码。前面7种是具体落地的软件架构,最后1种是架构设计思想。 1、极简数据库访问架构,这种架构非常适合编写一些小软件,里面只有一个SQLHelper文件,并且模仿三层架构,拥有DAL类和BLL类,最后加上一个程序入口Program。 2、简单三层架构,这种架构非常适合开发小型项目,web层就是MVC或者API,并且拥有BLL层和DAL层。 3、N层架构,这是一种适合大型项目的开发架构,但是更多是基于数据库构建的系统,没有基于DDD或者其他好的软件设计模式。 4、基于AutoFac、依赖注入和模板模式的多层架构。 5、基于ABP框架的架构,完全按照DDD设计模式开发,可能有些臃肿,但是非常适合大型软件和系统。 6、基于整洁架构的框架,完全按照DDD并且结合各种软件技术。 7、垂直切片架构,这是一种和传统分成架构完全不一样的架构,适合已经熟悉DDD和各种架构模式的成熟团队使用,并且适合开发微服务架构下的子系统。 8、基于清晰架构的微服务软件架构设计思想,这不是具体的实现,而只是一种架构大局观,用于指导大型的软件架构设计。

April 3, 2023

[转]垂直切片架构 - Jimmy Bogard

许多年前,我们开始了一个新的长期项目,首先,我们基于洋葱架构构建了它的架构。在几个月内,这种风格开始显示出裂缝,我们从这种架构转向CQRS。随着转向CQRS,我们开始围绕垂直切片而不是层(无论是平面还是同心,它仍然是层)构建我们的架构。从那以后,在过去7到8年左右的时间里,围绕垂直切片架构构建应用程序和系统的所有方式一直是我们独有的方法,我无法想象回到分层架构方法的限制。 传统的分层/洋葱/清洁架构在其目标是单体的: 这种架构方式问题是实际上只适用于系统中的少数典型请求。此外,我倾向于看到这些架构严重拟合,严格遵守依赖关系管理规则。在实践中,我发现这些规则很少有用,并且你开始得到很多关于真正不应该被抽象的抽象(控制器必须与必须使用存储库的服务进行对话)。 相反,我想对我的系统采用量身定制的方法,我将每个请求视为如何处理其代码的独特用例。因为我的系统整齐地分解为“命令”请求和“查询”请求(HTTP-land中的GET与POST / PUT / DELETE),所以向垂直切片架构的移动使我使用了CQRS。 什么是“垂直切片架构”?在这种风格中,我的架构是围绕不同的具体请求功能而构建的,通过这种方法,我们的每个垂直切片都可以自行决定如何最好地满足请求: (对于获取订单,直接使用ORM转换为DTO,对于订单细节使用原生SQL转换为DTO,对于发票,使用基于聚合根的事件溯源,取消订单使用存储过程,这是一种微服务风格) 在所谓正常的“n层”或六边形或任何架构中,通过垂直切片移除这些层障碍,并沿着变化轴聚合在一起: 在应用程序中添加或更改功能时,通常会在应用程序中涉及到许多不同的“层”。现在改为沿着切片垂直将这些功能聚合在一起。 最小化切片之间的耦合,并最大化切片内的聚合。 通过这种方法,大多数抽象都消失了,我们不需要任何类型的“共享”层抽象,如存储库,服务,控制器。有时我们仍需要这些工具,但我们将交叉切片逻辑共享保持在最低限度。 通过这种方法,我们的每个垂直切片都可以自行决定如何最好地满足请求。 “企业架构模式”一书中的旧域逻辑模式不再需要成为应用程序范围内的选择。相反,我们可以从简单的(事务脚本)开始,并简单地重构从我们在业务逻辑中看到的代码气味中出现的模式。新功能只添加代码,您不会更改共享代码并担心副作用。非常自由! 但是,这种方法有一些缺点,因为它确实假设您的团队了解代码气味和重构。如果您的团队不理解“服务”在将逻辑推送到领域时自己却做得太多相关业务逻辑事情,那么这种模式可能不适合您。(服务类似餐厅服务员,服务员不应该做决定,只是协调者,当然如果你想退菜,服务员会决定说:不能退,菜已经烧了。) 如果您的团队确实理解了重构,并且能够识别何时将复杂的逻辑推入域,进入DDD服务应该是什么,并且熟悉其他Fowler/Kerievsky重构技术,那么您会发现这种架构风格能够远远超过传统的分层/同心架构。 来源:https://www.jdon.com/53095.html

March 24, 2023