Quando cerchi la frase "i costruttori non devono lavorare", in vari post del blog troverai il consiglio di non lasciare che il costruttore lavori. Nonostante questo, ho qualche problema a capire perché questo è il caso. Inoltre, questo post popolare suggerisce di prendere tale consiglio con un tocco di sale.
Ho un esempio di due implementazioni della stessa situazione. Nella situazione, un AFactory ha un metodo createA , utilizzando un B . A ha bisogno di un risultato di una query, che B produce. Ci sono due modi per implementarlo:
Esempio 1:
class AFactory {
public function createA(B $b): A {
return new A($b->getQueryResult());
}
}
class A {
private $query_result;
public function __construct(array $query_result) {
$this->query_result = $query_result;
}
public function doFooWithQueryResult() {
// Do something with query result
}
public function doBarWithQueryResult() {
// Do something with query result
}
}
Nel primo esempio, la factory recupera il risultato della query e lo passa al costruttore di A . A quindi assegna semplicemente il risultato della query alla proprietà di classe corrispondente. Tuttavia, c'è un problema qui: A non verifica se il risultato della query è una struttura dati valida, cioè un risultato di query effettivo adatto per A . Non sa da dove viene. La responsabilità di questa convalida è ora trapelata al AFactory e A è diventata strettamente accoppiata a AFactory . L'altra implementazione risolve questo problema, ma in seguito il costruttore esegue il lavoro. E a quanto pare è male.
Esempio 2:
class AFactory {
public function createA(B $b): A {
return new A($b);
}
}
class A {
private $query_result;
public function __construct(B $b) {
$this->query_result = $b->getQueryResult();
}
public function doFooWithQueryResult() {
// Do something with query result
}
public function doBarWithQueryResult() {
// Do something with query result
}
}