用于从类生成构建器模式的 PHP 独立库。
通过在您的项目或全局范围内使用 Composer
composer require natitech/builder-generator
composer global require natitech/builder-generator
您可以使用二进制文件在类附近生成构建器:
/path/to/vendor/bin/generate-builder /path/to/class
或者您可以在另一个 PHP 脚本中使用它:
Nati BuilderGenerator FileBuilderGenerator:: create ()-> generateFrom ( ' /path/to/class ' );
这将在构建类旁边生成一个构建器类。
例子 :
//From /path/to/MyClass.php file = the built class
class MyClass {
public int $ id ;
public string $ label ;
}
//This new file /path/to/MyClassBuilder.php will be generated = the builder class
class MyClassBuilder {
private int $ id ;
private string $ label ;
public function __construct ( Faker $ faker )
{
$ this -> id = $ faker -> number ();
$ this -> label = $ faker -> word ;
}
public function build (): MyClass
{
$ myClass = new MyClass ();
$ myClass -> id = $ this -> id ;
$ myClass -> label = $ this -> label ;
return $ myClass ;
}
//this will have to be generated by your IDE
public function withLabel ( string $ label ): self
{
$ this -> label = $ label ;
return $ this ;
}
}
//The ultimate goal is to use this in tests
/** @test */
public function canTestSomething ()
{
$ this -> assertEquals (
' test ' ,
$ this -> service -> something ( $ this -> myClass ()-> withLabel ( ' used in test ' )-> build ())
);
}
private function myClass (): MyClassBuilder
{
return new MyClassBuilder ( Faker Factory:: create ());
}
构建器类可能需要接收有关代码样式、faker 用法、推断类型、命名空间等的更新。此外,为了避免生成未使用的代码,构建器属性没有设置器。您的 IDE 应该能够轻松解决所有问题。
生成器将尝试检测属性类型(php 类型、phpdoc 类型、学说 orm 属性或注释),并尝试根据属性的类型和名称检测适当的 faker 方法。
您可以使用 --faker 选项来尝试设置最相关的值。在这种情况下,Faker 将用作构建器类的依赖项。
构建类的策略有很多:公共属性、setter(流畅或不流畅)、构造函数。下面给出了每种策略的简要说明,但您可能更喜欢阅读单元测试以完全理解它们。
默认情况下,生成器将尝试检测构建类中最常用的策略,并将其用于整个构建器类。如果您对除一个属性之外的所有属性使用 setter,则生成器将在支持它的属性上使用 setter,并忽略不支持的属性。
但您也可以使用“--strategy”选项显式传递策略。
当属性是公开的时。请参阅上面的示例。
当属性被保护/私有并在 __construct 方法内设置时。
//Built class
class MyClass {
private int $ id ;
public function __construct ( int $ id , private string $ label )
{
$ this -> id = $ id ;
}
}
//Builder class
class MyClassBuilder {
private int $ id ;
private string $ label ;
public function __construct ( Faker $ faker )
{
$ this -> id = $ faker -> number ();
$ this -> label = $ faker -> word ;
}
public function build (): MyClass
{
return new MyClass (
$ this -> id ,
$ this -> label
);
}
}
当属性是受保护/私有但可以使用公共设置器设置时。设置者可以流利,也可以不流利。
//Built class
class MyClass {
protected int $ id ;
protected string $ label ;
public function setId ( int $ id )
{
$ this -> id = $ id ;
return $ this ;
}
public function setLabel ( string $ label )
{
$ this -> label = $ label ;
return $ this ;
}
}
//Builder class
class MyClassBuilder {
private int $ id ;
private string $ label ;
public function __construct ( Faker $ faker )
{
$ this -> id = $ faker -> number ();
$ this -> label = $ faker -> word ;
}
public function build (): MyClass
{
return ( new MyClass ())
-> setId ( $ this -> id )
-> setLabel ( $ this -> label );
}
}
这是构建类的一种不太传统的方法。在这种情况下,属性是受保护/私有的,并由公共域方法设置。因此,没有简单的方法可以将构建的类设置为某种状态。如果出于测试目的,您希望能够通过属性快速设置该对象属性的状态,解决方案是在构建的类中添加静态 build() 方法。
//Built class
class MyClass {
private int $ id ;
private ? string $ label = null ;
public static function create ( int $ id ): self
{
$ myClass = new self ();
$ myClass -> id = $ id ;
return $ myClass ;
}
public function updateLabel ( string $ label ): self
{
$ this -> label = $ label ;
return $ this ;
}
//This method will have to be generated by you IDE from the builder class
//It allows you to hack the state of this object without relying on its public interface
public static function build ( int $ id , string $ label ): self
{
$ myClass = new self ();
$ myClass -> id = $ this -> id ;
$ myClass -> label = $ this -> label ;
return $ myClass ;
}
}
//Builder class
class MyClassBuilder {
private int $ id ;
private string $ label ;
public function __construct ( Faker $ faker )
{
$ this -> id = $ faker -> number ();
$ this -> label = $ faker -> word ;
}
public function build (): MyClass
{
return MyClass:: build (
$ this -> id ,
$ this -> label
);
}
}
创建自定义策略:
NatiBuilderGeneratorPropertyPropertyBuildStrategy
并将其添加到NatiBuilderGeneratorPropertyPropertyBuildStrategyCollection
。这将决定如何构建属性。NatiBuilderGeneratorAnalyzerBuildableClassAnalyzer::getWriteStrategies()
。这将决定何时可以使用此策略建造房产。 您可以将此工具用作 IDE 中的外部工具。
对于 PHPStorm 用户,请参阅 https://www.jetbrains.com/help/phpstorm/configuring-third-party-tools.html。配置示例: