php – 单身人士和服务定位器的真正替代品?

我正在努力提高我的编程技巧,我遇到了一个令人沮丧的问题,最好用一个例子来解释:

假设我正在用PHP创建一个microCMS.这个microCMS有一个Router类,负责路由.它还包含从中提取的URI和额外参数.

class Router{
  private $uri;
  private $params;
  ...
  public function getRoute(){ ... }
  ...
  public function getParams(){
    return $this->params;
  }
  ...
}

我还有一个Front Controller,我正在传递一个新的Router()对象.到目前为止,这么好,我可以访问前端控制器中的额外参数(通过$router-> getParams();).

class FrontController{
  private $controller;
  private $view;

  public function __construct(Router $router){
    $route = $router->getRoute();
    ...
    $params = $router->getParams(); //Yay, I can get to the params here!
    ...
    $this->view = new View($route->getModel());
    ...
  }

现在,这对我来说变得复杂了.此前端控制器构造一个视图.我希望这个View也能够访问路由器的功能(例如,能够从中获取URI参数).

class View{
  public function output(){
    //But how do I access the Router's params here...?
  }
}

第一个,最简单的解决方案似乎是将路由器变为单例或只是使函数静态并简单地调用Router :: getParams()……但这是不可能因为反模式.

第二个明显的解决方案是将我的Router实例传递给View的构造函数.我想避免这种情况,因为我担心我的构造函数会在某个地方变得巨大.我不确定我需要从View中访问多少其他类,我不希望它们不必要地混淆其构造函数.这种恐惧是否合理?

另一种解决方案是使用服务定位器并在我的视图中调用类似$serviceLocator-> getRouter()的内容.但显然,这也是一种反模式.

那么解决方案是什么?或者CMS的架构根本就是错误的东西?

最佳答案 FrontController使用
Dependency Injection,这被认为是处理此问题的最佳方式.因为你直接传递了类的实例,所以你不会创建单身人士固有的全局性问题.

担心View构造函数会变得臃肿是没有根据的.如果你需要依赖,那么你需要将它注入某个地方.您不必在构造函数中执行此操作.你总是可以做一个像这样的功能

public function setRouter(Router $router) {
     $this->router = $router;
}

并注入它.

如果你的类本身真的变得臃肿,那么你需要将它重构为子类.

点赞