Гм, у ваших подходов есть недостатки, независимо от того, какая версия.Во-первых, poly_base_Article выставляет поля, которые нарушают инкапсуляцию и, в первую очередь, побеждают цель использования ООП.
Далее, у вас есть точная инъекция через параметр $ _GET.Надлежащий способ сделать класс должен быть таким:
class poly_base_Article {
private $title;
private $author;
private $date;
private $category;
public function __construct($title, $author, $date, $category = 0) {
$this->title = $title;
$this->author = $author;
$this->date = $date;
$this->category = $category;
}
public function getTitle() { return $this->title;}
//...other getters defined here...
public function AsArray()
{
return (array) $this;
}
//this could be removed
public function write(poly_writer_Writer $writer) {
return $writer->write($this);
}
}
Метод write , похоже, не требуется, вы просто говорите автору писать объект напрямую.
Метод * call_tool * должен принадлежать службе или как фабричный метод для создания экземпляра poly_writer_Writer (кстати, вы должны изменить наименование классов и интерфейса на что-то более естественное), что-то вроде этого
class WriterFactory
{
public static function GetWriter($type='json')
{
switch($type)
{
case 'json'
case 'xml': $class= 'poly_writer_' . $type . 'Writer';
return new $class;
break;
default: throw new Exception("unsupported format: " . $type);
}
}
}
$article = new poly_base_Article('nPolymorphism', 'Steve', time(), 0);
$writer=WriterFactory::GetWriter(, $_GET['format']);
echo $writer->write($article);
Что является более безопасным, более стабильным, защищенным от несанкционированного доступа и пригодным для будущего (в отношении разработки кода).
Это зависит только от навыков и дисциплины разработчика.В этом конкретном случае код, который я написал, является более безопасным, защищенным от несанкционированного доступа и надежным на будущее: P
Обновление Действительно, я забыл поместить геттеры в poly_base_Article, я добавилих сейчас.Так как вы делаете сериализацию, статья не должна знать об этом, так как это не его ответственность (это часть уровня инфраструктуры), поэтому метод записи вообще не требуется, но здесь есть особый случай (все зависитв контексте).
WriterFactory - это в основном фабричный шаблон, который создает экземпляр модуля записи и возвращает абстракцию - это полиморфизм, в котором интерфейс полезен.Этот подход позволяет очень легко добавлять новые реализации интерфейса, а также защищать от внедрения кода. Переключатель должен проверять, разрешены ли только допустимые значения типа $.Вы можете проверить тип $ в других местах, но это единственное место, которое должно обрабатывать все, что связано с созданием писателей.Даже если вы хотите проверить вне его, вы просто создаете статический метод в WriterFactory, который будет возвращать true / false и использовать than.
Об интерфейсах, являющихся модой ... использование интерфейсов - это то, как ООП должно быть сделано.Лучше всего программировать против абстракции, а интерфейсы являются «лучшей» абстракцией.Проще говоря: если интерфейсы - это причуды, то ООП - это причуды.
О вашем втором примере, ну и первый тоже, метод, который создает писателя, не должен быть там во-первых, так как он соединяетсятворчество автора статьи и тех двоих не имеет ничего общего.Это нарушение SRP (принцип единой ответственности).
В этом конкретном случае, когда вы выполняете фабрику создания в отдельном классе, вам почти все равно, какие интерфейсы вам нужны, поскольку использование здесь очень упрощено, и вы используете PHP илиязык свободного типа.Если вы передадите писателя как зависимость, это поможет обойти интерфейс, а не реальную реализацию (как вы это делали в первом примере).Очень полезно знать, какой тип вы передаете.
Кроме того, на языке, подобном C #, у вас будет тип возврата, а затем, в качестве оптимального использования, вы вернете его как тип интерфейса (C #поддерживает динамические типы, которые, скажем, ведут себя немного как в PHP, так что вы можете возвращать динамические и не заботящиеся, но это приводит к снижению производительности, и если возвращенный тип не имеет вызванного метода, он выдаст исключение)