棄用: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然後,我們很樂意合併您的功能。