Contracts
Laravel’s contract is a set of interfaces that define the core services provided by the framework. For example, we have mentioned in the chapter introducing user authentication The User Guard ContractIllumninateContractsAuthGuard
and the User Provider ContractIlluminateContractsAuthUserProvider
as well as the IlluminateContractsAuthAuthenticatable
# implemented by the App\User model that comes with the framework ##contract.
Why use contracts
We can see from the source code files of the above contracts that the contract provided by Laravel is a set of interfaces defined for the core module . Laravel provides corresponding implementation classes for each contract. The following table lists the implementation classes provided by Laravel for the three contracts mentioned above.Define and use contracts
What we mentioned above are all contracts provided by the Laravel kernel. When developing large projects, we can also define contracts in the project ourselves. and implementation classes. You may feel that the built-in Controller and Model layers are enough for you to write code. Adding additional contracts and implementation classes out of thin air will make development cumbersome. Let's start with a simple example and consider what's wrong with the following code:class OrderController extends Controller { public function getUserOrders() { $orders= Order::where('user_id', '=', \Auth::user()->id)->get(); return View::make('order.index', compact('orders')); } }
Separation Of Concerns
Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.Each class should have only a single responsibility, and everything in the responsibility should be encapsulated by this classNext we define an interface and then implement the interface
interface OrderRepositoryInterface { public function userOrders(User $user); } class OrderRepository implements OrderRepositoryInterface { public function userOrders(User $user) { Order::where('user_id', '=', $user->id)->get(); } }
App::singleton('OrderRepositoryInterface', 'OrderRespository');
class UserController extends Controller { public function __construct(OrderRepositoryInterface $orderRepository) { $this->orders = $orderRespository; } public function getUserOrders() { $orders = $this->orders->userOrders(); return View::make('order.index', compact('orders')); } }
Interface and Team Development
When your team is developing a large application, different parts have different development speeds. For example, one developer is developing the data layer, and another developer is working on the controller layer. The developer who wrote the controller wants to test his controller, but the data layer development is slow and cannot be tested simultaneously. If two developers can first reach an agreement in the form of an interface, various classes developed in the background will follow this agreement. Once the agreement is established, even if the agreement has not been implemented, the developer can also write a "fake" implementation for this interfaceclass DummyOrderRepository implements OrderRepositoryInterface { public function userOrders(User $user) { return collect(['Order 1', 'Order 2', 'Order 3']); } }
App::singleton('OrderRepositoryInterface', 'DummyOrderRepository');
RedisOrderRepository.
那么使用IoC容器切换接口实现,应用就可以轻易地切换到真正的实现上,整个应用就会使用从Redis读出来的数据了。
接口与测试
建立好接口约定后也更有利于我们在测试时进行Mock
public function testIndexActionBindsUsersFromRepository() { // Arrange... $repository = Mockery::mock('OrderRepositoryInterface'); $repository->shouldReceive('userOrders')->once()->andReturn(['order1', 'order2]); App::instance('OrderRepositoryInterface', $repository); // Act... $response = $this->action('GET', 'OrderController@getUserOrders'); // Assert... $this->assertResponseOk(); $this->assertViewHas('order', ['order1', 'order2']); }
总结
接口在程序设计阶段非常有用,在设计阶段与团队讨论完成功能需要制定哪些接口,然后设计出每个接口具体要实现的方法,方法的入参和返回值这些,每个人就可以按照接口的约定来开发自己的模块,遇到还没实现的接口完全可以先定义接口的假实现等到真正的实现开发完成后再进行切换,这样既降低了软件程序结构中上层对下层的耦合也能保证各部分的开发进度不会过度依赖其他部分的完成情况。
更多laravel框架相关技术文章,请访问laravel教程栏目!
The above is the detailed content of Parsing the Contracts contract under the Laravel framework. For more information, please follow other related articles on the PHP Chinese website!