纯PHP体系结构。如何测量和控制它?

前言


正如您已经从名称中了解的那样,在这里,我将讨论最“高级”的纯建筑。整个故事发展的动力是罗伯特·马丁(Robert Martin)的《纯建筑》。如果我还没有读过,我敢推荐它!作者揭示了许多重要的话题,积极地分享了他丰富的生活经验(当然,是从专业领域获得的)以及根据其得出的结论,偶尔也将故事的章节编入了我们的父辈和祖父如何精明的sh头(当然,不仅是)早在60年代,70年代,80年代,甚至是破旧的90年代,就像谷物一样,人们就收集了每个人最喜欢的SOLID原理及其在零件世界中的类似物,并收集了他们在过去半个世纪中学到的知识。在阅读本书的过程中,可以很好地追踪软件开发行业的开发路线,这是男孩们必须应对的典型问题,及其解决方法。

不要以为,重述本书的摘要不是此帖子的目的。
接下来,我们将讨论促使我开发一种工具的想法(我将确定该工具对您的有用程度,并且将以极大的兴趣等待反馈,建议和建设性批评)。

在我看来,这篇文章将对所有人有用。那些已经熟悉这本书的人将能够刷新其记忆中的某些时刻,或者只是跳过第一部分就可以立即开始熟悉该工具。那些以前从未阅读过本书的人可能在第一部分中为自己找到了一些新东西。

为了方便起见,本文分为两部分。

在第一篇文章中,我将讨论在脑海中产生的使整件事自动化的愿望的关键思想,我们是程序员还是到底是谁?在这里,我会引用很多作者的文章,并积极插入本书不同章节的摘录和插图。

第二部分几乎全部用于描述已出现的工具,并揭示其功能和逐步指南。

如果您认为自己是将一切都贴在心上的人,我建议您从Afterword开始阅读



第1部分


什么是软件架构?


las,这本书的作者没有给出一个单一的定义。有很多不同的表述,并且所有的表述都是正确的。
但是,我们可以从另一端出发..

建筑的目的是什么?


只有一个答案:

软件体系结构的目标是减少创建和维护系统所需的人力。

一点介绍..

许多项目从哪里开始?


“我们稍后将能够恢复订单,我们只会进入市场!”
结果,由于市场竞争的压力永远不会消失,因此订单尚未恢复。

许多开发人员认为,最大的谎言是,肮脏的代码将帮助他们迅速进入市场,但实际上,从长远来看,这将减慢其发展速度。相信这一谎言的开发人员表现出了野兔的傲慢,他们相信将来他们将能够从制造混乱到恢复秩序,但他们犯了一个简单的错误。事实是,不管选择哪种时间尺度,混乱的产生总是比持续遵守清洁要慢。

软件产品的两个价值


  1. 行为(紧急但并非总是重要的事情)
  2. 体系结构(很重要,但并不总是紧迫的)

许多人常常被淹死在第一个之中,而完全忽略了第二个。

输入:“为什么要浪费时间仔细考虑架构,主要是它可以正常工作!”

但是他们错过了一个重要的观点:“如果正常运行的程序不允许更改它,那么当需求改变时它将停止正确运行,并且他们将无法使其正常运行。也就是说,该程序将变得无用。

如果程序无法正常运行,但是很容易更改,那么他们将能够使程序正确运行并随着需求的变化保持其性能。也就是说,该程序将始终保持有用。”

我喜欢这句话:“如果您认为好的架构很昂贵,请尝试劣质的架构。”(Brian Foote和Joseph Yoder)

事实证明,从一开始对代码的整洁性和体系结构给予应有的重视是很重要的。但是,如果代码的纯度一切都相对清晰(嗅出代码中的各种不良气味,并加以纠正,此外,这些工具中充满了智能IDE,静态分析器和其他毫无疑问的垃圾),那么就架构而言,事实并非如此(至少至少我)。

