使用Dependancy Injection和共享变量的PHP设计模式?

时间:2015-06-12 08:31:35

标签: php oop design-patterns dependency-injection

我将尝试尽可能地解释这一点,请原谅我,如果部分没有完全合理。我正在构建一个用于教育目的的PHP库/框架。我正在使用单例模式构建它但遇到了一些问题,最近似乎也读到它不应该被使用,因为它不是非常可测试的(虽然我并不担心这是可测试的,但我想学习如何做到这一点),而应该使用依赖注入。

我想要的是一个共享变量,如果你愿意的话,它包含许多不同的类。例如$ app->数据库; $ APP->图; $ APP->会议;等等,我不确定我是否正确行事。所有课程也都是自动加载的。

我有bootstrap / start.php初始化主变量(有这个名字吗?):

$app = new App(new Database, new Views, new Session);

在我主要使用的App.php类中:

 public $database;
 public $views;
 public $session

public function __construct(Client $client, Views $views, Session $session)
{
     $this->database = $database;
     $this->views = $views;
     $this->session = $session;
}

我的问题是:我应该像这样初始化构造函数中的所有类吗?最重要的是...如何在我的Views.php类中使用$ database变量而不创建可能会覆盖Database类中某些属性的全新实例?

非常感谢对此的一些见解。

2 个答案:

答案 0 :(得分:1)

你应该真正了解类似MVC的架构,它们所基于的整个点称为关注点分离(SoC)。

为什么要在视图中访问数据库连接?显然是因为您想要执行查询并在那里显示结果。这就是打破SoC的原因。为了显示数据,你必须访问模型中的数据库连接,如果需要,以某种方式解析,然后简单地将准备好的数组传递给视图,这样视图甚至不知道数据库存在这样的东西,他们只知道有一个数组,需要以某种方式显示。这种方法引入了一个主要优点 - 您可以轻松交换数据库引擎(使用SOAP / REST,Mongo等),而无需触及视图!

至于你的问题,你可以通过创建一个抽象类来解决这个问题,这个抽象类将被称为AbstractApplication并将所有那些初始化逻辑放在那里。然后你可以简单地继承这个基类。

您拥有的另一种方式是使用所谓的服务定位器来接近它。您创建一个包装器,将所有依赖项放在那里,然后只需为需要它的类注入Service Locator。这不是最好的方法,但它是处理大量依赖项的唯一方法(在现实世界中,你需要注入4个以上的参数)

答案 1 :(得分:-1)

您的代码看起来不错,但我会推荐这些更改,将变量设为私有并生成getter和setter。

<?php
Class App {

private $database;
private $views;
private $client;
private $session;

/**
 * 
 * @param type $database
 * @param type $views
 * @param type $client
 * @param type $session
 */
function __construct($database, $views, $client, $session) {
    $this->database = new $database;
    $this->views = new $views;
    $this->client = new $client;
    $this->session = new $session;
}

/**
 * 
 * @return type
 */
function getDatabase() {
    return $this->database;
}

/**
 * 
 * @return type
 */
function getViews() {
    return $this->views;
}

/**
 * 
 * @return type
 */
function getClient() {
    return $this->client;
}

/**
 * 
 * @return type
 */
function getSession() {
    return $this->session;
}

/**
 * 
 * @param type $database
 */
function setDatabase($database) {
    $this->database = $database;
}

/**
 * 
 * @param type $views
 */
function setViews($views) {
    $this->views = $views;
}

/**
 * 
 * @param type $client
 */
function setClient($client) {
    $this->client = $client;
}


/**
 * 
 * @param type $session
 */
function setSession($session) {
    $this->session = $session;
}

}
//and in bootstrap or where you loading just do this and make database, view and all other singleton.
$database = database::getInstance();
$views = views::getInstance();
$client = client::getInstance();
$session = session::getInstance();
$App = new App($database, $views, $client, $session);