From Apprentice To Artisan 翻译 01

Dependency Injection

依赖注入

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耦合在一起了。 咱们注入一个资料库类。

Build A Contract 建立约定

First, we‘ll define an interface and a corresponding implementation:

首先我们定义一个接口,然后实现该接口。

interface UserRepositoryInterface
{
    public function all();
}

class DbUserRepository implements UserRepositoryInterface
{
    public function all()
    {
        return User::all()->toArray();
    }
}

Next, we‘ll inject an implementation of this interface into our controller:

然后我们将该接口的实现注入我们的控制器。

class UserController extends BaseController
{
    public function __construct(UserRepositoryInterface $users)
    {
        $this->users = $users;
    }

    public function getIndex()
    {
        $users=$this->users->all();
        return View::make(‘users.index‘, compact(‘users‘));
    }
}

Now our controller is completely ignorant of where our user data is being stored. In this case, ignorance is bless! Our data could be coming from MySQL, MongoDB, or Redis. Our controller doesn‘t know the difference, nor should it care. Just by making this small change, we can test our web layer independent of our data layer, as well as easily switch our storage implementation.

现在我们的控制器就完全和数据层面无关了。在这里无知是福!我们的数据可能来自MySQL,MongoDB或者Redis。我们的控制器不知道也不需要知道他们的区别。仅仅做出了这么小小的改变,我们就可以独立于数据层来测试Web层了,将来切换存储实现也会很容易。

From Apprentice To Artisan 翻译 01

时间: 2024-10-13 19:37:43

From Apprentice To Artisan 翻译 01的相关文章

From Apprentice To Artisan 翻译 03

The IoC Container 控制反转容器 Basic Binding 基础绑定 Now that we've learned about dependency injection, let's explore inversion of control containers. IoC containers make managing your class dependencies much more convenient, and Laravel ships with a very pow

From Apprentice To Artisan 翻译 04

Reflect Resolution 反射解决方案 One of the most powerful features of the Laravel container is its ability to automatically resolve dependencies via reflection. Reflection is the ability to inspect a classes and methods. For example, the PHP ReflectionClass

From Apprentice To Artisan 翻译 02

Respect Boundaries 严守边界 Remember to respect responsibility boundaries. Controllers and routes serve as a mediator between HTTP and your application. When writing large applications, don't clutter them up with your domain logic. 记得要保持清晰的责任边界. 控制器和路由是作

6. Laravel5学习笔记:IOC/DI的理解

介绍 IOC 控制反转 Inversion of Control 依赖关系的转移 依赖抽象而非实践 DI 依赖注入 Dependency Injection 不必自己在代码中维护对象的依赖 容器自动根据配置,将依赖注入指定对象 IOC.DI对于Laravel的意义 Laravel框架的基础是一个功能强大的控制反转容器(IoC container). 为了真正理解该框架,需要好好掌握该容器.然而我们需要了解,控制反转容器只是一种用于方便实现"依赖注入"的工具.但要实现依赖注入并不一定需要

干翻线段树——指令集优化指北

前言 在我们刷题的时候,总会碰到一些关于区间操作/修改的题目.这些题目往往要求我们维护一段区间,支持对一段区间进行查询/修改操作.这些题目有如树状数组1一般的简单题,也有如[无聊的数列][2]一般,线段树.树状数组能够完成,但是码量长,可读性差,思考难度大的较难题.这种题目对时间的要求非常严格,询问/查询次数与序列长度均在\(10^5\)级别或以上,能够使\(O(n^2)\)的暴力算法望屋窃叹.那么,有没有什么方法,可以通过数据,代码又易于实现呢? 指令集优化 今天我要讲的指令集优化,就是对这个

我喜欢减肥我们来减肥吧

http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313278016/2015.01.28.html http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313282016/2015.01.28.html http://www.ebay.com/cln/honus.jyw4mvptb/cars/158313289016/2015.01.28.html http://www.ebay.com/cln/usli

百度回家看沙发沙发是减肥了卡斯加积分卡拉是减肥

http://www.ebay.com/cln/hpryu-caw8ke/cars/158056866019/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/158445650015/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/158445674015/2015.01.31 http://www.ebay.com/cln/xub.50x2l7cj/cars/1584456790

巢哑偕倥乇椭煞谙暗逞帕俸

IEEE Spectrum 杂志发布了一年一度的编程语言排行榜,这也是他们发布的第四届编程语言 Top 榜. 据介绍,IEEE Spectrum 的排序是来自 10 个重要线上数据源的综合,例如 Stack Overflow.Twitter.Reddit.IEEE Xplore.GitHub.CareerBuilder 等,对 48 种语言进行排行. 与其他排行榜不同的是,IEEE Spectrum 可以让读者自己选择参数组合时的权重,得到不同的排序结果.考虑到典型的 Spectrum 读者需求

我国第三代移动通信研究开发进展-尤肖虎200106

众所周知,数据科学是这几年才火起来的概念,而应运而生的数据科学家(data scientist)明显缺乏清晰的录取标准和工作内容.此次课程以<星际争霸II>回放文件分析为例,集中在IBM Cloud相关数据分析服务的应用.面对星际游戏爱好者希望提升技能的要求,我们使用IBM Data Science Experience中的jJupyter Notebooks来实现数据的可视化以及对数据进行深度分析,并最终存储到IBM Cloudant中.这是个介绍+动手实践的教程,参会者不仅将和讲师一起在线