如何控制如此模糊不清的内容,以至于很难用一个单一的措辞来定​​义它,它具有非常广泛的想法,一秒钟,该死,该死,看到它并尝试以自己的方式解释它,如果您不是Vanga的孙子,就不会赢得“ Intuition “而且不是特别敏感的第五点吗?然后,这本书的作者提出了一些有价值的想法供您思考...让我们对其进行梳理。

您为什么要提出SOLID,为什么还不够?


我们可能都知道SOLID的原理。

他们的目标是创建中级软件结构,以:

  • 容忍变化
  • 简单易懂;
  • 构成可在许多软件系统中使用的组件的基础。

但是:“就像优质的砖砌成无法使用的墙一样,平均水平的精心设计的组件也可能创建无法使用的系统。”
因此,在组件世界中,存在SOLID原理的类似物以及用于创建体系结构的高级原理。

我将非常肤浅地涉及这些主题,更多细节可以在本书中找到。我们走吧!

组件的连接性及其确定原则


“这个或那个类别属于哪个组成部分?必须根据既定的软件开发原则做出此重要决定。不幸的是,这样的决定具有特殊的性质,几乎完全是根据具体情况做出的。”

REP: 重用/释放等效原理-重用和释放等效原理。

就体系结构和设计而言,此原理意味着组成组件的类和模块必须属于连接的组。组件不能简单地包含类和模块的随机混合;所有模块都应该有一些共同的主题或目标。

组合在一起的类和模块必须一起释放。

CCP: 通用关闭原则-持续变更的原则。
这是组件的SRP(单一职责)的原则。

出于相同原因并同时更改的类应包含在一个组件中。不同的组件应包括因各种原因在不同时间更改的类。

CRP: 通用重用原则-共享重用原则。
此原理类似于ISP(接口隔离)。

不要强迫组件用户依赖于他们不需要的东西。

该原理表明,不密切相关的类不应包含在一个组件中。

“也许您已经注意到,连接组件的三项原则相互冲突。重用等效性(REP)和一致更改(CCP)的原则包括在内:两者都在努力使组件尽可能大。重用原则(CRP)是例外,致力于使组件尽可能的小。一个好的建筑师的任务就是解决这个矛盾。”

图片

“过去,我们研究连接性要比重用等效性(REP),一致更改(CCP)和共享重用(CRP)的原理更容易。一旦我们认为连通性只是一种属性,模块就只能执行一项功能。但是,组件连接性的三个原理描述了更为复杂的变化。在选择要包含在组件中的类时,必须考虑与易于重用和开发相关的反向作用力。要根据应用程序的需求找到这些力量的平衡并非易事。此外,平衡几乎总是在不断变化。也就是说,今天认为成功的分区可能一年后仍未成功。所以,组件的组成几乎肯定会随着时间而改变,并且该项目的重点将从易于开发转向易于重用。”

组件兼容性


“以下三个原则定义了组件之间关系的规则。同样,我们面临着易于开发和逻辑组织之间的矛盾。影响组件结构的架构的力量是技术,政治和动荡的。”

ADP: 非循环依赖性原则-依赖性非循环性原则。
组件依赖图中不允许循环!

图片

从图形上显示的任何组件开始,您将沿着指示依赖关系方向的箭头开始移动,您将无法返回到原始点。这是一个非循环定向图(DAG-有向非循环图)。

图片

在此图中,我们具有导致循环出现的依赖性。由此产生的循环依赖性始终可以被打破。

打破循环依赖的方法


1.通过应用DIP(依赖倒置原则)

图片

2.新组件的介绍

图片

“第二种解决方案涉及组件结构对不断变化的需求的依赖性。确实,随着应用程序的增长,组件依赖项的结构也在增长和变化。因此,必须不断检查周期。当循环形成时,需要以一种或另一种方式破坏它们。有时为此,有必要创建新的组件,这会使依赖项的结构增长。”

自上而下的设计,或者说它不切实际


不能从上到下设计组件结构。他们一开始设计系统就不会立即得出这个结论,但这不可避免地随着系统的发展和变化而发生。

考虑到较大的框图,例如组件依赖关系的结构,我们认为组件必须以某种方式表示系统的功能。但是实际上,这并不是组件依赖关系图必不可少的属性。

