gpt4 book ai didi

PHP 设计模式 : Are private constructors bad for classes that you will let others to extend?

转载 作者:可可西里 更新时间:2023-10-31 23:49:57 26 4
gpt4 key购买 nike

我有一个名为 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 构造函数是公共(public)的,用户可以这样做:

$page = new Page($valid_page_id);

并最终调用 ContentAbstract::__construct() 但无法初始化页面本身的数据(template_fileshort_name) 因为它是在 Page::newFromName()Page::newFromID() 之外调用的。所以我最终得到了一个半生不熟的内容数据。一种解决方案是使用类似于 Page::newFromID() 的方法覆盖父构造函数,确保我们能够在实例化 Page 时设置所有字段(当然,仍然通过在 Page::__construct()) 中调用父构造函数。

现在问题出在 Page::newFromName() 方法中,因为这种方法需要我进行 2 个查询,一个是使用 获取页面的内容 ID short_name 列,然后当在 Page::newFromName() 中调用页面构造函数时,它将创建一个新查询以获取与页面关联的数据。这是不可取的,不是吗?

所以我看到的唯一解决方案是将 Page::__construct() 设为私有(private)并强制最终用户使用静态方法来实例化对象。

我的问题是,这是我想作为开源项目发布的东西,它允许用户通过简单地子类化 ContentAbstract 类来添加更多类型的内容。要求私有(private)构造函数是否不利于上述目标(考虑到人为错误和懒惰阅读文档)?或者这些事情应该是我最不关心的?还是实际类的结构本身导致了这个问题?

最佳答案

“现在我的问题在于 Page 构造函数是公共(public)的,用户可以这样做:

$page = new Page($valid_page_id);"

根据您在 OP 中发布的代码,情况并非如此。您的页面在构造所在的位置扩展了 ContentAbstract,但您实际上并没有从 Page 类调用构造。您将不得不强制 child 给 parent 打电话:

class Page extends Content // I wouldn't name this abstract as it may change in the future
{
public function __construct($args)
{
// Here I forced a call to parent
// If I comment this out, the parent construct will never be accessed
parent::__construct($args);
}
}

关于PHP 设计模式 : Are private constructors bad for classes that you will let others to extend?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8440848/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com