Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在类内创建新对象_Php_Oop_Dependency Injection - Fatal编程技术网

Php 在类内创建新对象

Php 在类内创建新对象,php,oop,dependency-injection,Php,Oop,Dependency Injection,我还在学习OOP和依赖注入,还有一些东西我正在努力解决 下面是一个简单的类,它通过构造函数注入了一个单独的数据库类,并使用getAll方法从数据库返回所有项目。我知道DI是首选,也是最佳实践,因为它使类易于通过单元测试进行测试,并将其解耦,等等 class Articles { private $Database; public function __construct(Database $database) { $this->Database = $da

我还在学习OOP和依赖注入,还有一些东西我正在努力解决

下面是一个简单的类,它通过构造函数注入了一个单独的数据库类,并使用getAll方法从数据库返回所有项目。我知道DI是首选,也是最佳实践,因为它使类易于通过单元测试进行测试,并将其解耦,等等

class Articles {
    private $Database;

    public function __construct(Database $database) {
        $this->Database = $database;
    }
    public function getAll() {
        return $this->Database->query("SELECT * FROM Articles");
    }
}
但是,如果我想迭代数组中的所有这些项,并为另一个类中的每个项实例化一个新类,该怎么办?(在本例中,这将是一个新任务,然后将其放入任务队列中。)我可以注入队列类并重用它,但我不能注入任务类,因为我正在实例化它的多个实例,所以我当前直接在类内实例化它,而不注入它,这是不好的。像这样:

class Articles {
    private $Database;
    private $Queue;

    public function __construct(Database $database, Queue $queue) {
        $this->Database = $database;
        $this->Queue = $queue;
    }
    public function init() {
        $tasks = [];
        $articles = $this->getAll():
        foreach ($articles as $article) {
            $item = new Task($article);
            $tasks[] = $item;
        }
        $queue = $this->Queue($tasks);
    }
    public function getAll() {
        return $this->Database->query("SELECT * FROM Articles");
    }
}
那么,我如何实现我的愿望呢?我可以在控制器中实例化类,但这意味着当我希望在类的init方法中完成时,需要故意构建逻辑以向控制器公开iterable数组,以便将所有逻辑分组在一起


有什么想法吗?

如果任务只用于表示数据,那么它不会改变,也不需要注入数据

无论如何,问题的解决方案是使用
Builder
设计模式,注入Builder并使用它来构建对象

// Abstract class for the builder
abstract class BaseTaskBuilder {

abstract public function build();
}

//Concrete class for builder
class GreatTaskBuilder extends BaseTaskBuilder{
public function build() {
// return a new instance of GreatTask
}
}

// Abstract class for task
abstract class BaseTask{}

// Concrete class for task
class GreatTask extends BaseTask{}

因此,您所要做的就是注入构建器,就像您在代码中所做的那样。

我更喜欢保持我的模型干净

Article
是一种数据模型,在其中您可以使用常用的
CRUD
函数
update()
retrive()
delete()
insert
getAll()
getOne($id)

可以将
数据库
插入,但实际上不是
队列
,此时它实际上不是一个模型

您不应该在模型中构建任务和队列,而应该创建一个服务类来处理该流程,并在那里使用依赖项注入


这将使单元测试变得更容易

我认为您需要添加一个“列表”类或集合或任何您想调用的东西,它可以包含多个“任务”或“URL”或任何东西(不同的列表/集合/组)。通过这种方式,可以注入列表,并在运行时使用每个数据模型类型的单独实例填充列表。谢谢,您能否提供一个示例,说明在这种情况下服务类可能是什么样子的?但问题是否仍然存在,即我必须在类中实例化模型对象?