本人是做PHP开发的,才开始学习写博客记录和分享自己的所学,欢迎各位大神来捶,批评指正。在刚开始学习PHP编程的几年中!通常为了快速学习,我们选择了框架来学习编程,从最初的ThinkPHP 到后来的CI、Yii2 最近也在摸索laravel.框架给开发人员搭建了一套平台,为开源的大牛们致敬,这使我能轻易的基于MVC模式开发,如建站、BBS、CRM等方方面面。在翻来覆去的使用过程中,把MVC烂熟于心,一个个小项目简直不要太简单。
在我入门编程的时候,我遇见了一位好领导,他让我记住一点,只要记住这一点,那说你就还能做这行,不然就找些去干其它的吧,他说:你今天写的代码,到一个星期以后看看是什么感觉,是不是还能改进,一个月再回头看看这代码,是不是需要重写,三个月再回头看看,是不是就像垃圾一样,完全可以使用更好的方式实现。
我一直谨记教诲,一堆废话,下面进入本章正题,很早之前接触到一个词“设计模式”,听起来好高大上的样子,也立即搜索了相关的各种文档和文章,都能看明白,就是不知道怎么使用,通过实践出真理,今天给大家分享的是设计模式中的依赖注入
例子:
我们写一个订单程序,订单中我们需要实现订单的生成,订单的各项费用计算,付款,订单完成,大概就这几步(例子);支付中我们需要对接现在的支付宝,微信、银联等支付机构。我们的订单类中就需要实现 创建订单方法 计算各项费用和优惠 付款方法 保存订单。
按照以前的方法是直接在控制器里面从上到下写上一个个方法来完成以上功能,突然有一天,领导说,加一个百度支付,这时候,你打开之前写的订单控制器。查看以前的代码逻辑,理清楚思路,然后再创建几个方法实现百度支付的方法,然后再在本地反复的测试几遍,提交,这时候如果是新手或者是刚刚接手这个项目的人就难办了,看看半天代码不知道怎么办,一点一点的缕思路,然后加代码,然后测试,一不小心哪里改错了不知道,上线就是各种麻烦,调试,找问题。
依赖注入就能很好的解决这个问题。
第一步:我们创建一个接口
/** * 支付接口 * Interface PayInterface * @package app\index\infc */ interface PayInterface { /** * 提交订单 * @return mixed */ public function pushOrder(); /** * 支付后的回调方法 * @return mixed */ public function collback(); }然后我们再创建两个类来实现这个接口
第一个是支付宝类
use app\index\infc\PayInterface; /** * 这只是个不完整的例子,请按照实际情况编写代码 * Class AliPay * @package app\index\logic */ class AliPay implements PayInterface { private $config = [ 'APP_KEY' => "HFAJALJEFALKWEHFLAHESKDGFEAIESJFAS", 'Ali_Pay' => 'www.alipay.com/pay' ]; private $order; public function config($config) { $this->config = array_merge($this->config, $config); } public function getOrcer($order) { $this->order = $order; } /** * 执行支付行为 * @param $order * @return mixed|void */ public function pushOrder($order) { //这里就可以写 接入支付宝的SDK 实现支付动作 $this->order; } /** * 回调方法 * @param $collback * @return mixed|void */ public function collback($collback) { //这里实现支付宝支付成功或者失败后的回调。 } }
第二个是微信支付类
use app\index\infc\PayInterface; /** * 这只是个不完整的例子,请按照实际情况编写代码 * Class AliPay * @package app\index\logic */ class WeChatPay implements PayInterface { private $config = [ 'APP_KEY' => "HFAJALJEFALKWEHFLAHESKDGFEAIESJFAS", 'WeChat_Pay' => 'www.wechat.com/pay' ]; private $order; public function config($config) { $this->config = array_merge($this->config, $config); } public function getOrcer($order) { $this->order = $order; } /** * 执行支付行为 * @param $order * @return mixed|void */ public function pushOrder($order) { //这里就可以写 接入微信的SDK 实现支付动作 $this->order; } /** * 回调方法 * @param $collback * @return mixed|void */ public function collback($collback) { //这里实现微信支付成功或者失败后的回调。 } }
接下来就是订单类:
use app\index\infc\PayInterface; class Order { /** * 订单 * @var null */ private $Order = null; /** * 支付金额 * @var null */ private $num = null; /** * 创建订单 * @param $orderName * @param $OrderList * @return mixed */ public function createdOrder($orderName, $OrderList) { return $this->Order[$orderName] = $OrderList; } /** * 获取订单中所有小项目的和 * @return float|int */ public function getPayNum() { $num = []; foreach ($this->Order as $item) { $num[] = $item->money; } return $this->num = array_sum($num); } /** * 发起支付 * @param PayInterface $pay */ public function pushPay(PayInterface $pay) { $pay->pushOrder($this->num); } /** * 这个方法中实现订单的保存 */ private function saveOrder() { } }这样我们就完成了整个接口的实现,需要调用订单的时候,只需要按照流程实现即可。不知道你有没有发现我们使用了一个有意思的传参
public function pushPay(PayInterface $pay)这里的PayInterface 就是我们所约束的条件 整理的$pay 必须是实现PayInterface接口的实例,否则将报致命错误。我们实现的的支付宝支付和微信支付都是实现了PayInterface接口,所以我们就可以通过前端选择的是什么支付方式,我们就给pushPay方法传递那个实例进入即可。
以后不管有多少个支付方式,只要按照接口实现,就可以无限扩展,在多人协作开发的过程中也很有用,你的小伙伴不需要理解清楚你的支付是怎么实现的,他只需要知道使用你提供的方法就能达到目的!
引用骨灰级大神 《java骨灰级女神经》 的总结:
http://blog.csdn.net/qq_35091777/article/details/78358887
1.构造方法注入:
优点:
- 在构造方法中体现出对其他类的依赖,一眼就能看出这个类需要其他那些类才能工作。
- 脱离了IOC框架,这个类仍然可以工作,POJO的概念。
- 一旦对象初始化成功了,这个对象的状态肯定是正确的。
缺点:
- 构造函数会有很多参数(Bad smell)。
- 有些类是需要默认构造函数的,比如MVC框架的Controller类,一旦使用构造函数注入,就无法使用默认构造函数。
- 这个类里面的有些方法并不需要用到这些依赖(Bad smell)。
- 在对象的整个生命周期内,可以随时动态的改变依赖。
- 非常灵活。
- 对象在创建后,被设置依赖对象之前这段时间状态是不对的。
- 不直观,无法清晰地表示哪些属性是必须的。
希望对你有所帮助