object-calisthenics/phpcs-calisthenics-rules

该包已被 弃用 并不再维护。作者建议使用 symplify/phpstan-rules 包。

PHP CodeSniffer 对象体操规则/sniffs

安装数: 2,455,977

依赖者: 47

建议者: 0

安全性: 0

星标: 606

关注者: 31

分支: 58

公开问题: 0

类型:phpcodesniffer-standard

v3.9.1 2020-09-08 10:18 UTC

README

已弃用:PHP_CodeSniffer 在处理空格和字符位置方面很棒。然而,这些规则关注的是代码架构和结构。2020年,有工具可以完美地实现这一点 - PHPStan.

话虽如此,对象体操 已作为 symplify/phpstan-rules 包中的 PHPStan 规则实现。请使用它 👇

includes:
    - vendor/symplify/phpstan-rules/packages/object-calisthenics/config/object-calisthenics-rules.neon
    - vendor/symplify/phpstan-rules/packages/object-calisthenics/config/object-calisthenics-services.neon



Downloads

对象体操是 面向对象代码中的一组规则,侧重于可维护性、可读性、可测试性和可理解性。我们 首先实用 - 它们可以一起使用或单独使用。

为什么你应该在你的项目中使用这个工具?

阅读 William Durand 的帖子查看 Guilherme Blanco 的演示

安装

composer require object-calisthenics/phpcs-calisthenics-rules --dev

使用方法

如果你知道你想要什么,可以直接跳转到具体的规则

如何快速检查 1 个规则?

PHP_CodeSniffer

vendor/bin/phpcs src tests -sp \
--standard=vendor/object-calisthenics/phpcs-calisthenics-rules/src/ObjectCalisthenics/ruleset.xml \
--sniffs=ObjectCalisthenics.Classes.ForbiddenPublicProperty

EasyCodingStandard

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\Classes\ForbiddenPublicPropertySniff: ~

然后

vendor/bin/ecs check src

实现的规则 Sniffs

1. 每个方法只使用 X 级别的缩进

foreach ($sniffGroups as $sniffGroup) {
    foreach ($sniffGroup as $sniffKey => $sniffClass) {
        if (! $sniffClass instanceof Sniff) {
            throw new InvalidClassTypeException;
        }
    }
}

👍

foreach ($sniffGroups as $sniffGroup) {
    $this->ensureIsAllInstanceOf($sniffGroup, Sniff::class);
}

// ...
private function ensureIsAllInstanceOf(array $objects, string $type)
{
    // ...
}

只使用此规则?

在 PHP_CodeSniffer 中

vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.Metrics.MaxNestingLevel

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\Metrics\MaxNestingLevelSniff: ~

🔧 可配置

在 PHP_CodeSniffer 中

<?xml version="1.0"?>
<ruleset name="my-project">
    <rule ref="ObjectCalisthenics.Metrics.MaxNestingLevel">
        <properties>
            <property name="maxNestingLevel" value="2"/>
        </properties>
    </rule>
</ruleset>

在 ECS 中

services:
    ObjectCalisthenics\Sniffs\Metrics\MaxNestingLevelSniff:
        maxNestingLevel: 2

2. 不要使用 "else" 关键字

if ($status === self::DONE) {
    $this->finish();
} else {
    $this->advance();
}

👍

if ($status === self::DONE) {
    $this->finish();
    return;
}

$this->advance();

只使用此规则?

在 PHP_CodeSniffer 中

vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.ControlStructures.NoElse

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\ControlStructures\NoElseSniff: ~

5. 仅在每个语句中使用一个对象操作符(《->》)

$this->container->getBuilder()->addDefinition(SniffRunner::class);

👍

$containerBuilder = $this->getContainerBuilder();
$containerBuilder->addDefinition(SniffRunner::class);

使用这个规则吗?

在 PHP_CodeSniffer 中

vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.CodeAnalysis.OneObjectOperatorPerLine

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\CodeAnalysis\OneObjectOperatorPerLineSniff: ~

🔧 可配置

在 PHP_CodeSniffer 中

<?xml version="1.0"?>
<ruleset name="my-project">
    <rule ref="ObjectCalisthenics.CodeAnalysis.OneObjectOperatorPerLine">
        <properties>
            <property name="variablesHoldingAFluentInterface" type="array" value="$queryBuilder,$containerBuilder"/>
            <property name="methodsStartingAFluentInterface" type="array" value="createQueryBuilder"/>
            <property name="methodsEndingAFluentInterface" type="array" value="execute,getQuery"/>
        </properties>
    </rule>
</ruleset>

在 ECS 中

services:
    ObjectCalisthenics\Sniffs\CodeAnalysis\OneObjectOperatorPerLineSniff:
        variablesHoldingAFluentInterface: ["$queryBuilder", "$containerBuilder"]
        methodsStartingAFluentInterface: ["createQueryBuilder"]
        methodsEndingAFluentInterface: ["execute", "getQuery"]

6. 不要缩写

这与类、特质、接口、常量、函数和变量名称有关。

class EM
{
    // ...
}

👍

class EntityMailer
{
    // ...
}

使用这个规则吗?

在 PHP_CodeSniffer 中

vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.NamingConventions.ElementNameMinimalLength

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\NamingConventions\ElementNameMinimalLengthSniff: ~

🔧 可配置

