Eigenständige PHP-Bibliothek zum Generieren eines Builder-Musters aus einer Klasse.
Indem Sie Composer in Ihrem Projekt oder weltweit verwenden
composer require natitech/builder-generator
composer global require natitech/builder-generator
Sie können die Binärdatei verwenden, um einen Builder in der Nähe einer Klasse zu generieren:
/path/to/vendor/bin/generate-builder /path/to/class
ODER Sie können es in einem anderen PHP-Skript verwenden:
Nati BuilderGenerator FileBuilderGenerator:: create ()-> generateFrom ( ' /path/to/class ' );
Dadurch wird neben der erstellten Klasse eine Builder-Klasse generiert.
Beispiel :
//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 ());
}
Die Builder-Klasse muss möglicherweise Updates zu Codestil, Faker-Verwendungen, abgeleiteten Typen, Namespace usw. erhalten. Um die Produktion von ungenutztem Code zu vermeiden, gibt es außerdem keine Setter für Builder-Eigenschaften. Ihre IDE sollte das alles problemlos beheben können.
Der Generator versucht, Eigenschaftstypen (PHP-Typen, PHPDoc-Typen, Doctrine-ORM-Attribute oder Annotationen) zu erkennen und versucht, die entsprechende Faker-Methode basierend auf dem Typ und dem Namen der Eigenschaften zu erkennen.
Mit der Option --faker können Sie versuchen, die relevantesten Werte festzulegen. In diesem Fall wird Faker als Abhängigkeit der Builder-Klasse verwendet.
Es gibt viele Strategien zum Erstellen einer Klasse: öffentliche Eigenschaften, Setter (fließend oder nicht), Konstruktor. Im Folgenden finden Sie eine kurze Erklärung zu den einzelnen Strategien. Um sie vollständig zu verstehen, möchten Sie jedoch möglicherweise lieber die Unit-Tests lesen.
Standardmäßig versucht der Generator, die am häufigsten verwendete Strategie innerhalb der erstellten Klasse zu erkennen und diese für die gesamte Builder-Klasse zu verwenden. Wenn Sie Setter für alle Eigenschaften außer einer verwenden, verwendet der Generator Setter für Eigenschaften, die dies unterstützen, und ignoriert die Eigenschaft, die dies nicht unterstützt.
Sie können eine Strategie aber auch explizit mit der Option „--strategy“ übergeben.
Wenn Eigenschaften öffentlich sind. Siehe Beispiel oben.
Wenn Eigenschaften geschützt/privat sind und innerhalb der __construct-Methode festgelegt werden.
//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
);
}
}
Wenn Eigenschaften geschützt/privat sind, aber mit öffentlichen Settern festgelegt werden können. Die Setzer können fließend sein oder nicht.
//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 );
}
}
Dies ist eine weniger konventionelle Art, eine Klasse zu erstellen. In diesem Fall sind die Eigenschaften geschützt/privat und werden durch Methoden der öffentlichen Domäne festgelegt. Daher gibt es keine einfache Möglichkeit, die erstellte Klasse in einen bestimmten Zustand zu versetzen. Wenn Sie zu Testzwecken den Status dieses Objekts schnell Eigenschaften für Eigenschaften festlegen möchten, besteht eine Lösung darin, der erstellten Klasse eine statische build()-Methode hinzuzufügen.
//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
);
}
}
So erstellen Sie eine benutzerdefinierte Strategie:
NatiBuilderGeneratorPropertyPropertyBuildStrategy
implementieren und zu NatiBuilderGeneratorPropertyPropertyBuildStrategyCollection
hinzufügen. Dadurch wird entschieden, WIE Immobilien gebaut werden.NatiBuilderGeneratorAnalyzerBuildableClassAnalyzer::getWriteStrategies()
vervollständigen. Dies wird darüber entscheiden, WANN Immobilien mit dieser Strategie gebaut werden könnten. Sie können dieses Tool als externes Tool in Ihrer IDE verwenden.
Für PHPStorm-Benutzer siehe https://www.jetbrains.com/help/phpstorm/configuring-third-party-tools.html. Beispielkonfiguration: