【问题标题】:Dependency injection php website依赖注入php网站
【发布时间】:2014-11-15 23:05:17
【问题描述】:

我对依赖注入的了解越多,我就越感到困惑。我知道它的用途,那不是问题。尝试在纸上做一些设计,这是我的想法,但在我看来,我似乎忽略了一些东西。

首先,我设想构建一个实际的服务器,它可以接受传入的请求并将响应返回给用户。

class Server {
  private $responseBuilder;

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

  public function run() {
    // create socket, receive request
    $response = $this->responsebuilder->build($request);
    // send response
  }
}

class Response {
  private $method;
  private $message;
  private $url;

  // getters & setters
}

class ServerBuilder {
   public build() {
      // construction logic
      return new Server(new ResponseBuilder());
   }
}

由于 Apache 用于处理服务器请求,我们可以将服务器替换为仅发送响应的服务器。

$bldr = new ResponseBuilder();
$response = $bldr->build();
// send response some way

请注意,ResponseBuilder 可以直接访问请求 ($_SERVER['..']) 因此它拥有选择正确响应所需的一切。

然而,PHP 允许我们内联构建和发送响应。因此,我们可以为每个页面或其他发送响应的对象创建一个控制器对象,并为此创建一个构建器。

$bldr = new ControllerBuilder();  
$controller = $bldr->build();
$controller->run();

class ExampleController implements Controller {
    public function run() {
       header("HTTP/1.1 404 Not Found");
       echo 'sorry, page not found';
    }
} 

这一切对我来说都很有意义。但是让我们再看一下服务器示例。 它调用 $responseBuilder->build() 并得到响应。但这意味着构建器(或其他构建器,如果我们拆分它)还负责可能发生的任何其他事情,例如验证用户,写入数据库,......而且我无法理解这样一个事实写入数据库将是对象图构造的一部分。 就像:向我发送您的请求。哦,你想要主页?我会建立你的回应,当我在做的时候,我也会做一些与建立它无关的事情,比如记录我刚刚做的事情,把你的一些数据保存在一个 cookie 中,然后向管理员发送一封邮件你是这个页面上的第一个访问者,...

【问题讨论】:

  • 让我把这个做对,你想把它用作后端。向它发送任何数据的请求,找到与数据匹配的页面,并显示它?
  • php 中的一切不都是后端吗?反正。我是这样看的。因为它是网络,所以理论上 setter 没有用,因为所有东西都可以注入构造函数中。传入的 http 请求的主要目的是返回一些 html。依赖注入用于通过使用在构造函数中注入所有内容的构建器或工厂来组装 html。但是在组装过程中必须完成一些副作用,例如写入数据库,我不认为这是构建器的任务
  • 不是,你可以只用PHP来创建接口(前端),或者你可以用它来保存数据库或处理模型数据(后端)
  • 但是在服务器上构建接口不仍然是后端工作吗?无论如何,是的,这基本上就是我想要的。获取传入的 http 请求,构建接口并发送 http 响应。我的理论示例将使用 buildResponse() 执行此操作。问题是副作用属于哪里。如果不在界面构建过程中,那么在哪里。

标签: php dependency-injection web dependencies code-injection


【解决方案1】:

您应该将它们解耦。你有一些我认为有点奇怪的假设。让我们从他们开始。

传入的http请求的主要目的是返回一些html

我已经构建了只返回 JSON 而不是 HTML 的 PHP 后端。我在后端和前端之间有一个非常强大的边界。我只使用后端给我数据库中的数据,或者在数据库中添加/编辑数据。前端只是一个 PHP 脚本,可以按照我想要的任何方式构建页面。

既然是网络,理论上 setter 是没有用的,因为 一切都可以在构造函数中注入

你可以使用构造函数,但你也没有。您可以使用设置器。依赖注入实际上只是扭转了局面。

不过,您走在正确的轨道上。您需要一些负责构建页面的类。因此,让它只负责您构建页面,并承担其他责任。日志记录、身份验证等应该不在此范围内。

例如,如果您想要记录,您可以让构建器创建您的页面,然后您的记录器可以监听您的构建器正在执行的所有操作(例如使用观察者模式)。因此,如果您的构建器说:“我创建了主页”,您可以使用您的记录器记录它,该记录器实际上正在听您的构建器。

例如,验证应该在您的构建器启动之前进行。如果您已经可以确定用户不应该出现在页面上,则您不希望您的构建器开始工作。您可以为此使用数据库,并将任何用户类型/页面请求组合列入白名单。

然后对于数据处理,我将创建一个后端,它只处理应该返回数据或保存数据的请求。然后前端可以通过拉取通信来获取它的内容。

我希望这可以解决一些问题,但我很乐意回答更多不成熟的问题。

【讨论】:

  • 在这种情况下 in 只会返回 html 但我的意思是主要目的是返回响应。让它成为 html,重定向,json,......我建立了我的例子这个想法。服务器收到请求。服务器构建响应。服务器返回响应。然后我很困惑,因为当它建立响应时它可以记录。但是,是的,我想我看到了服务器端后端和前端分离的意义。
  • 要真正回答您的问题,请尽可能遵守单一责任原则。这对类很重要,对函数也很重要。一旦你发现一个类在做两件事,就用它创建三个类。两个用于它所做的两件事,第三个是实际确保为他们两个提供他们需要的数据,并处理他们应该处理的数据。
  • 所以我能做的有点像输入/输出套接字流并注入它们(告诉不问原则),让另一个类处理发送响应而不是要求构建一个然后返回它(基本上是php echo)。这样我就可以拥有一个可以拆分其关注点的对象 RequestHandler。一条路径记录,另一条路径发送响应。
  • 听起来不错的解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 2021-04-06
  • 2010-11-27
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多