【问题标题】:Real alternative to Singletons and Service Locators?单例和服务定位器的真正替代品?
【发布时间】:2023-03-11 17:46:02
【问题描述】:

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

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

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

我还有一个前端控制器,我正在向它传递一个新的 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());
    ...
  }

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

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

第一个也是最简单的解决方案似乎是将 Router 变成单例,或者只是将函数设为静态并简单地调用 Router::getParams()... 但这是不可以的,因为反模式。

第二种显而易见的解决方案是将我的路由器实例传递给视图的构造函数。我想避免这种情况,因为担心我的构造函数会在某个地方变得巨大。我不确定我需要像这样从 View 访问多少其他类,并且我不希望它们不必要地弄乱它的构造函数。这种恐惧有道理吗?

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

那么解决方法是什么?还是我的 CMS 架构存在根本问题?

【问题讨论】:

    标签: php dependency-injection singleton service-locator


    【解决方案1】:

    FrontController 使用Dependency Injection,这被认为是处理此问题的最佳方式。因为您是直接传入类的实例,所以不会在 Singleton 中创建 global-esque 问题。

    担心View 构造函数会变得臃肿是没有根据的。如果您需要依赖项,则需要将其注入某处。您不必在构造函数中执行此操作。你总是可以做一个像

    这样的函数
    public function setRouter(Router $router) {
         $this->router = $router;
    }
    

    然后像这样注入它。

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

    【讨论】:

    • 通过多个实例化级别注入路由器依赖项(首先进入前端控制器,然后进入视图,然后谁知道我可能需要在哪里......)不被认为是不好的做法?我什么时候知道是时候将我的类重构为子类了?什么时候依赖太多了?
    • 并非如此。您正在注入同一个类,因此它将根据需要随时注入。我的经验法则是,如果一个类超过 700 行,则需要重构。至于太多的依赖......这取决于你在做什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    相关资源
    最近更新 更多