用许多参数实例化类


Instantiating class with many parameters

我正在创建自己的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类(因为我想避免构造函数中有很多参数)。所以,我的问题是,如何创建这样一个类实例的最佳方法是什么?

提前感谢您的帮助。

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

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

请看下面我通常使用的一个想法的例子。它非常可靠,速度也相当快。如果你的框架有很多不同的类,并且你非常依赖这个功能,我强烈建议你实现一些从反射类缓存参数列表的方法。

<?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/

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