实际上,组件的依赖关系图很少反映应用程序功能。在更大程度上,它们反映了应用程序的组装和维护的便利性。这就是为什么在项目开发之初就没有设计它们的主要原因。在此期间,无需收集和维护软件,因此无需绘制构建和维护图。但是随着在实施和设计的早期阶段出现越来越多的模块,管理依赖关系的需求也随之增加。此外,人们希望尽可能地限制变更的影响,因此我们开始关注单一职责(SRP)和协调变更(CCP)的原理,并结合类别,可能会一起改变。

这种依赖结构的主要任务之一是隔离可变性。我们不需要因最小的原因而经常更改的组件,而不会影响本来会完全稳定的其他组件。例如,对GUI的外观更改不应影响业务规则。添加和修改报告不应影响高级策略。因此,架构师创建并创建了组件依赖图,以保护稳定且有价值的组件免受易失组件的影响。

随着应用程序的开发,我们开始担心创建可重复使用的项目。在此阶段,共享重用(CRP)的原理开始影响组件的组成。最后,随着循环的出现,我们开始应用依赖非循环性(ADP)原理,结果,组件的依赖图开始变化和增长。

尝试早于任何类设计组件的依赖关系结构的尝试可能会失败。在这一阶段,我们对变更的协调几乎一无所知,我们无法想象哪些元素可以重复使用,并且我们几乎可以肯定会创建形成循环依赖关系的组件。因此,组件依赖项的结构应随着系统的逻辑设计一起发展和发展”

嘿,你还在这里吗?伙计,这很重要,至少要对此打个招呼才能输入下一部分的含义,这里将提供有关使用tulza的原始教程。

SDP: 稳定依赖原则-稳定依赖原则。
依赖关系应指向稳定性!

“什么是“可持续性”?想象一下站在边缘的硬币。她的位置稳定吗?您很可能会回答“否”。但是,如果您保护它免受振动和风吹袭,它可以在该位置停留任意长时间。也就是说,可持续性与变化的频率没有直接关系。硬币没有变化,但是几乎没有人会说,站在边缘,它处于稳定的位置。

解释性词典说可持续性是“在外界影响下维持自身状况的能力”。可持续性与改变状态所需的工作量有关。一方面,站在边缘的硬币处于不稳定状态,因为需要花费很少的精力才能将其翻倒。另一方面,桌子处于非常稳定的状态,因为它需要花费更多的精力来倾斜它。

这一切与软件有什么关系?有很多因素使组件的变更复杂化,例如组件的大小,复杂性和清晰度。但是我们将抛开所有这些因素,而将重点放在其他方面。有一种surefire方法,可以通过创建许多依赖它的组件来使软件组件难以更改。具有许多传入依赖项的组件非常稳定,因为要使更改与所有依赖项保持一致就需要付出很大的努力。”

图片

图片

如何评估组件的稳定性?作者建议计算其传入和传出依赖性的数量,并在此基础上计算其稳定性的度量。

  • Fan-in ( ): . , .
  • Fan-out ( ): . , .
  • I: : I = Fan-out ÷ (Fan-in + Fan-out). [0, 1]. I = 0 , I = 1 – .

因此,该原理表明,I组件的度量应大于依赖于它的I组件的度量。也就是说,指标我应该在依赖方向上减少。

重要的是要注意,如果系统的所有组件都尽可能稳定,那么将无法更改该系统。因此,并非所有组件都必须稳定。

老兄,别睡着了,我就在附近。还剩一点!

SAP: 稳定抽象原理-抽象稳定原理。组件的稳定性与其抽象度成正比。

“软件系统的某些部分应该很少更改。这些作品代表了高层架构和其他重要决策。没有人希望这样的决定是不稳定的。因此,封装高级规则的软件必须驻留在稳定的组件中(I = 0)。易失性(I = 1)应该只包含可变代码-可以轻松快速地更改的代码。

