【问题标题】:Instantiating class with many parameters实例化具有许多参数的类
【发布时间】:2013-06-24 14:23:25
【问题描述】:

我正在创建自己的 MVC 框架,只是为了学习一些新东西,最近遇到了这个问题。 假设我有这样的:

Class Post extends \application\BaseClass
{
    private $objPostDetail = null;
    private $objAuthor = null
    private $objCategory = null;
    private $objType = null;
    private $objTitlePicture = null;

    public function __construct(PostDetail $objPostDetail,
                                Author $objAuthor, 
                                Category $objCategory, 
                                Type $objType, 
                                TitlePicture $objTitlePicture)
    {
        $this->objPostDetail = $objPostDetail;
        $this->objAuthor = $objAuthor;
        $this->objCategory = $objCategory;
        $this->objType = $objType;
        $this->objTitlePicture = $objTitlePicture;
    }
}

那么构造函数中使用的一些对象也可以复杂地创建。 我从 PostDAO 类中获取数据,该类返回数据数组。 现在的问题是如何创建这个类的新实例,因为它可能在应用程序的许多地方。 我认为到处创建 $objAuthor,然后 $objCategory 等最终创建 $objPost 并不好。所以我创建了我认为可能被称为工厂的东西:

Class PostFactory extends \application\BaseFactory
{
    private $arrData = null;
    private $objPostDetail = null;
    private $objCategory = null;
    private $objType = null;
    private $objTitlePicture = null;

    public function __construct($arrData)
    {
        $this->arrData = $arrData;
    }

    public function build()
    {
        $this->objPostDetail = $this->buildPostDetail();
        $this->objCategory = $this->buildCategory();
        $this->objType = $this->buildType();
        $this->objTitlePicture = $this->buildTitlePicture();

        return $this->buildPost();
    }

    private function buildPostDetail()
    {
        $objPostDetail = new \includes\classes\factories\PostDetailFactory($this->arrData);
        return $objPostDetail->build();
    }

    private function buildCategory()
    {
        $objCategory = new \includes\classes\factories\CategoryFactory($this->arrData);
        return $objCategory->build();
    }

    private function buildType()
    {
        $objType = new \includes\classes\factories\TypeFactory($this->arrData);
        return $objType->build();
    }

    private function buildTitlePicture()
    {
        $objTitlePicture = new \includes\classes\factories\TitlePictureFactory($this->arrData);
        return $objTitlePicture->build();
    }

    private function buildPost()
    {
        return new \includes\classes\Post($this->objPostDetail, $this->objCategory,
                        $this->objType, $this->objTitlePicture);
    }
}

效果很好,但我不喜欢我有两倍多的类,而且我不知道实例化 Post 需要什么参数,因为我将数组传递给 Factory 类(因为我想避免很多参数在构造函数中)。 那么,我的问题是如何创建这样的类实例的最佳方法是什么?

提前感谢您的帮助。

【问题讨论】:

    标签: php instantiation factory


    【解决方案1】:

    如果你想创建自己的 MVC 框架,我强烈建议从某种“容器”开始,它包含服务类的实例(只需要初始化一次的类,例如请求或响应)。

    使用反射类通过迭代构造函数的函数参数来自动注入构造函数所需的参数。

    请参阅以下我通常使用的想法的示例。它非常可靠且速度相当快。如果您的框架有很多不同的类,并且您非常依赖此功能,我强烈建议您实现某种方法来缓存反射类中的参数列表。

    <?php
    class SomeClass
    {
        public function __construct(Request $request, Response $response, $title = '')
        {
            echo get_class($request);
            // will output "Request"
    
            echo $title;
            // will output "Hello World"
        }
    }
    
    // This function will handle the dynamic dependency injection to make sure the constructor gets the arguments passed that it needs, with optional named arguments passing.
    $some_class = YourFrameworkDispatcherClass->createInstance('SomeClass', array('title' => 'Hello World'));
    ?>
    

    我实际上已经在我的博客上写了一篇关于此的博文。 http://harold.info/engineering/php-dynamic-dependency-injection/

    我认为这可以帮助您解决这个结构性问题。

    【讨论】:

    • 我的问题是我从模型中获取数据后如何创建一个对象,我知道如何将它传递给模型,因为它通常是很少的参数。
    • 好吧,那么同样的解决方案也适用。你已经知道你从模型中得到了什么。如我的博客文章中所述,以命名参数样式使用它。只需将构造函数的参数命名为与模型相同的名称,它就会自动传递给构造函数;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多