GraphGists

简介

有时软件开发似乎只是随意发生的,尽管我们忠于勤奋和流程。系统通过人员、技能和工具的某种组合进入我们的生活。结果通常是一堆由许多作者编写的、不熟悉且不清楚的组件,对全局了解甚少。

广泛认知的好处

当软件得到良好管理时,它会受益于对围绕其创建和使用生态系统中“活动部件”的广泛认知。真实的人与我们构建的系统进行交互,我们应该构建更好的模型来跟踪和描述这些系统。

碎片化的功能和孤立的团队

很多时候,致力于特定功能(如质量保证)的团队拥有允许管理与其工作职能直接相关的实体的应用程序和系统,但是!… 这些团队没有一个主系统将其他团队和工作职能的关注点联系起来。Neo4j 可以通过正确的建模来解决这个问题。

连接关注点

通过跟踪系统的各个部分、它们如何连接和交互以及谁关心这些连接,我们可以更好地了解我们所做更改的影响、与这些更改相关和受其影响的利益相关者,并且,通过可视化,我们可以预测和传达这些影响。

关于模型

zRAOaHp

在此模型中,已采用以下类别对密切相关的标签进行分组

节点域

包含的标签

人类

:Audience, :Group, :Organization, :Person, :Role

流程

:CheckIn, :Defect, :Feature, :Iteration, :Release, :Requirement, :Task, :TestCase, :TestSuite, :UserProfile, :UserStory

技术

:AppLayer, :CodeProject, :CodeSolution, :Component, :CssFile, :Database, :DbFunction, :DbTable, :DbSchema, :DbView, :Environment, :File, :JsFile, :LocalizationKey, :Location, :MvcController, :MvcView, :Platform, :Permission, :Service, :Server

知识

:Audience, :Document, :Term, :Publication, :Skill

测试

:Defect, :Environment, :Feature, :Requirement, :TestCase, :TestSuite, :UserProfile, :UserStory

网络

:CssFile, :JsFile, :MvcController, :MvcView

设置

“人类”节点域 - 人员和群体

拥有构建软件的人员或组织环境的“地图”使我们能够应对查找问题答案或履行更改系统所需请求的挑战。当我们需要通知利益相关者其业务流程的影响时,它还有助于我们的沟通工作。

// Find Node Types in the "Human" Node Domain
MATCH (m) WHERE m:Person OR m:Group OR m:Role OR m:Organization
RETURN m;

“流程”节点域 - 跟踪工作

在此示例中,通过元数据包含在“流程”节点域中的标签用于查找此类节点的实例。

// Find node examples in the "Process" 'Node Domain'
MATCH (nt:NodeType)--(:NodeDomain { name: "Process" })
WITH COLLECT(nt.name) AS processNodeTypes
MATCH (m) WHERE LENGTH(FILTER(lbl IN labels(m) WHERE lbl IN processNodeTypes)) > 0
RETURN m LIMIT 50;

示例:查找连接的系统元素

在准备修改应用程序中的共享代码资产时,可视化资产与系统其他部分的连接非常有用。例如,考虑一个包含影响 Web 界面中多个视图的共享样式表的电子商务应用程序。Cypher 查询可以揭示对正在修改的代码的多个依赖项。

这是一个 Web 电子商务应用程序中共享 CSS 文件的示例。

// CSS to MVC View and MVC Controllers, if present
MATCH (css:CssFile)--(vw:MvcView)
OPTIONAL MATCH (vw)--(ctl:MvcController)
RETURN css, vw, ctl;

示例:建模源代码签入

随着源代码的签入,跟踪源代码更新到它们影响的资产和功能非常有用。在大多数系统中,源代码控制本身就是一个孤岛,没有提供任何跟踪功能来抽象应用程序中功能区域的指定。通过在图中建模代码提交,您可以建立我们日常使用的工具不支持的连接。

// Developer checks in changes
MATCH (dev:Person { name: "Dev, Donna" })
MATCH (global_css:CssFile { name: "Global.css" })
MATCH (details_css:CssFile { name: "ProductDetails.css" })
MERGE (checkin:CheckIn { name: "Change set 2231" })
	ON CREATE SET checkin.description = "CSS fixes for product details"
MERGE (global_css)-[:INCLUDED_IN]->(checkin)
MERGE (details_css)-[:INCLUDED_IN]->(checkin)
MERGE (dev)-[:SUBMITTED { submitDate : "2015-06-13" }]->(checkin)
RETURN dev, global_css, details_css, checkin;

示例:签入影响了哪些功能?

通过在 Cypher 查询中使用几个“跳转”,可以确定对高级功能的可能影响,并且此信息可用于缩小需要关注的项目列表。

// What features did a checkin affect?
MATCH (checkin:CheckIn { name: "Change set 2231" })
MATCH (css_file)-[:INCLUDED_IN]->(checkin)
MATCH (css_file)--(vw:MvcView)
MATCH (vw)-[*1..3]-(feature:Feature)
RETURN DISTINCT checkin, css_file, vw, feature;

示例:质量保证需要运行哪些测试?

超越受影响的功能,您还可以使用测试套件与功能的关联以及测试用例与测试套件的关联来构建给定代码签入需要执行的测试用例列表。

这还可以更进一步,根据与版本关联的代码(稍后描述)考虑版本所需的测试用例。

// Data: What tests does QA need to run?
MATCH (checkin:CheckIn { name: "Change set 2231"})
MATCH (css_file)-[:INCLUDED_IN]->(checkin)
MATCH (css_file)--(vw:MvcView)
MATCH (vw)-[*1..3]-(feature:Feature)
MATCH (t_case:TestCase)--(t_suite:TestSuite)-[*1..2]-(feature)
RETURN DISTINCT t_suite.name AS `Test Suite`, t_case.name AS `Test Case`;

示例:将签入与版本关联

通过将签入与版本关联,您可以对版本所做的更改进行全面分析,包括受影响的功能。

MATCH (checkin:CheckIn { name: "Change set 2231" })
MATCH (release { name: "Release v1.3" })
MERGE (checkin)-[:INCLUDED_IN]->(release)
RETURN checkin, release;

示例:此版本需要测试什么?

可以从模型中得出关于为版本运行哪些测试用例的结论。

// Data: What needs tested for this release?
MATCH (rel:Release { name: "Release v1.3" })--(checkin:CheckIn)-[*1..4]-(feature:Feature)--(suite:TestSuite)--(testCase:TestCase)
RETURN DISTINCT rel.name AS `Release`, checkin.name AS `Check-In`, suite.name AS `Test Suite`, testCase.name AS `Test Case`;

示例:给定版本计划了什么?

除了预测版本的测试需求外,还可以对版本的“内容”进行高级概述建模。

// What's scheduled for Release v1.3?
MATCH (release_v1_3:Release { name : "Release v1.3" })
OPTIONAL MATCH (release_v1_3)<--(n)
RETURN release_v1_3, n;

示例:给定版本中有什么内容(来自签入的版本说明)

与版本关联的签入的原始视图允许编译版本说明,然后发布给利益相关者。

// Data: What's in release v1.3?
MATCH (rel_v1_3:Release { name: "Release v1.3" })
OPTIONAL MATCH (rel_v1_3)--(checkin:CheckIn)
RETURN rel_v1_3.name AS `Release`, checkin.name AS `Check-In`, COALESCE(checkin.description, "No description provided") AS `Description`;

示例:每个环境中存在哪些版本?

软件开发团队面临的挑战之一是跟踪每个环境的版本。如果您只有有限数量的环境可供选择,那么了解这一点就更加至关重要。

第 1 部分:将版本添加到 UAT 环境

// Add v1.3 to UAT
MATCH (rel_v1_3:Release { name: "Release v1.3" })
MATCH (uat:Environment { name: "UAT Environment"})
MERGE (rel_v1_3)-[r_1_3:DEPLOYED_IN]->(uat)
RETURN uat, rel_v1_3, r_1_3;

第 2 部分:按环境检查版本

// Releases in environments
MATCH (rel:Release)--(env:Environment)
RETURN rel, env;
// Data: Releases in environments
MATCH (rel:Release)-[i]-(env:Environment)
RETURN rel.name AS `Version`, TYPE(i) AS `is`, env.name AS `in Environment`;

试一试

自己执行一些查询来探索上面描述的模型。

结论

通过对软件开发过程的不同部分进行建模,可以在软件开发过程中更好地理解风险和影响。这可以避免浪费时间和精力去解决模型可以揭示的意外问题。


作者:Jeffrey A. Miller - Twitter | 博客 | LinkedIn