但是,如果将高级规则放在稳定的组件中,则会使实现它们的源代码中的更改复杂化。这会使整个架构变得僵化。如何使具有最大稳定性(I = 0)的组件如此灵活,以使其在更改期间保持稳定?答案在于开放性/封闭性(OCP)原则。该原则说,有可能而且有必要创建足够灵活的类,以便可以在不进行更改的情况下继承(扩展)它们。哪些班级符合这一原则?抽象。

SAP(抽象稳定性的原理)在稳定性和抽象性之间建立了联系。一方面,他说一个稳定的组件也必须是抽象的,以便其稳定性不会妨碍扩展;另一方面,他说一个不稳定的组件必须是具体的,因为不稳定使得易于更改其代码。

也就是说,稳定的组件应由接口和抽象类组成,以便可以轻松扩展。可用于扩展的弹性组件足够灵活,不会过度限制体系结构。

抽象的稳定性(SAP)和稳定的依赖关系(SDP)的原理一起对应于组件的依赖关系反转(DIP)的原理。之所以如此,是因为SDP原则要求将依赖关系指向可持续性,而SAP原则则指出可持续性意味着抽象性。也就是说,依赖关系应针对抽象性。

但是,DIP原则是针对班级制定的,对于班级,没有中间调。该类是否是抽象的。 SDP和SAP的原理适用于组件,并允许组件部分抽象或部分稳定的情况。”

如何衡量一个组件的抽象性?在这里,一切都非常简单。
度量抽象组件的值取决于其接口和抽象类的数量与类总数的比率。

  • Nc:组件中的类数。
  • Na:组件中抽象类和接口数量。
  • 答:摘要。A = Na÷Nc

度量标准A的值在0到1的范围内变化。0表示组件中完全没有抽象元素,而1表示组件仅包含抽象类和接口。

I和A之间的依赖关系

如果在图上绘制(Y-抽象,X-不稳定性),两种类型的“好”成分:抽象稳定和具体不稳定,我们会得到:

图片

但是,因为组件具有不同程度的抽象性和稳定性,远远不属于这两个点(0,1)或(1,0),并且由于不可能要求所有组件都在其中,因此我们必须假设在图A /我有一些要点决定了组件的最佳位置。

可以通过定义不应放置组件的区域(换句话说,定义排除区域)来得出此集合。

图片

疼痛区

考虑位于点(0,0)附近的组件。

它们非常稳定和具体。这些成分是不希望的,因为太难了它们不能扩展,因为它们不是抽象的,并且由于其巨大的稳定性而很难更改。我们改变进入疼痛区域的成分越多,带来的疼痛就越多。这是由于其更改的复杂性。

设计正确的组件通常不应靠近点(0,0)。
但是,实际上,有些软件实体属于此区域。例如,数据库模式尽可能具体,并且许多依赖关系都朝着它延伸。这是数据库模式更改通常带来极大痛苦的原因之一。

无用区

考虑位于点(1,1)附近的组件。

这些组件也是不希望的,因为它们尽可能抽象,没有依赖性。他们根本没用。通常,这些是从未实现的抽象类。

如何避免进入禁区?

将组件放在主序列附近或上方。这些组件的稳定性不是太“抽象”,抽象性也不是“太不稳定”。它们不是无用的,不会造成太大的痛苦。其他组件在某种程度上依赖于它们的抽象性,而它们自身在某种程度上依赖于其他组件。
组件最理想的位置是主序列的端点。但是,在大型系统中,总会有一些组件不够抽象且不够稳定。当位于主序列上或附近时,此类组件具有出色的特性。

到主序列的距离

由于希望组件位于主序列上或附近,因此有可能确定一个度量来表示组件与理想序列的距离。

  • D:距离。D = | A + I – 1 | 该指标的取值范围为[0,1]。值为0表示该组件直接位于主序列上。值为1表示该组件位于距主序列最大的距离处。

通过采用此指标,您可以在主要顺序附近探索整个设计。可以为任何组件计算度量D。度量值D远离零的任何组件都需要进行修订和重组。

图片

作者结论(罗伯特·马丁)