在 PHP_CodeSniffer 中

<?xml version="1.0"?>
<ruleset name="my-project">
    <rule ref="ObjectCalisthenics.NamingConventions.ElementNameMinimalLength">
        <properties>
            <property name="minLength" value="3"/>
            <property name="allowedShortNames" type="array" value="i,id,to,up"/>
        </properties>
    </rule>
</ruleset>

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\NamingConventions\ElementNameMinimalLengthSniff:
        minLength: 3
        allowedShortNames: ["i", "id", "to", "up"]

7. 保持你的类小型化

class SimpleStartupController
{
    // 300 lines of code
}

👍

class SimpleStartupController
{
    // 50 lines of code
}

class SomeClass
{
    public function simpleLogic()
    {
        // 30 lines of code
    }
}

👍

class SomeClass
{
    public function simpleLogic()
    {
        // 10 lines of code
    }
}

class SomeClass
{
    // 20 properties
}

👍

class SomeClass
{
    // 5 properties
}

class SomeClass
{
    // 20 methods
}

👍

class SomeClass
{
    // 5 methods
}

使用这个规则吗?

在 PHP_CodeSniffer 中

vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.Files.ClassTraitAndInterfaceLength,ObjectCalisthenics.Files.FunctionLength,ObjectCalisthenics.Metrics.MethodPerClassLimit,ObjectCalisthenics.Metrics.PropertyPerClassLimit

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\Files\ClassTraitAndInterfaceLengthSniff: ~
    ObjectCalisthenics\Sniffs\Files\FunctionLengthSniff: ~
    ObjectCalisthenics\Sniffs\Metrics\MethodPerClassLimitSniff: ~
    ObjectCalisthenics\Sniffs\Metrics\PropertyPerClassLimitSniff: ~

🔧 可配置

在 PHP_CodeSniffer 中

<?xml version="1.0"?>
<ruleset name="my-project">
    <rule ref="ObjectCalisthenics.Files.ClassTraitAndInterfaceLength">
        <properties>
            <property name="maxLength" value="200"/>
        </properties>
    </rule>
    <rule ref="ObjectCalisthenics.Files.FunctionLength">
        <properties>
            <property name="maxLength" value="20"/>
        </properties>
    </rule>
    <rule ref="ObjectCalisthenics.Metrics.PropertyPerClassLimit">
        <properties>
            <property name="maxCount" value="10"/>
        </properties>
    </rule>
    <rule ref="ObjectCalisthenics.Metrics.MethodPerClassLimit">
        <properties>
            <property name="maxCount" value="10"/>
        </properties>
    </rule>
</ruleset>

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\Files\ClassTraitAndInterfaceLengthSniff:
        maxLength: 200
    ObjectCalisthenics\Sniffs\Files\FunctionLengthSniff:
        maxLength: 20
    ObjectCalisthenics\Sniffs\Metrics\PropertyPerClassLimitSniff:
        maxCount: 10
    ObjectCalisthenics\Sniffs\Metrics\MethodPerClassLimitSniff:
        maxCount: 10

9. 不要使用获取器和设置器

这个规则部分与领域驱动设计相关。

  • 类不应包含公共属性。
  • 方法应该表示行为,而不是设置值。

class ImmutableBankAccount
{
    public $currency = 'USD';
    private $amount;

    public function setAmount(int $amount)
    {
        $this->amount = $amount;
    }
}

👍

class ImmutableBankAccount
{
    private $currency = 'USD';
    private $amount;

    public function withdrawAmount(int $withdrawnAmount)
    {
        $this->amount -= $withdrawnAmount;
    }
}

使用这个规则吗?

在 PHP_CodeSniffer 中

vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.Classes.ForbiddenPublicProperty,ObjectCalisthenics.NamingConventions.NoSetter

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\Classes\ForbiddenPublicPropertySniff: ~
    ObjectCalisthenics\Sniffs\NamingConventions\NoSetterSniff: ~

🔧 可配置

在 PHP_CodeSniffer 中

<?xml version="1.0"?>
<ruleset name="my-project">
    <rule ref="ObjectCalisthenics.NamingConventions.NoSetter">
        <properties>
            <property name="allowedClasses" type="array" value="*\DataObject"/>
        </properties>
    </rule>
</ruleset>

在 ECS 中

# ecs.yaml
services:
    ObjectCalisthenics\Sniffs\NamingConventions\NoSetterSniff:
        allowedClasses: 
            - '*\DataObject'

未实施规则 - 过于严格、模糊或令人烦恼

在实际使用中,我们发现这些规则过于严格、模糊或甚至令人烦恼,而不是帮助编写更干净、更实用的代码。它们也与领域驱动设计密切相关。

3. 包装原始类型和字符串 - 自PHP 7以来,您可以使用define(strict_types=1)和标量类型提示。对于其他情况,例如电子邮件,您可以在您的中处理。

4. 使用一等集合 - 这个规则很有意义,但在实践中过于严格,没有实际用途。即使我们的代码也完全无法通过它。

8. 不要使用具有两个以上实例变量的类 - 这取决于每个项目的具体领域。为这个制定规则没有意义。

贡献的3个规则

  • 每个PR一个特性

  • 每个新特性都必须由测试来覆盖

  • 所有测试样式检查必须通过

    composer complete-check

那时我们将很乐意合并您的功能。