laravel 基础面试题--2020-12-18-laravel契约(contracts)
感谢关注本人公众号: 上海 PHP 自学中心
qq群(3年2万):517085546
契约理解
1. 契约的目的
为了让开发者能够根据自己项目的需要自己定义实现类
而对于这些接口的消费者(比如:Controller、或者内核提供的 AuthManager这些)
他们不需要关心接口提供的方法具体是怎么实现的, 只关心接口的方法能提供什么功能.
然后去使用这些功能就可以了,我们可以根据需求在必要的时候为接口更换实现类,而消费端不用进行任何改动。
2. 定义和使用契约,你的mc足够用?别开玩笑了
上面我们提到的都是Laravel内核提供的契约, 在开发大型项目的时候我们也可以自己在项目中定义契约和实现类
你有可能会觉得自带的Controller、Model两层就已经足够你编写代码了,凭空多出来契约和实现类会让开发变得繁琐。我们先从一个简单的例子出发,考虑下面的代码有什么问题:
class OrderController extends Controller{ public function getUserOrders() { $orders= Order::where('user_id', '=', \Auth::user()->id)->get(); return View::make('order.index', compact('orders')); }}
这段代码很简单,但我们要想测试这段代码的话就一定会和实际的数据库发生联系。也就是说, ORM和这个控制器有着紧耦合。如果不使用Eloquent ORM,不连接到实际数据库,我们就没办法运行或者测试这段代码。这段代码同时也违背了“关注分离”这个软件设计原则。简单讲:这个控制器知道的太多了。 控制器不需要去了解数据是从哪儿来的,只要知道如何访问就行。控制器也不需要知道这数据是从MySQL或哪儿来的,只需要知道这数据目前是可用的。
Separation Of Concerns 关注分离
Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.
每个类都应该只有单一的职责,并且职责里所有的东西都应该由这个类封装
接下来我们定义一个接口,然后实现该接口
interface OrderRepositoryInterface { public function userOrders(User $user);} class OrderRepository implements OrderRepositoryInterface{ public function userOrders(User $user) { Order::where('user_id', '=', $user->id)->get(); }}
将接口的实现绑定到Laravel的服务容器中
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')); }}
现在我们的控制器就完全和数据层面无关了。在这里我们的数据可能来自MySQL,MongoDB或者Redis。我们的控制器不知道也不需要知道他们的区别。这样我们就可以独立于数据层来测试Web层了,将来切换存储实现也会很容易。
Laravel核心解读–Contracts契约
3. 契约 对比 门面
Laravel 的 Facades 和辅助函数提供了一种利用 Laravel 服务的简单方法,无需类型提示并可以从服务容器中解析契约。 在大多数情况下,每个 Facade 都有一个等效的契约。
和 Facades(它不要求您在类的构造函数中引入它们)不同,契约允许您为类定义显式依赖关系。 一些开发人员更喜欢以这种方式显式定义其依赖项,所以更喜欢使用契约,而其他开发人员则享受 Facade 带来的便利。
技巧:无论您更喜欢 Facads 还是契约,大多数应用都运行得不错。但是,如果要构建程序包,则应强烈考虑使用契约,因为它们在程序包上下文中更容易测试。
思考
- laravel 契约,你会如何优化自己当前项目的 M 与 C层?
- 让你设计一个支付类,需要阿里pay,wxpay,银联pay,请问如何设计?
防爬虫说明
禁止 学习某地爬虫,知乎爬虫,CSDN 爬虫。
本文,首发在 learnku 社区。
@author
汪春波(www.shxdledu.cn)