“本章中描述的依赖性管理度量标准可帮助您量化依赖性结构和设计抽象与我所说的“良好”设计的一致性。经验表明,存在良好的依赖性,存在不良的依赖性。该评级反映了这种经验。但是,度量标准不是最终的真理。这些只是基于任意标准的测量。这些指标并不完美-充其量不过,但我希望您发现它们有用。”

伙计,很高兴你能和我在一起。这就是第一部分。尽管仍然有很多话题,并且作者的详细思想仍然不受影响。尽管如此,我的文章的主要目的不是重述这本书,否则您一定会更高兴阅读原著。我,徒步旅行,因此内容的数量已经过分了,但是我会很混蛋,我尽量不充气。回合!

第二天。嗯,即 第2部分


介绍


这么久我一直在这里摩擦什么? “啊,是的……我们就像建筑师,或者我们真的很想成为他们,对吧?”

我们有什么? -某种可悲的预测,或者是一个可怕的系统,PROJECT,他的母亲,好吧,或者最后还没有任何问题,但是我们只是揉搓双手,看一下日历,弄清楚我们要说的话。

没有我们,我一个人工作!或者,也许我们在车库里有个助手,打算装一个新的苹果,为什么不呢?好吧,要么我们是一支军队,我们全都隶属于一家庞大的公司,要么我们正在努力工作,就像家里的穷人(当然是非裔美国人)的黑人一样,或者也许我们在悄悄地踢,以免被解雇。对于奖金丰厚的薪水,饼干和莫斯科市的风光,或者是出于热情,对于初创公司在起飞时自然会陷入困境的想法和股权。

实际上,没关系。重要的是:最后,我们所有人都只是希望我们的聪明才智不要过早弯曲,至少在我们出发之前,这是有机会的。是的,是的...

你问现在该怎么办?因此,如果您在办公室没有大哥,那么兄弟就不会没有第三只眼睛。

第一部分摘要


在本文的最后一部分,我们讨论了一些度量标准,这些度量标准使架构师能够以数字形式衡量其数字,以反映其系统架构的质量程度。

-部件的抽象
-成分的不稳定
d - ,在图上的主序列距离A / I 的性感区疼痛无用区被

揭示 我们得出的结论是,理想情况下,一个应该增加,减少比例的下降,因此,在增加了

。设计良好的组件应位于主序列上或至少靠近主序列,即D应该尽可能地接近零,并且组件之间的依赖关系应该是非循环的,并指向稳定性。

我也希望每个人都了解某些组件可能了解许多其他组件,而另一些组件则不应了解任何内容。就像在好叔叔亚伯拉罕到来之前的奴隶制国家一样,黑人(在非裔美国人的意义上)不允许使用镍铬合金(就知识而言,不仅如此),在我们的情况下,该系统中最重要的组成部分应该具有最少的知识,应该自给自足,并从不同的细节中抽象出来。

那么第三只眼呢?PHP清洁架构- 由于鲍勃叔叔(罗伯特·马丁(Robert Martin))的宝贵思想,疯狂地想可视化整个内容,便于分析和自动化的一种工具,而该工具是由于读书而出现的,以便在CI / CD中包含各种检查(类似于PHPStan,Phan和其他内容,仅用于精确识别架构问题)。

工具和测试项目。主题介绍


Fuf,一切似乎都像一个理论...现在,您甚至可以弄脏细节。
因此,对我而言,现在没有真空可以抽抽象马的经验了,而您的阅读末尾却没有理由叫我穆迪,因为您他妈的花了这么多时间,我请婆婆花了一点时间,并准备了演示sobstna这个项目,我们现在要做hara-kiri。对于那些无疑会成为并想在评论中闲逛的“超级有天赋”的家伙,我强调一下 - 一个DEMO项目
大概说了半天,我把它切碎了在女友的膝盖上。毕竟,我无法将与我合作的战斗项目的细节带给大众。……伤者们不会理解,他们会向我展示,但是我需要吗?好吧,如果您是一个简单的小伙子,而不是“特别出色的小伙子”之一,那么对于这么长的介绍我还是很烂,我只需要承担风险,并减少集市上关于什么都不做的评论中繁殖的潜在威胁。

