Ho avuto questo argomento per un po ', perché ho notato che alcune persone preferiscono il codice "leggibile" su uno correttamente strutturato. Quindi nell'esempio che sto mostrando, in pratica ho questa classe Mapper
in cui diverse istanze Mappable
sono iniettate e il Mapper usa le istanze per sapere come mappare alcuni dati. La domanda qui è, perché è una cattiva pratica farlo. Ho il sospetto che i problemi siano: il metodo è statico, la factory è nella classe sbagliata, rendendo il Mapper strettamente accoppiato alle classi Map
.
interface Mappable {
public function getMetaData();
public function setMetaData(array $metaData);
}
class BaseMap implements Mappable {
protected $metaData = [];
public function getMetaData() {
return $this->metaData;
}
public function setMetaData(array $metaData) {
$this->metaData = $metaData;
}
/**
* Possible Code Smell
*/
public static function getNewMapper() {
return new Mapper(new static);
}
}
class MapA extends BaseMap {
protected $metaData = [
'backField1' => 'frontField1',
'backField2' => 'frontField2'
];
}
class MapB extends BaseMap {
protected $metaData = [
'backFieldA' => 'frontFieldA',
'backFieldB' => 'frontFieldB'
];
}
class Mapper {
private $map;
public function __construct(Mappable $map) {
$this->setMap($map);
}
public function setMap(Mappable $map) {
$this->map = $map;
}
public function parseData($dataRow) {
$metaData = $this->map->getMetaData();
$parsedDataRow = [];
foreach($dataRow as $columnName => $columnValue) {
if(isset($metaData[$columnName]))
$parsedDataRow[$metaData[$columnName]] = $columnValue;
}
return $parsedDataRow;
}
}
// Probably correct
$mapper = new Mapper(new MapA());
print_r($mapper->parseData(['backField1' => 'foo1', 'backField2' => 'bar1']));
$mapper->setMap(new MapB());
print_r($mapper->parseData(['backFieldA' => 'fooA', 'backFieldB' => 'barB']));
// Possible Code Smell
print_r(MapA::getNewMapper()->parseData(['backField1' => 'foo1', 'backField2' => 'bar1']));
print_r(MapB::getNewMapper()->parseData(['backFieldA' => 'fooA', 'backFieldB' => 'barB']));
Schema di classe UML: