k00ni / dwm
该软件包的规范仓库似乎已消失,因此软件包已被冻结。
Requires
- php: ^8.0
- composer-runtime-api: ^2.2
- doctrine/dbal: ^3.3.4
- ml/json-ld: ^1.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^1.4
- phpstan/phpstan-phpunit: ^1.0.0
- phpstan/phpstan-strict-rules: ^1.1
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2023-03-24 14:56:40 UTC
README
DWM 是一个项目,旨在探索增强软件开发的真实知识驱动方法。目前重点关注用 PHP 8.0+ 编写的系统。
当前状态:正在积极开发,预alpha版本。
许可证
本作品根据 MIT 许可证条款授权。
为什么使用 DWM?
DWM 旨在用于具有复杂业务案例的软件,并且(高度)依赖于领域知识。领域知识包括描述感兴趣领域所有信息,如重要术语、类层次结构等。目前,领域知识通常被放入源代码和/或关系数据库模型中。
这有以下 缺点
- 存储在源代码中的知识意味着在领域变更的情况下,您被迫更新您的代码。
- 除了领域知识外,代码通常还包含平台(例如操作系统)和供应商组件相关的信息和程序。您将得到不同事物的混合体。
- 领域知识的变化可能导致代码变化,这可能导致错误。同样,平台或供应商组件相关代码的变化:它们可能导致错误和不良行为。
- 在测试代码中与知识相关部分时,您必须首先将其分离。
具有领域知识的源代码看起来如何?
示例 1
包含领域知识的源代码可能看起来像
/* * domain is e-commerce */ $price = 100.0; /** * VAT = Valued Added Tax * * @var int */ $vat = 19; if (19 != $vat) { // error, VAT must be 19%! } else { // VAT correct, do something }
在这个例子中,我们将增值税(增值税)概念部署到我们的数据中。增值税通常是一个浮点数 0 =<
,用于计算毛价。
当我们的增值税从 19
变为 18.1
时会发生什么?
示例 2
另一个例子是类似以下代码
class Person { public ?string $name = null; } $person1 = new Person(); $person1->name = 'Name'; // ... // we check that name is not empty if (null != $person1->name && 0 < strlen($person1->name)) { // Person::name is correct } else { // Error, name is empty or null }
在这个例子中,我们构建了一个结构,该结构强制实施一定的数据模型约束。该约束是,Person
的 name
不能为空。
当 name
可以为空并且可能存在多个时会发生什么?
主要目标
DWM 旨在提供工具和方法来实现以下目标
- 提高具有复杂业务案例的源代码的可理解性
- 提高源代码和相关材料(如领域知识)的维护性
- 在长时间更改源代码时,减少错误和相关风险的数量
- 通过提供工具来简化主要知识相关任务,提高生产率。
领域
以下领域中,知识可以帮助软件开发。
Software <---------> PHP Classes
| ^
| |
| ,-------------->|
| / |
v / |
Domain v
Knowledge <--------> Database
单一真相点
单一事实点意味着有关您的领域相关信息只存储在一个地方。在这种情况下,我们假设我们的知识文件构成了这个单一的事实点。
将类似知识的信息放入JSON-LD文件(紧凑格式)。JSON-LD可以被很多人读取和写入,并且还允许转换为其他RDF序列化格式。当在文件中存储JSON-LD时,您还可以利用代码版本控制系统的功能(以更好地跟踪更改和比较状态)。
从知识到数据库,再到知识
DWM提供了一个基于一组数据库表生成知识的工具。我们这里所说的知识是一组类(每个表一个)及其相互之间的关系。您无需从零开始,只需将自动生成的知识作为起点即可。
在精炼您的知识时,您可能想生成SQL差异来保持数据库的更新。您可以使用bin/generateDBSchemaBasedOnKnowledge
来完成此操作(不完整,可能有错误,目前仅支持MySQL)。
使用bin/generateDBClassesFromKnowledge
来生成表示您的RDF类的PHP类。我们正在努力寻找一种方法,使用这些类来使数据库操作更安全。
使用流程模式组织操作
不要将所有代码都放在类中(面向对象风格),而是使用流程模式逐步组织操作。一个流程由一组给定顺序的步骤组成,并且应该在它表示一系列要运行的步骤时使用。流程是孤立的,不会互相调用。如果您有非线性代码,则不要使用流程。
使用静态分析工具
像PHPStan这样的工具有助于尽可能清晰地了解类型和类。它们可以在运行代码之前提前发现错误。此外,使用显式类型使用的代码在一般情况下更容易理解。
利用代码版本控制
将您的知识放入知识文件中,可以使它们包含到代码版本控制系统,如GIT。这样就可以轻松跟踪更改,并可以使用如GitHub的拉取请求等机制(以促进协作)。迁移操作也更容易,因为更改被跟踪,并且可以使用差异工具进行比较。
常见错误
Jena SHACL
java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer
如果预期为类型integer
的值是类型string
,则会发生此错误。
这是wrong
(检查sh:minCount
和sh:maxLength
)
{ "sh:path": { "@id": "dwm:givenName" }, "sh:datatype": { "@id": "xsd:string" }, "sh:minCount": "1", "sh:maxLength": "255" }
这是correct
{ "sh:path": { "@id": "dwm:givenName" }, "sh:datatype": { "@id": "xsd:string" }, "sh:minCount": 1, "sh:maxLength": 255 }