承接 alephtools/ddd 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

alephtools/ddd

Composer 安装命令:

composer require alephtools/ddd

包简介

Helpful instruments for Domain Driven Design.

README 文档

README

Collection of classes that can be useful to build applications according to Domain Driven Design (DDD).

Table of Contents

Base Domain Classes

DTO

The base class of all domain objects is DTO. DTO allows to embed properties (as in JAVA, C# and some other strictly-typed program languages) in our classes. A class property consists of three elements:

  1. Private or protected class field.
  2. Property description according to PHPDoc (@property) at the class comment.
  3. Optional setter or getter.

DTO is an abstract class. There are two child classes of it: StrictDto and WeakDto. The difference between them is that the first one throws NonExistentPropertyException during class initialization if a property does not exist and the second one isn't.

DTO usage example:

/**
 * @property string $prop1
 * @property-read DateTime $prop2
 * @property-write int $prop3
 */
class Data extends StrictDto
{
    private $prop1;
    private DateTime $prop2;
    protected int $prop3 = 0;
    
    public function setProp1(string $value): void
    {
        $this->prop1 = $value;
    }
    
    protected function setProp2(?DateTime $value): void
    {
        $this->prop2 = $value;
    }
    
    public function getProp2(): array
    {
        return $this->prop2 ?: new DateTime();
    }
}

$dto = new Data([
    'prop1' => 'abc',
    'prop2' => null,
    'prop3' => 10,
    'prop4' => 1 // causes NonExistentPropertyException for StrictDto but not for WeakDto.
]);

$val1 = $dto->prop1; // abc
$val2 = $dto->prop2; // current time object
$dto->prop3 = 100;
$val3 = $dto->prop3  // throws RuntimeException
$dto->prop4 = 1      // throws NonExistentPropertyException

$dtoAsArray = $dto->toArray(); // you can use toNestedArray() if some properties are DTO themselves.
$dtoAsJson = json_encode($dto); // or use $dto->toJson()
$dtoAsString = (string)$dto // or use $dto->toString() 

There are some rules to get properties work properly:

  • The property type in PHPDoc comment does not matter. To restrict property by type you need to specify type hinting for property setter, getter or field. If assigned value does not match property type InvalidArgumentException is thrown.
  • Getters of read-only or regular properties must be public.
  • Setters of write-only or regular properties must be public.
  • Private and protected setters are automatically invoked during the class initialization.
  • If you want to inherit a property its field and setter must not be private.

DomainObject

DomainObject is a base class for all domain object. It is inherited from StrictDto. All domain objects contains sone useful methods:

  1. equals() to compare domain objects with others.
  2. copy() to create a copy of the domain object.
  3. copyWith() to create a copy of the domain object with the given property values.
  4. hash() to get unique domain object hash.
  5. domainName() to get name of the domain object (it equals class name by default).

ValueObject

ValueObject is a base class for all domain value objects. It has the same methods as DomainObject.

SQL Builder

SQL Builder is a simple wrapper that allows to build SQL query string for some particular RDBMS (MySQL and PostgreSQL are currently only supported). You can use it to be independent of any PHP framework. See the table below to figure out how to use SQL Builder.

MySQL

Select Queries

PHP Expression:

$row = (new SelectQuery($queryExecutor))
    ->from('users', 'u')
    ->where('u.id', '=', 10)
    ->row();
    
// $row is a single record (associative array) or empty array.

Executed SQL Query:

SELECT * FROM users u 
WHERE u.id = 10

PHP Expression:

$rows = (new SelectQuery($queryExecutor))
    ->from('users')
    ->select([
        'id',
        'firstName',
        'lastName',
        'email'
    ])
    ->where('email', 'LIKE', '%gmail.com')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array. 

Executed SQL Query:

SELECT id, firstName, lastName, email FROM users 
WHERE email LIKE '%gmail.com'

PHP Expression:

$rows = (new SelectQuery($queryExecutor))
    ->from([
        'users' => 'u,
        'contacts' => 'c'
    ])
    ->select([
        'u.id' => 'user_id',
        'c.id' => 'contact_id'
    ])
    ->where('c.user_id = u.id')
    ->limit(10)
    ->offset(50)
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

Executed SQL Query:

SELECT u.id user_id, c.id contact_id FROM users u, contacts c 
WHERE c.user_id = u.id 
LIMIT 10 OFFSET 50

PHP Expression:

$rows = (new SelectQuery($queryExecutor))
    ->from('users', 'u)
    ->from('contacts', 'c')
    ->select('u.id', 'user_id')
    ->select('c.id', 'contact_id')
    ->where('c.user_id = u.id')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

Executed SQL Query:

SELECT u.id user_id, c.id contact_id FROM users u, contacts c 
WHERE c.user_id = u.id

PHP Expression:

$rows = (new SelectQuery($queryExecutor))
    ->from('users')
    ->orderBy('email', 'DESC')
    ->orderBy('id', 'ASC')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

Executed SQL Query:

SELECT * FROM users
ORDER BY email DESC, id ASC 

PHP Expression:

$count = (new SelectQuery($queryExecutor))
    ->from('users u')
    ->leftJoin('contacts c', 'c.user_id = u.id')
    ->where('u.id', '=', 5)
    ->count('DISTINCT c.name');
    
// $count is an integer value.

Executed SQL Query:

SELECT COUNT(DISTINCT c.name) FROM users u
LEFT JOIN contacts c ON c.user_id = u.id
WHERE u.id = 5

PHP Expression:

$count = (new SelectQuery($queryExecutor))
    ->from('users u')
    ->innerJoin('contacts c', 'c.user_id = u.id')
    ->select([
        'u.id', 
        'u.email'
    ])
    ->select('COUNT(c.id)', 'contact_number')
    ->groupBy('u.id')
    ->rows();
    
// $rows is a record set (array of associative arrays) or empty array.

Executed SQL Query:

SELECT i.id, u.email, COUNT(c.id) contact_number FROM users u
INNER JOIN contacts c ON c.user_id = u.id
GROUP BY u.id

PostgreSQL

alephtools/ddd 适用场景与选型建议

alephtools/ddd 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 26.63k 次下载、GitHub Stars 达 9, 最近一次更新时间为 2018 年 11 月 12 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「ddd」 「clean architecture」 「Aleph」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 alephtools/ddd 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 alephtools/ddd 我们能提供哪些服务?
定制开发 / 二次开发

基于 alephtools/ddd 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 26.63k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 9
  • 点击次数: 24
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 9
  • Watchers: 2
  • Forks: 10
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2018-11-12