因此,项目本身位于github.com/Chetkov/php-clean-architecture-example-project

将来,他可能会成为一个成熟的在线商店。我当然是一个凶猛的完美主义者,但是您需要完全胡说八道食入者和长肝者除了患有失眠症之外,还需要花费大量时间在“实验兔子”上并从中获取糖果。如您所知,这个项目永远不会得出合乎逻辑的结论,但是,与其他项目一样,甚至是战斗项目。

虽然还不错。目前,它具有:用户,产品和订单,以及方案:用户注册,密码更改,添加产品和预订订单

该项目或多或少都在工作,您可以自己克隆它并从沙盒文件夹中运行脚本,尽管实际上,我什至无法这样做,因为对于体系结构分析,该项目不需要可操作性。

将来,我将抛出指向特定提交的链接,以便立即修复本文中描述的技术要点。

初始状态

,我想您已经熟悉了该结构。这样我们就可以继续。

我们包括PHP Clean Architecture
composer require v.chetkov/php-clean-architecture:0.0.3


我们创建并配置配置文件

可视化分析


我们在控制台中执行(在项目根目录中):

vendor/bin/phpca-build-reports
要么
vendor/bin/phpca-build-reports /path/to/phpca-config.php

作为回应,我们得到:

Report: /path/to/reports-dir/index.html

该报告包含3个屏幕:

1.有关系统的一般信息

图片

此屏幕显示:

相同的A / I图显示了组件的分散:

图片

该图显示了组件与主要序列之间的距离:

图片

还有一个显示组件之间关系的图形:

图片

箭头指示依赖关系的方向,而其上的数字指示连接的强度。

因为现代IDE提供了一种简单的重构方法(它们自己查找并修复了显式调用方法或类的所有区域,例如,在重命名或转移到另一个命名空间时),为了提高连接强度,我采用了依赖模块所使用的依赖模块的元素数量。

例如:服务模块的元素知道模型模块的12个元素,而基础结构元素知道服务的 1个元素。等等。

顺便说一句,什么是*未定义*兄弟,预期的问题 这是为系统分析期间无法归因于任何已知元素(即配置文件中列出的元素)的所有元素自动创建的模块。

但是,如果您以这种方式更正配置:

图片

然后,在分析系统的过程中,还将考虑通过composer连接的数据包(它们本身将不会被扫描,但是图像将变得更加完整)。

顺便说一句,您需要vendor_path中指定vendor目录的路径,并在要排除的软件包目录的排除路径中指定(例如,如果我们在要扫描的模块的主配置中描述了软件包)。

启用vendor_based_modules之后 尽管我们没有更改模块本身的配置,但图形已更改

图片

2.有关组件的详细信息在

图片

这里,我们还可以看到:

  • 互连图,但不是整个系统,而是仅涉及的组件
  • A / I图表仅显示当前组件
  • 关键模块功能

    图片


  • 出站依赖关系图显示当前模块中文件的数量和列表,具体取决于其他模块的文件。
  • 图片

  • 还有一个传入依赖关系图,显示了当前模块中其他模块中文件的数量和列表。

    图片

我认为最后两张图特别有趣,因为 很容易找到对它们的不需要的依赖关系,但是稍后会更多。

3.有关组件元素的详细信息在

图片

这里您可以看到:

  • 的主要特征的元件,诸如类型抽象,不稳定性,原始的,并且其组件所属访问修饰符

“ Che,PHP中的类访问修饰符?” -你说用手指在太阳穴区域钻一个洞,对吗?慢慢来,我知道目前没有私人课程,但是如果有的话,这会很酷吗?总的来说,以后会更多。

  • 依赖图,反映了所考虑元素与系统其他元素的交互

  • 以及具有传出和传入依赖性的平板电脑

    图片

完成对屏幕的描述后,转到配置以选择和配置它的配置方式。

配置选项


限制到主序列的最大允许距离(对于所有组件)

首先,让我们尝试将所有组件设置为到主序列的最大允许距离。认为它们都将位于主要对角线上是很愚蠢的,因为世界并不完美,所以让我们变得现实。我执行0.3

图片

重新启动报告生成命令,并立即在主页上看到违规情况。模型组件超出允许距离0.192

图片

将最大允许距离限制到主序列(特定组件)

很好,但是让我们假设它是可以违反此限制模型组件。发生不同的事情……毕竟,我们常常已经没有理想的系统来与我们合作,支持并改进它们。任何人都知道,即​​使有神,也没有人能够迅速缩短这一距离(我希望他会原谅我)。

我认为,最主要的是确定当前状态,努力改善并控制局势,以免加重局势。

同样,转到配置,并仅针对特定模块设置max_allowable_distance。我将其当前值固定为0.492

图片

ZBS,现在一切恢复正常。

图片

但是,如果他带着** ka Vasya再次抽烟并变得更糟- 砍下他的手!包括运行phpca-check命令的CI / CD (我们将在后面讨论)会骂他,甚至是粗话,当然,它会突出显示错误。

组件依赖控制

在我们的军械库中,还有什么对付糟糕的架构还有什么好处呢?当然,依赖控制。谁知道谁,反之亦然。

您如何看待,系统的最核心部分(例如domain)可以使DDDowski完全了解一些臭味的基础架构吗?
当然是的,对某些人而言,直接是成功的属性(嗯,我在说的是那些将HTML与业务逻辑混合在一起的人)。但是最后,就像是,我不应该……我当然是xs,但是书中各种聪明的家伙都说这不是patsansky。

然后让我们这样激荡……一切都在相同的地方,在model的限制配置中

图片

嗯...到目前为止,所有规则,因为关于基础架构的模型真的一无所知...

好吧,让我们玩得开心...愚蠢无疑很罕见,但是我没有提出更好的建议。 Krch,在创建用户时,我们将“发送” SMS,在创建订单时,将“发送”电子邮件。并通过基础设施中通告程序的特定实现来做到这一点

github.com/Chetkov/php-clean-architecture-example-project/commit/6bad365176b30999035967319a9c07fae69fabf9

现在我们看一下报告...正如我们所看到的,报告不同页面上的图形强调了这种连接是非法的。

家。

图片

组件报告。

图片

在“外发依赖” 模型和“入站依赖”图上基础架构,我们立即

图片

模型元素的“传出依赖性”表基础架构元素的“入站依赖性” 表中立即看到违反引入规则元素

PHPCAEP \模型\用户\用户

图片

PHPCAEP \基础结构\通知\ Sms \ SmsNotifier

图片

以及元素关系图。我认为将来会完全摆脱它,因为它的信息量不是很大(特别是对于活跃使用的类,因为节点名称的长度+节点的数量巨大),

图片

可以使用allowed_dependencies 配置来执行类似的操作

图片

结果将完全相反。

可以组成一个指示模块的配置并禁止允许(如果有需要,我们将在评论中进行详细讨论)。尚不能同时在禁止允许中指定一个组件。...曾经有过种种想法,以引入一种配置来指示优先级,但是到目前为止,我还没有做到这一点,并且不确定该怎么做。这完全取决于您的反馈。也许这一切都浪费了?

PHP中的公共/私有类

好的,我们学习了如何缩小和控制组件知识的范围。已经不错。下一步是什么?

然后是另一个问题。敌人不睡觉,尽管在大多数情况下,这个敌人是我们自己还是办公室的助手。

毕竟,它发生了,你遇到了一个女孩,聊天,发现了关于她的东西,也许甚至向她求婚,但是该死,这对你没有用。我们是朋友,所有的一切……当她遇见您时她可以亲吻您,可以用亲切的言语来倾听并支持您,但她不会给您任何杀戮。所以我在说什么...啊,在这里...所有关于可访问性。

但是在代码中,不断地...连接一个新的程序包,不是一天过去了,但是它已经被使用了,但是可以直接用于所有地方从四面八方。您的代码库的一半已经绑定到其各种类。简而言之,他与其他人有着非常密切的联系。也许在某些情况下这是常态,但不是全部,对吗?

您: “一切都很好,很害羞。如何解决问题?”
我: “只保留允许交互的类,并限制对其余类的访问。”
您: “但是在PHP中,没有类的访问修饰符。”
我: “我同意,但是有一个PHP Clean Architecture。”

现在将再次以吸毒者为例,但该怎么做。

当然,在实际的项目中,案例充满了案例,但是它们可以带来一个瓶子来消耗信息,并让他们坐下来。这就是为什么你必须作曲。

假设由于某种原因,模型中,只有2个类可以让其他人知道...用户和订单,其余所有类都应隐藏。

图片

我们现在有什么?

指望主要。

图片

您可以立即看到需要检查的组件。

我们爬上去看看基础设施出了什么问题

图片

在“传出依赖性”图上,我们看到违反规则

图片

的元素在元素信息页面上,类似。

图片

如果在config中指定private_elements,我们将得到完全相反的结果

图片

例如,我们禁止所有人了解Fio。

现在在

图片

主页上服务组件信息页面上

图片

在元素信息页面PHPCAEP \ Model \ User \ Fio上

图片

监控违反ADP和SDP原则的情况

,也许,我们仍然需要强调包括检查的可能性:

  • 违反ADP原则,即 图中是否存在循环依赖关系(check_acyclic_dependencies_principle
  • 并且违反SDP原则,即 从较稳定的模块到较不稳定的模块的依赖关系(check_stable_dependencies_principle

图片

但这到目前为止仅在phpca-check中有效并且未在报告中显示。将来,我想我会纠正它。

CI / CD中的自动控制


我一直在谈论第一部分-可视化。并且可以在其基础上进行分析。

是时候让我们的朋友govnokodera值得尊敬的同事受苦了。

我们在控制台中启动(在项目根目录中):

vendor/bin/phpca-check

要么

vendor/bin/phpca-check /path/to/phpca-config.php

假定运行此命令将被添加到项目的CI / CD进程中。在这种情况下,该错误将阻止进一步的组装。

该脚本以错误终止,并抛出以下内容:

图片

我很努力,列表在实际项目中会更长。

汇报

  1. 违反非循环依赖原则(ADP)
  2. 同样,但是周期要短一些
  3. 2个模型元素(列出)取决于基础架构,这是配置所不允许的
  4. 再次违反ADP
  5. 另一个周期和违反ADP
  6. 违反SDP,因为 更具可持续性的模式取决于缺乏可持续性的基础设施
  7. 再次循环依赖,错了
  8. 1个服务元素(列出)取决于非公共Fio

由于我们的努力和勤奋的政府,大约可以得到这个结果

现在,让我们把一切都摆在屁股上。好吧 并非所有内容,我都会自然地离开配置。我只统治代码。

对于初学者来说,修复违反以下依赖规则的文件是有意义的。在这个项目中,大多数周期可能会自行消失,但实际上,肯定需要更长的时间(尽管这取决于对系统的忽视程度和配置的设置)。

故障排除

我删除了以前发明的瘾。

github.com/Chetkov/php-clean-architecture-example-project/commit/f6bbbf713ebb4a22dfb6061f347ef007ba3b422f

重新启动供应商/ bin / phpca-check

图片

嗯,只有正确的配置,因为 吸毒者确实发明了一个例子。

图片

再次进行供应商/ bin / phpca-check

图片

,CI / CD继续!

就这样。

后记


如果您没有读到最后,请抓住五分之一,否则,请嗅探您的脚步(无论如何,您都没有看到)。

但是说真的,谢谢您的时间,无论您是在中间合并还是阅读,深入研究每一行并分析每个屏幕或对角翻转两个部分都没有关系。不管怎么说,还是要谢谢你。

如果出现问题,我再次表示歉意。

也许,对某些人来说,我的表现方式似乎太过气势或不敬,我只是想稍微稀释一下文章,而绝不冒犯任何人。我认为,如果没有此功能,结果将变得过于干燥且难以阅读。

我真的很想知道您的意见,如果您有任何想法,想法,建议或反对意见,请在评论中进行讨论。

干净的代码和灵活的体系结构为您服务!

All Articles