The Problem 遇到的问题
The foundation of the Laravel framework is its powerful IoC container. To truly understand the framework, a strong grasp of the container is necessary. However, we shold note that an IoC container is simply a convenience mechanism for achieving a software design pattern: dependency injectionl. A container is not necessary to perform dependency injection, it simply makes the task easier.
Laravel 框架的基础是一个功能强大的控制反转容器(IoC container)。 为了真正理解本框架,需要好好掌握该容器。但我们要搞清楚,控制反转容器只是一种用于方便实现“依赖注入”的工具。要实现依赖注入并不一定需要控制反转容器,只是用容器会更方便和容易一点儿。
First, let's explore why dependency injection is beneficial. Consider the following class and method:
首先来看看我们为何要使用依赖注入,它能带来什么好处。 考虑下列代码:
class UserController extends BaseController{
public function getIndex()
{
$users= User::all();
return View::make('users.index', compact('users'));
}
}
While this code is concise, we are unable to test it without hitting an actual database. In other words, the Eloquent ORM is tightly coupled to out controller. We have no way to use or test this controller without also using the entire Eloquent ORM, including hitting a live database. This code also violates a software design principle commonly called separation of concerns. Simple put: our controller knows too much. Controllers do not need to know where data comes from, but only how to access it. The controller doesn't need to know that the data is available in MySQL, but only that it is available somewhere.
这段代码很简短,但我们要想测试这段代码的话就一定会和实际的数据库发生联系。也就是说, Eloquent ORM(译者注:Laravel 的数据库对象模型库)和该控制器有着紧耦合。如果不使用 Eloquent ORM,不连接到实际数据库,我们就没办法运行或者测试这段代码。这段代码同时也违背了“关注分离”这个软件设计原则。简单讲:这个控制器知道的太多了。 控制器不需要去了解数据是从哪儿来的,只要知道如何访问就行。控制器也不需要知道这数据是从 MySQL 或哪儿来的,只需要知道这数据目前是可用的。
Separation Of Concerns 关注分离
Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.
每一个类都应该有单独的职责,并且该职责应完全被这个类封装。(译者注:我认为就是不要让多个类负责同样的职责)
So, it will be beneficial for us to decouple our web layer (controller) from our data access layer completely. This will allow us to migrate storage implementations easily, as well as make our code easier to test. Think of the "Web" as just a transport layer into your "real" application.
关注分离的好处就是能让 Web 控制器和数据访问解耦。这会使得实现存储迁移更容易,测试也会更容易。“Web” 就仅仅是为你真正的应用做数据的传输了。
Imagine that your application is like a monitor with a variety of cable ports. You can access the monitor's functionality via HDMI, VGA, or DVI. Think of the Internet as just a cable into your application. The bulk of a monitor's functionality is independent of the cable. The cable is just a transport mechanism just like HTTP is a transport mechanism for your application. So, we don't want to clutter up our transport mechanism (the controller) with application logic. This will allow any transport layer, such as an API or mobile application, to access our application logic.
想象一下你有一个类似于监视器的程序,有着很多线缆接口(HDMI,VGA,DVI等等)。 你可以通过不同的接口访问不同的监视器。把 Internet 想象成另一个插进你程序线缆接口。大部分显示器的功能是与线缆接口互相独立的。线缆接口只是一 种传输机制就像 HTTP 是你程序的一种传输机制一样。所以我们不想把传输机制(控制器)和业务逻辑混在一起。这样的好处是很多其他的传输机制比如 API 调用、移动应用等都可以访问我们的业务逻辑。
So, instead of coupling our controller to the Eloquent ORM, let's inject a repository class.
那么我们就别再将控制器和 Eloquent ORM 耦合在一起了。 咱们注入一个资料库类。