私はその後Page
クラスもContentAbstract
PHPデザインパターン:他の人に拡張させるクラスではプライベートコンストラクタが悪いですか?
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'];
...
}
}
のサブクラスであるこの
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');
}
}
のようになりますContentAbstract
と呼ばれる抽象クラスを持っている今、私の問題はPage
コンストラクタがあるという事実にあります一般ユーザーとユーザーはこれを行うことができます:
$page = new Page($valid_page_id);
Page::newFromName()
およびPage::newFromID()
の外部で呼び出されたため、ContentAbstract::__construct()
を呼び出すことになりましたが、ページ自体のデータ(template_file
およびshort_name
)を初期化できませんでした。だから私は半分のコンテンツデータで終わる。 1つの解決策は、親コンストラクタをPage::newFromID()
に似たものでオーバーライドし、Page
がインスタンス化されたときに(もちろん、親コンストラクタをPage::__construct()
の中で呼び出すことによって)すべてのフィールドを設定できるようにすることです。
この問題は、short_name
列を使用してページのコンテンツIDを取得することと、ページのコンストラクタが呼び出されたときに2つのクエリを作成する必要があるため、Page::newFromName()
メソッドにあります。 Page::newFromName()
と入力すると、ページに関連付けられたデータを取得するための新しいクエリが作成されます。それは望ましくないですね。
私が見る唯一の解決策は、Page::__construct()
を非公開にして、エンドユーザーにオブジェクトをインスタンス化する静的メソッドを使用させることです。
私はオープンソースプロジェクトとしてリリースしたいと考えています。ユーザーはContentAbstract
クラスをサブクラス化するだけで、より多くの種類のコンテンツを追加できます。個人的なコンストラクタが上記の目的に有害であることを要求しているか(人間の誤りとドキュメンテーションを読むための怠惰を説明する)?あるいは、そのようなことが私の懸念事項の中で最も少ないのでしょうか?あるいは、実際のクラスそのものの構造自体がこの問題に役立っていますか?
Ahhhh ...しかし、クラスそのものからコンストラクタが呼び出されたかどうかはどのようにわかりますか? –
私はあなたがしたいことを誤って読んでいたので、私の提案は間違っていました。誰かを混乱させないように、私はその問題に関する私のコメントを削除しました! – rdlowrey