您的位置:首页 > 移动开发

From Apprentice To Artisan 01

2015-05-10 17:19 337 查看
Dependency Injection 依赖注入

laravel 框架的基础是:IoC Container (控制反转容器)、控制反转的"容器” 是方便实现“依赖注入”的工具、但实现依赖注入并不一定需要控制反转容器、只是使用“容器”会方便和容易一点

#控制反转

class UserController extends BaseController{
public function getIndex()
{
$users= User::all();
return View::make('users.index', compact('users'));
}
}
如果测试這段代码就需跟实际的数据库发生联系、即Eloquent ORM 跟改控制器有紧耦合,违背了“关注分离”软件设计的原则、简单讲:這个控制器知道太多了。

控制器不需要了解数据从哪里来,只知道如何访问、和这数据是可用的即可

Separation Of Concerns    关注分离

Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.

每一个类都应该有单独的职责,并且该职责应完全被这个类封装。(译者注:我认为就是不要让多个类负责同样的职责)


“关注分离”的好处就是让Web 控制器和数据访问解耦、這样使得实现存储迁移更容易、测试也更容易!"Web"在你的应用中就紧紧作为一个传输层!

例如:一台显示器、用很多连接的线缆接口(HDMI、VGA、DVI)、你可以通过不同的接口访问该显示器的功能。Internet 就像一个线缆连接你的应用程序、大部分显示器的功能是独立于线缆的,线缆(比如 HTTP)只是你应用程序的一种传输机制、所以不想把传输机制(控制器)和业务逻辑混在一起。這样的好处就是其他的传输机制比如:API调用、移动应用等都可以访问我们的业务逻辑

所以就别把控制器和Eloquent ORM 耦合在一起了,咱们添加(注入)一个 Repository 类

#建立协议

定义一个接口、然后实现它

interface UserRepositoryInterface
{
public function all();
}

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


#然后就将改该接口的“实现” 添加(注入)到我们的控制器中

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'));
}
}
這样控制跟数据层面就无关了,无知就是福!数据可能来之MySql、MongoDB 或者Redis 、控制器不知道也不关注他们的区别、這个小小的改变就让web 层独立 Data 层,将来切换存储也很容易.

#写一个测试案例、首先模拟一个Repository 和绑定它到 应用 IoC 容器中、然后要保证控制器正确的调用這个Repository(数据仓库)

public function testIndexActionBindsUsersFromRepository()
{
// Arrange...
$repository = Mockery::mock('UserRepositoryInterface');
$repository->shouldReceive('all')->once()->andReturn(array('foo'));
App::instance('UserRepositoryInterface', $repository);
// Act...
$response  = $this->action('GET', 'UserController@getIndex');

// Assert...
$this->assertResponseOk();
$this->assertViewHas('users', array('foo'));
}


#mockery 插件

Are you Mocking Me 你在模仿我么?

In this example, we used the `Mockery` mocking library. This library provides a clean, expressive interface for mocking your classes. Mockery can be easily insalled via Composer.

在上面的例子里, 我们使用了名为`Mockery`的模仿库。 这个库提供了一套整洁且富有表达力的方法,用来模仿你写的类。 Mockery可以通过Composer安装。


该文章只是个人笔记、原文参照:http://my.oschina.net/zgldh/blog/300008#OSC_h2_1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: