Nel mio attuale progetto sto rifattorizzando il codice per ottenere un DBAL. Ho un class Entity
che è la classe base per tutte le classi che modellano una tabella di database. Quindi ci sono diverse classi che ereditano da Entity
come Document
, Article
e così via.
abstract class Entity {
/** @var DatabaseRequest $dbReuest */
protected $dbRequest;
/** @var Login $login */
protected $login;
/* some methods like insert(), update(), JsonSerialize(), etc.
}
Poiché tutte queste classi hanno lo stesso costruttore __construct( DatabaseRequest $dbRequest, Login $login )
e non voglio gironzolare per quei due paramenter, ho anche fatto questo:
class EntityFactory {
public function __construct( DatabaseRequest $dbRequest, Login $login )
{
$this->dbRequest = $dbRequest;
$this->login = $login;
}
public function makeEntity( string $class )
{
if ( $this->extendsEntity( $class ) ) {
$reflection = new \ReflectionClass( $class );
$construct = $reflection->getConstructor();
$params = $construct->getParameters();
return new $class( clone $this->dbRequest, clone $this->login );
}
throw new APIException( "Class $class does not extend " . Entity::class, JsonResponse::DEBUG );
}
}
Chiami il metodo in questo modo: $factory->makeEntity( Document::class )
e questo ti darà un oggetto di quella classe.
In questo modo un cambiamento nel costruttore Entity
ha ridotto lo sforzo di refactoring al minimo. Tuttavia, in classe che estenda Entity
ho anche definito alcuni metodi per le relazioni tra le loro tabelle. Per esempio:.
class DocumentAddressee extends Entity {
/* ... */
public static function createFromCustomer( Address $address )
{
$self = new DocumentAddressee( clone $address->dbRequest, clone $address->login );
/* transferring data from Address to $self */
return $self;
}
}
(Secondo verraes.net questo è un uso legittimo di metodi statici come costruttivo).
E metodi come questi avvengono abbastanza spesso (approssimativamente 1-2 metodi per chiave esterna in una tabella). Ora mi piacerebbe mantenere quei metodi, perché posso facilmente accedere ai dati dipendenti in questo modo. Ma mi piacerebbe anche mantenere questi costruttori in fabbrica, quindi non devo rifattorizzare tutte le 100 classi Entity quando cambia il costrutto Entity (questo potrebbe accadere se decidessimo di usare un QueryBuilder in futuro.
Esiste già una sorta di best practice per gestire questi metodi? Dovrei gestire in modo propizio queste relazioni all'interno della fabbrica o modellare quelle relazioni in classi extra?