繁体   English   中英

从另一个类内部调用PHP类?

[英]Calling PHP class from inside another class?

我正在建立小型MVC,并希望解决一些疑问。

我有调度程序类,该类需要HTTP请求,HTTP响应和路由器类。

我可以使用依赖注入来做到这一点,例如:

$dispatcher = new Dispatcher($request, $response, $router);

现在说我不喜欢这种方法,并且想在Dispatcher类中使用这样的类:

class Dispatcher()
{
    protected $request;
    protected $response;
    protected $router;

    public function __construct()
    {
        $this->request = new Request();
        $this->response = new Response();
        $this->router = new Router();
    }
}

2方法有问题吗? 我是否违反了一些OOP原则? 或者以这种方式使用它就好了吗?

很难说一种方法或另一种方法有什么问题 如果它不符合要求的规格,那是错误的。

之所以选择第一种方法而不是第二种方法,是因为它使您可以灵活地注射。 例如:

class Dispatcher {
   private $req;
   public function __construct(IRequest $req) {
      $this->req = $req;
   }
}
interface IRequest {}
class Request implements IRequest {}
class MockRequest implements IRequest {}

//PRODUCTION
new Dispatcher(new Request);
//TESTING
new Dispatcher(new MockRequest);

您应该浏览一下DI是有原因的:依赖关系注入从代码中删除依赖关系,并将其抽象给调用方。 这也使对代码进行单元测试变得更加容易,因为代码天生就不需要外部依赖来起作用。

在一个示例中最好地证明了这一点。 想象一下您的班级是否需要数据库连接:

class Dispatcher()
{
    protected $db

    public function __construct() {
        $this->db = new MysqlDB();
    }
}

现在,您只是强迫所有人使用MySQL数据库。 但是,如果您使用了DI,则可以抽象出数据库的详细信息,而仅依赖于代表数据库对象的某个类:

class Dispatcher()
{
    protected $db

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

然后,定义一些代表不同数据库连接的对象:

interface Database {
    public function query( $sql);
}

class MySQLDB implements Database {
    public function query( $sql) { // Stuff for MySQL 
    }
}

class OracleDB implements Database {
    public function query( $sql) { // Stuff for Oracle 
    }
}

现在,无论您的用户是否这样做:

$dispatcher = new Dispatcher( new MysqlDB());

要么:

$dispatcher = new Dispatcher( new OracleDB());

没关系-相同的类可以在两个数据库中重用。

第二个示例导致Dispatcher类与其使用的所有3类之间的紧密耦合。 如果您正在寻找被其违反的特定法律或原则,那将是开放/封闭的原则

PS:确定要使用事件驱动的体系结构吗? 因为那是我发现Dispatcher提到的唯一上下文

第二个示例应该以Factory后缀调用,因为它创建了其他对象。

在两个示例中,您最终都将获得一个高耦合的Dispatcher对象( Dependency inversion

分派器应该只能够询问其他对象实现/注册到的接口或服务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM