弃用:php_codesniffer非常适合处理空间和char位置。然而,这些规则是关于代码架构和结构的。在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
对象健美操是面向对象的代码中的一组规则,其重点是可维护性,可读性,可检验性和可理解性。我们首先是务实的- 它们易于一起使用或一个一个一个。
阅读威廉·杜兰德(William Durand)的帖子,或查看Guilherme Blanco的演讲。
composer require object-calisthenics/phpcs-calisthenics-rules --dev如果您知道想要什么,请直接跳到特定规则:
在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 :
ObjectCalisthenicsSniffsClassesForbiddenPublicPropertySniff : ~然后
vendor/bin/ecs check srcX缩进水平 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 :
ObjectCalisthenicsSniffsMetricsMaxNestingLevelSniff : ~ 在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 :
ObjectCalisthenicsSniffsMetricsMaxNestingLevelSniff :
maxNestingLevel : 2 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 :
ObjectCalisthenicsSniffsControlStructuresNoElseSniff : ~-> ) $ 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 :
ObjectCalisthenicsSniffsCodeAnalysisOneObjectOperatorPerLineSniff : ~ 在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 :
ObjectCalisthenicsSniffsCodeAnalysisOneObjectOperatorPerLineSniff :
variablesHoldingAFluentInterface : ["$queryBuilder", "$containerBuilder"]
methodsStartingAFluentInterface : ["createQueryBuilder"]
methodsEndingAFluentInterface : ["execute", "getQuery"]这与类,性状,界面,常数,功能和可变名称有关。
class EM
{
// ...
}?
class EntityMailer
{
// ...
}在php_codesniffer中:
vendor/bin/phpcs ... --sniffs=ObjectCalisthenics.NamingConventions.ElementNameMinimalLength在ECS中:
# ecs.yaml
services :
ObjectCalisthenicsSniffsNamingConventionsElementNameMinimalLengthSniff : ~ 在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 :
ObjectCalisthenicsSniffsNamingConventionsElementNameMinimalLengthSniff :
minLength : 3
allowedShortNames : ["i", "id", "to", "up"] 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 :
ObjectCalisthenicsSniffsFilesClassTraitAndInterfaceLengthSniff : ~
ObjectCalisthenicsSniffsFilesFunctionLengthSniff : ~
ObjectCalisthenicsSniffsMetricsMethodPerClassLimitSniff : ~
ObjectCalisthenicsSniffsMetricsPropertyPerClassLimitSniff : ~ 在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 :
ObjectCalisthenicsSniffsFilesClassTraitAndInterfaceLengthSniff :
maxLength : 200
ObjectCalisthenicsSniffsFilesFunctionLengthSniff :
maxLength : 20
ObjectCalisthenicsSniffsMetricsPropertyPerClassLimitSniff :
maxCount : 10
ObjectCalisthenicsSniffsMetricsMethodPerClassLimitSniff :
maxCount : 10该规则与域驱动的设计部分相关。
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 :
ObjectCalisthenicsSniffsClassesForbiddenPublicPropertySniff : ~
ObjectCalisthenicsSniffsNamingConventionsNoSetterSniff : ~ 在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 :
ObjectCalisthenicsSniffsNamingConventionsNoSetterSniff :
allowedClasses :
- ' *DataObject '在实践中使用时,我们发现这些规则太严格,模糊甚至烦人,而不是帮助编写更清洁和更务实的代码。它们也与域驱动的设计密切相关。
3。包装原始类型和字符串- 自PHP 7以来,您可以使用define(strict_types=1)和标量类型提示。对于其他情况,例如电子邮件,您可以通过价值对象在域中处理。
4.使用头等舱收藏- 此规则很有意义,但是太严格了,无法在实践中有用。甚至我们的代码根本没有通过它。
8。请勿使用具有两个以上实例变量的类- 这取决于每个项目的各个域。为此制定规则是没有意义的。
每公关1个功能
每个新功能都必须涵盖测试
所有测试和样式检查必须通过
composer complete-check然后,我们很乐意合并您的功能。