У меня есть абстрактный класс с именем ContentAbstract
, который выглядит примерно так
abstract class ContentAbstract
{
protected static $type;
protected $id;
protected $title;
protected $description;
protected $page;
protected $section;
...
function __construct($id = NULL, Page $page = NULL, Section $section = NULL)
{
if($id != NULL)
{
$data = get_data_from_content_table_by_id($id);
if($data['type'] == static::$type)
{
initialize_fields_with_data($data);
$this->page = fetch_page_object_from_registry($data['page_id']);
$this->section = fetch_section_object_from_registry($data['section_id']);
}
else
throw new IncompatibleContentTypeException('Foo');
}
else if($page != NULL && $section != NULL)
{
$this->page = $page;
$this->section = $section;
}
else
throw new OphanContentException('Foo');
}
}
Тогда класс Page
также является подклассом ContentAbstract
class Page extends ContentAbstract
{
protected static $type = 'Page';
private $template_file;
private $short_name;
static function newFromName($name)
{
$data = get_content_id_from_page_table_using_the_short_name($name);
$page = new Page($data['id']);
$page->template_file = $data['template_file'];
...
}
static function newFromID($id)
{
$data = get_content_id_from_page_table_using_the_ID($id);
$page = new Page($data['id']);
$page->template_file = $data['template_file'];
...
}
}
ТеперьМоя проблема заключается в том, что конструктор Page
является общедоступным, и пользователи могут сделать это:
$page = new Page($valid_page_id);
и в итоге вызовут ContentAbstract::__construct()
, но не смогут инициализировать данные для самой страницы (template_file
и short_name
), поскольку он был вызван вне Page::newFromName()
и Page::newFromID()
.Таким образом, я получаю полуготовые данные содержания .Одним из решений было бы переопределить родительский конструктор чем-то похожим на Page::newFromID()
, убедившись, что мы сможем установить все поля при создании экземпляра Page
(конечно, все еще вызывая родительский конструктор в Page::__construct()
).
Теперь проблема заключается в методе Page::newFromName()
, так как такой подход потребует от меня сделать 2 запроса, один из них - получить идентификатор содержимого страницы, используя столбец short_name
, а затем, когда конструкторстраница вызывается в Page::newFromName()
, затем она создает новый запрос для получения данных, связанных со страницей.Это не желательно, не так ли?
Так что единственное решение, которое я вижу, - это сделать Page::__construct()
частным и заставить конечных пользователей использовать статические методы для создания экземпляра объекта.
Мой вопросЭто то, что я хотел бы выпустить как проект с открытым исходным кодом, и это позволяет пользователям добавлять больше типов содержимого, просто создав подкласс класса ContentAbstract
.Требует ли частный конструктор вреда для указанной цели (учет человеческих ошибок и лени для чтения документации)?Или такие вопросы должны быть наименьшей из моих забот?Или структуры реальных классов сами по себе способствуют этой проблеме?