4、你最赞赏和最让人反感的行为网络行为是什么

怎样用精神分析学家和行为主义鍺的观点进行分

四岁小孩怕黑晚上不敢睡觉,怎样用精神分析学家和行为主义者的观点进行分析
全部
  • 其实他不一定是心理问题我意同倳孩子都5岁了结果还是和妈妈一个被窝,据他所说就是跟孩子分床分的太晚的原因以至特别依赖母亲。
    你可以让他慢慢适应慢慢过渡!
    铨部
  • 答:一个4岁的孩子你就用那么深奥的东西去分析他真奇怪

  • 答:人们将行为主义描述为一种学习理论。不过学习的心理过程需要用荇为术语 来表示。因此为了回应一种特定的刺激而连续不断做出一种新行为时,就发生了 学习

  • 答:精神分析理论的代表性观点主要有鉯下几种:(1)以弗洛伊德(S. Freud)为代表的经典的精神分析理论学派认为婴儿和父母的 关系是婴儿的情绪和社会性发展的基础。...

  • 答:教育的精神是囚的自由、平等、健康、和谐的发展

  • 餐饮业厨房产生的油烟,顾名思义废气中主要污染物为油烟,一般采用静电除油 液化气属较清潔能源,废气...

  • 铝属于两性金属遇到酸性或碱性都会产生不同程度的腐蚀,尤其是铝合金铸件的孔隙较多成分中还含有硅和几...

  • 1、以身作則,如果连自己都做不好还怎么当班长? 2、人缘好我就是由于人缘不好,才改当副班长的 ...

  • 规模以上工业企业是指全部国有企业(在工商局的登记注册类型为"110"的企业)和当年产品销售收入500...

  • 组装一台机箱需要显示器、机箱、电源、CPU、内存、显卡、网卡、硬盘、主板、以及一些連接硬件的电线。 ...

  • 1.将WMware虚拟机克隆 2.将虚拟机的多个磁盘文件合并成一个;(否则vSphere会说找不到...

这篇文章是()的一部分这部编年史由组成。在这一系列文章中我将写下我对软件架构的学习和思考,以及我是如何运用这些知识的如果你阅读了这个系列中之前的文嶂,本篇文章的的内容将更有意义

我们学习了如何编码,我们构建了一些很酷的应用然后我们学习了架构以及它们如何保证应用可以維护多年...

但是我们还是需要向别人(新来的开发、产品负责人、投资人...)解释应用是如何工作的,我们还需要做更多...我们需要文档

我们囿哪些可供选择的文档工具来表达整个应用的构建块以及应用如何工作?!

本文我将介绍以下这些选择:

我们可以用 UML 绘制各种图我们将這些图分成两大类:

  • UML 行为图(译注,)
  • UML 结构图(译注)

这里我不会介绍每种类型的细节,一篇文章不可能讲清楚而且这些图的类型的介绍文档实在是太多了。要想深入了解每种类型你可以点击上面这些连接,它们会跳转到 的对应介绍或者可以读一下。(译注可以茬这里找到各种 UML 图的中文介绍,)

总而言之UML 很酷很有意思,表达力很强我们可以简单地描绘我们的思路,并和同事讨论

然后,用 UML 记錄一个完整的应用会用到不同类型的图而且,如果我们只想用一张类图来表达完整应用就是在自找麻烦

一个适合 UML 类图的例子是用来记錄设计模式:

很好,这实际上很不错!它可以表代类、接口、使用以及继承关系、数据和行为这种类图也简洁易读,因为图很小创建起来也快。

然而下面这个例子却没什么用...它非常大,因而令人困惑并且很难懂而且,绘制这样一张类图非常耗时当我们完成绘制的時候就已经过时了,因为在绘制的同时多半代码已经发生了变化

所以,我们可以并且应该使用 UML但是应该只在某些情况下使用,如:描述模式应用每一小部分的细节,或者没有太多细节的粗粒度应用试图(用的不是类图)(译注,除了使用一些重量级软件来绘制 UML 图之外可以使用 来绘制。PlantUml 是一个开源工具使用代码来描述 UML 图,通过工具来生成真正的图形)

但是问题没有彻底解决,我们怎样记录一个唍整的应用!

这种将软件应用架构可视化出来的方法基于五种不同的应用视图/视角,告诉我们每种试图应该是用哪种图来记录

  1. 关注系統提供的功能以及代码设计如何提供这些功能;
  2. 描绘代码的静态组织结构,如组件、模块和包;
  3. 聚焦系统的运行时行为系统进程如何通信,以及并发、同步、性能等等问题;
  4. 说明应用的物理组织结构就是“硬件上运行的是什么代码”;
  5. 利用少量几个用例来说明完整的架構,用例就是交互的序列部分架构在这些用例上进行演进。

需要注意的是4+1 架构视图模型并不要求我们使用前面提到的全部这些图,甚臸不会用到所有的视图我们总是要理解工具,根据我们的需要使用该用的功能

架构决策记录(ADR,Architecture Decision Record)实际上记录的并不是应用程序架构嘚当前或未来状态而是关于导致这些状态的原因。这些原因特别重要它们的目的是告诉他人和未来的自己,为什么架构是这个样子的

ADR 就是一条架构决策的日志条目,这些已经做出的决策导致了架构现在的状态或者未来将要变成的状态它们包含了这些描述架构的图背後的原因

首先我们需要了解一些制品:

  • 架构决策(Architecture Decision,AD):解决一个重要需求的软件设计选择;

我见过一些创建 ADR 的模板其中一些有点東西,于是我创建了自己的模板你也可以,也许应当创建符合自己或团队需要的模板

我认为就模板而言最重要的是简单,可以用一些攵件来帮助充实并协助作出务实和公正的决定

在讨论或者决策后记录一份文档,并不是 ADR 的最佳实践最佳实践是在讨论开始的时候就把咜当做记录思路/提案的 RFC(Request For Comments),我们提出的这些思路/提案需要团队/部门其它成员的输入/观点/批准其目的实际上是用它来开始讨论,进行头腦风暴做出可能的最佳决策,并将提案文档本身作为决策日志条目(ADR)从一开始就编写 ADR 并不意味着不可变,相反随着讨论的展开它表虛更新/改进把所有考虑到的方案以及利弊都写下来,我觉得这一点特别重要这样才能激发讨论和明确的决定。

如果你想进一步探讨这個话题推荐(译注,也可以参考 Phodal 的两篇文章:、)

C4 模型是 Simon Brown 发明的,是我目前看到的关于软件架构文档的最好思路我会快速地用自己嘚语言来阐述主要的思路,但使用的还是他的图例

其思路是用四种不同粒度(或者“缩放”)层级来记录软件的架构:

这是最粗粒度的圖。它的细节很少但其主要目标是描述应用所处的上下文因此,这幅图中只有一个方块代表整个应用其它围绕着应用的方块代表了应鼡要进行交付的外部系统和用户

现在我们将应用放大,也就是上一级图中的蓝色方块在这一级它对应的是下图中的虚线框。

在这个粒度级别我们将看到应用得容器,一个容器就是一个应用中技术上独立的一小部分例如一个移动 App,一个 API 或者一个数据库它还描述了應用使用的主要技术容器之间的通信方式

组件图展示的是一个容器内的组件在 C4 模型上下文里,每个组件就是应用的一个模块不光昰领域维度的模块(如账单、用户...)还包括纯粹的功能模块(如 email、sms...)。因此这个层级的图向我们展示了一个容器的主要齿轮和齿轮之间的齧合关系

这是最细粒度的图,目的是描述一个组件内部的代码结构在这个层级,我们使用的是表示类级别制品的 UML 图

要了解更多信息,可以阅读 Simon Brown 自己的说明:以及或者看看他关于 C4 模型的。(译注可以参考我的同事的文章“”。)(译注前面提到的 PlantUml 可以自己定义扩展图形,C4 模型上述的前三种图已经有了开源的扩展 使用非常简单高效。第四种代码图本来就是 PlantUML 支持的 UML 类图)

我认为 C4 模型是一种非常好嘚记录应用架构的方式,它可以帮我们很好地理解应用在某个层次上的架构但我觉得还是不够,尽管搞清楚这个问题花了不少时间

  1. 除叻一些例外情况,比如 Simon Brown 的这些图需要人工绘制,而不能自动生成也不能直接从代码中生成,这意味着它们体现的可能并不是实际代码而是我们目前对代码的理解;
  2. 这些图并不能帮助我们发现应用程序代码库中存在的问题,比如混乱的代码关系和糟糕的结构这些问题影响了模块化和封装,这对任何工程产品都是至关重要的;
  3. 这些图不能帮助我们从整体上理解代码库:应用程序的齿轮可以做什么它们の间如何交互。

我找到了另外两类图来帮我们解决这些问题

依赖图可以有效地告知我们代码库中不同类型代码之间存在的依赖。

有一点特别重要这些图是直接从代码自动生成的,不然这种图只能反映我们认为的代码的样子如果理解真的丝毫不差,我们也就不需要这种類型的文档了

此外,我们能借助这种依赖分析能力当预设的依赖关系规则被破坏的时候停止构建,这一点可能比这些图本身更为重要用来生成依赖图的工具也应该可以当做测试工具使用,包括在 CI 流水线上使用就像单元测试那样,组织不必要的依赖性进入生产环境這维护并强化了模块化,反过来也能帮助实现较高的变更频率进而适应特性开发的快节奏。

对这种图来说我觉得有三种不同类别对不哃的依赖类别进行断言。

下面的这些例子都是用我的通过 生成的这是我的一个实验项目。你可以在仓库根目录下中找到生成配置

不过囿一点请注意,我自己添加了一些颜色让这些图例在这篇文章里更容易读懂。不同的颜色代表了应用的不同层级和我之前文章中配图嘚层级一致:

这种图的目的是可视化,并且确保每个层级的代码只能依赖内部或下面的层级

因此,我们可以看到下面的图例重例如,朂外面层级之一的基础设施层可以依赖其他任何层反过来,最中心的领域层只能依赖下面的层层,即 SharedKernel-Domain(它也是领域的一部分)和 PhpExtension(其玳码被当成语言自身的一部分使用)

用 生成的 的层级依赖图

层级依赖图分析的是层级之间的依赖,但在层级之还有一些依赖关系不允许絀现

类依赖图则有助于分析代码仓库中不同类型的类之间的依赖关系,尤其是那些属于同一层级的类的依赖关系

例如,如果我们希望倳件可以被序列化以便于放到队列中我们可能希望它们不要包含实体,因为使用 ORM 来对实体进行反序列化和持久化可能会出问题事件依賴于服务也是没有意义的。使用这种类型的依赖图或者更准确地说,使用这种测试依赖关系的工具我们可以很容易地检测到这些问题,防止它们进入生产环境

用 生成的 的类依赖图

组件是领域维度的模块,这样的模块既包含应用层也包含领域层一个组件(例如“账单”)可以包含全部有关的用例和领域逻辑。

组件可以和 DDD 的限界上下文与/或微服务对应起来这意味着它们必须完全从物理上和时间上解耦。如果我们的单体应用包含的是完全解耦的组件(在代码维度)它就能很容易的转换成微服务架构。

而且如果能在其它非领域维度的模块上也应用同样的解耦要求,我们就能保证任何模块都可以轻松进行替换

组件依赖图的木不碍事保证应用组件和模块之间的解耦。

注意在下面这个图例中,同一个层级中的模块(颜色相同的节点)是互相不知道对方的存在的至少直接的依赖是不存在的。

尤其重要的┅点是两个组件(User 和 Blog图中央较深蓝色的两个椭圆)是解耦的。如果应用采用了微服务架构这两个组件应该是微服务。

用 生成的 的组件依赖图

大约一年前我意识到这些文档选项还有一些遗漏的地方:所有这些图只能告诉我们组成应用的是哪些构建块,哪些构建块之间需偠交互以及它们之间的关联但是这些图不能告诉我们 构建块的作用是什么也不能告诉我们 它们之间是如何交互的以及是 何时交付的。这要求我们既要从用户视角理解应用也要从开发者视角理解代码库。前面这些图无法告诉我们应用中有哪些用例也无法告诉我们事件是那些用例触发的,也无法告诉我们这些事件的后果是什么如果我们把这些图拿给产品负责人看,他会觉得大部分图对他没有任何帮助

所以我想到了一种信的文档图,我把它称为应用地图它可以替代 C4 模型组件图。

应用地图的目标就是成为名副其实的应用地图定义絀其中的“城市”(组件)、“当地的道路”(用例)、“高速公路”(事件)等等。

组件和模块之间的区别是模块是应用程序的任何模块化片段,而组件是应用程序的领域维度的模块因此,虽然 ORM 是应用程序的模块但它不是组件,因为它只关心技术另一方面,“账單”模块是一个组件因为它关心的是领域。

应用地图首先要定义出应用的组件即领域维度的模块,如“账单”、“用户”、“公司”、“订单”、“产品”等对一个简单的博客应用来说,我们可以划出两个组件“用户”(User)和“博客”(Blog):

在每个组件内部,我们萣义出可以发给它们的命令“用户”组件可以创建和删除用户,而“博客”组件可以创建和删除帖子还可以创建帖子的评论。

接下来我们列出每个组件相关的全部服务。这些服务之所以和组件相关是因为它们要么触发一个事件,要么被另一个组件直接使用这一点佷重要,因为应用地图应该把组件之间的连接及其含义和导致的任何副作用可视化出来因此,我们需要展现将组件和其他组件串联起来嘚服务及其名称(服务命名应该代表它们的功能)

服务列完之后,每个组件还要列出所有的事件***器哪怕实际上这些***器没有被鼡过,这样我们就可以检测到并按需修复或者删除未使用的代码这一点很方便。

我所说的***器就是一个类其公共方法由唯一一种的倳件类型触发,它们关注的是某一个事件

我们还要列出组件的事件订阅者,这和列出***器的目的一样事件订阅者和事件***器类似,但它的公共方法由不同的事件触发它们专注于一个复合的任务,一个类***不同的框架事件以控制何时开始、提交或回滚事务请求,就是一个事件订阅者的例子

现在,我们已经在地图中列出了所有的组件及其功能这张地图非常有价值,它能告诉我们或任何非技术囚员每个组件可以做什么。

但是它仍然没有告诉我们所有这些功能是之间是如何关联的,比如如“用户创建博客文章会产生什么结果”

要体现出这些关联,第一步是列出特定功能被触发时组件上会发生什么

在下面的这幅图例中,我们可以看到删除帖子(“DeletePost”)将触發 PostService 的DeletePost() 方法此外,当***器***到了用户已被删除的通知事件时也会触发这个方法。这告诉我们我们的应用删除帖子可以是用户直接命令导致的结果,也可以是帖子作者被删除导致的结果

我们可以看到用户组件在创建帖子时,其作者自动订阅了帖子的主题(标签)

現在,我们有了组件内部的流的相关信息但是我们仍然缺少跨组件的流的相关信息,因此我们要加上被触发和被***的事件:

  • 删除用户將触发将删除用户帖子的事件;
  • 创建帖子将同时触发作者订阅帖子主题的时间和提高作者等级的事件;
  • 任何用例只要删除帖子都会触发降低作者等级的事件

有了地图上的这些信息,我们就可以导航了任何技术人员或非技术人员都可以清楚地看到,任何应用用例触发时会發生什么这可以帮助我澄清我们的代码,和对应用行为的想法
(译注,如果熟悉我们可以发现,上述这些组件图和依赖非常想我们在倳件风暴过程中不断梳理出一些领域概念包括事件、命令、聚合、API,慢慢浮现出来的限界上下文地图/服务地图这个工具可以帮我们将倳件风暴的结成果进行电子化)。

然而这种图用在大型应用中时仍然或存在与前面提到的关系图相同的问题:

  1. 这份图需要花费大量的精力囷时间来完成,而维护其简单的时效性也要大量投入;
  2. 最后这幅图也会变得很大上面有很多文本,可读性也不是最好的

要解决第一个问題,我们需要能够随时从代码中生成应用地图这样创建应用地图不费吹灰之力,维护也不需要什么成本想要创建的时候可以立即创建。

要解决第二个问题我们需要能够选择性的生成部分应用地图。例如提供我们想要分析的用例的名称,只生成与给定用例相关的部分哋图

所以,我们需要一个工具但这个工具...现在...还不存在!

最近我开始创造这个工具,目前只有组件内部的流这部分功能还没完成但昰已经可以列出所有命令、服务、***器、订阅者和事件。这个工具仍然还处于非常早期的阶段不光是因为缺少组件内部的这些信息,還因为它分析的代码库还不够灵活但我目前工作的公司的代码库可以用它生成这样的图:

生成的(不完整的)应用地图示例

如果你对这个项目感兴趣,可以在找到它不过要请注意,这个仍然是非常初级只是验证了我的想法,而且我已经有几个月没做这个了如果你觉得有價值,也有时间可以贡献请联系我,我会全力支持你帮你创建任务让你把这个工具提升到更高的水平。

参考资料

 

随机推荐