06/2016 / Milan "perún" Herda / @moriquend / prezentacie.perunhq.org
Príklady prebrané z knihy Principles of Package DesignSkratka predstavujúca 5 základných princípov dobrého softvérového návrhu
Trieda by mala byť otvorená pre rozširovanie a zároveň uzatvorená pre zmeny
switch
)new
class GenericEncoder
{
public function encodeToFormat(array $data, $format)
{
if ($format == 'json') {
$encoder = new JsonEncoder();
) else if ($format == 'xml') {
$encoder = new XmlEncoder();
} else {
throw new InvalidArgumentException(sprintf('Unknown format %s', $format));
}
$data = $this->prepareData($data, $format);
return $encoder->encode($data);
}
private function prepareData(array $data, $format)
{
switch ($format) {
case 'json':
$data = $this->forceArray($data);
$data = $this->fixKeys($data);
break;
case 'xml':
$data = $this->fixAttributes($data);
break;
default:
throw new InvalidArgumentException(sprintf('Unknown format %s', $format));
}
return $data;
}
Pridajte do triedy podporu pre kódovanie do YAML
GenericEncoder robí priveľa vecí
Rozdelíme rozdpovednosti podľa Single Responsibility Principle
class EncoderFactory
{
/**
* @param string $format
*
* @return EncoderInterface
*/
public function createForFormat(string $format)
{
if ($format == 'json') {
return new JsonEncoder();
} else if ($format == 'xml') {
return new XmlEncoder();
}
throw new InvalidArgumentException(sprintf('Unknown format %s', $format));
}
interface EncoderInterface
{
/**
* @param array $data
*
* @return string
*/
public function encode(array $data);
}
class JsonEncoder implements EncoderInterface {}
class XmlEncoder implements EncoderInterface {}
interface EncoderFactoryInterface
{
/**
* @param string $format
*
* @return EncoderInterface
*/
public function createForFormat(string $format);
}
class EncoderFactory implements EncoderFactoryInterface {}
class GenericEncoder
{
private $encoderFactory;
public function __construct(EncoderFactoryInterface $encoderFactory)
{
$this->encoderFactory = $encoderFactory;
}
}
class EncoderFactory implements EncoderFactoryInterface
{
private $factories = [];
public function registerEncoderFactory($format, callable $factory)
{
$this->factories[$format] = $factory;
return $this;
}
public function createForFormat($format)
{
if (!array_key_exists($format, $this->factories)) {
throw new InvalidArgumentException(sprintf('Unknown format %s', $format));
}
$factory = $this->factories[$format];
$encoder = $factory();
return $encoder;
}
}
class JsonEncoder implements EncoderInterface
{
/**
* @param array $data
*
* @return string
*/
public function encode(array $data)
{
$this->prepareData($data);
return json_encode($data);
}
// ...
}
$data = [/* ... */];
$encoderFactory = new EncoderFactory();
$encoderFactory->addEncoderFactory('json', function () {
return new JsonEncoder();
});
$encoderFactory->addEncoderFactory('json', function () {
return new XmlEncoder();
});
$genericEncoder = new GenericEncoder($encoderFactory);
$genericEncoder->encodeToFormat($data, 'json');