Lavavel 面向对象学习 - 代码修改后的面向对象风格
发布时间:2022-10-18 10:58:43 所属栏目:PHP教程 来源:
导读: 系列文章:
Lavavel 面向对象学习 - 代码修改前过程方法风格Lavavel 面向对象学习 - 代码修改后的面向对象风格
Lavavel 面向对象学习 - 代码修改后的面向对象风格需求分析
因为消息模板
Lavavel 面向对象学习 - 代码修改前过程方法风格Lavavel 面向对象学习 - 代码修改后的面向对象风格
Lavavel 面向对象学习 - 代码修改后的面向对象风格需求分析
因为消息模板
|
系列文章: Lavavel 面向对象学习 - 代码修改前过程方法风格Lavavel 面向对象学习 - 代码修改后的面向对象风格 Lavavel 面向对象学习 - 代码修改后的面向对象风格需求分析 因为消息模板实际有多个的。业务进度消息只是其中一个模板。 控制器类 WechatPushController.php 返回给前端的公共对象类 ResultStandard.php 消息类公共接口 InterfaceMessage.php 业务进度消息类 MessageBusinessProgress.php 微信推送消息类 WechatPush.php 用户 openid 查找类 UserIdToOpenId.php 代码真实可用。 修改后的代码控制器类 WechatPushController.php class WechatPushController extends Controller { // 控制器方法,发送模板消息。 public function template_message(Request $request, MessageBusinessProgress $message) { $user_id = $request->input('user_id'); $message->setMessageTitle($request->input('message_title')); $message->setMessageOrderNo($request->input('message_order_no')); $message->setMessageContent($request->input('message_content')); $message->setMessageRemark($request->input('message_remark')); $json_result = $message->push($user_id); return response()->json( $json_result->to_json() )->setEncodingOptions(JSON_UNESCAPED_UNICODE); } } 返回给前端的公共对象类 ResultStandard.php <?php namespace App\Services; /** * 公共结果对象 * * @author x */ class ResultStandard { const RIGHT_CODE =200; protected $code; protected $message; protected $data; public function __construct(bool $boo, $data=[], $message='') { if ($boo) { $this->code = self::RIGHT_CODE; } $this->data = $data; $this->message=$message; } public static function get_instance(bool $boo, $data=[], $message='') { return new self($boo, $data, $message); } public function to_json() { if ($this->code == self::RIGHT_CODE ){ return [ 'code' => $this->code, 'errMsg' =>'成功', 'data'=> $this->data, ]; } return [ 'code' => $this->code, 'errMsg' =>$this->message ?: '错误', 'data'=> $this->data ?: [], ]; } } 消息类公共接口 InterfaceMessage.php <?php namespace App\Services\ThirdApi\Wechat; use App\Services\ResultStandard; /** * 业务进度消息类公共接口 * * @author 11 */ interface InterfaceMessage { // 获取业务进程消息的模板id public function get_template_id():string ; // 微信推送 public function push($user_id): ResultStandard; //收集推送的数据。 public function get_push_data():array; } 业务进度消息类 MessageBusinessProgress.php <?php namespace App\Services\ThirdApi\Wechat; use App\Services\ResultStandard; /** * 业务进度消息类 * * @author 11 */ class MessageBusinessProgress implements InterfaceMessage { const TEMPLATE_ID = 'f9it7NnvjG1XyxtRCGoFo-V7u96TIhT1ZP2yUfE-zNs'; protected $message_order_no; // 订单号 protected $message_title; // 标题 protected $message_content; // 消息主体内容。控制在80个汉字以内比较好 protected $message_remark; // 简短的备注 private $servicePush; private $serviceUser; public function __construct() { $this->servicePush = new WechatPush(); $this->serviceUser = new UserIdToOpenId(); } // 获取业务进程消息的模板id public function get_template_id():string { return self::TEMPLATE_ID; } // 微信推送 public function push($user_id): ResultStandard { $user_id = intval($user_id); $openid = $this->serviceUser->find_openid($user_id); if (!$openid) { return ResultStandard::get_instance(false, [], $this->serviceUser->get_err()); } try { $this->servicePush->push($this, $openid); } catch (\Exception $e) { return ResultStandard::get_instance(false, [], $e->getMessage()); } return ResultStandard::get_instance(true); } public function get_push_data():array { return [ 'first' => $this->getMessageTitle(), 'keyword1' => $this->getMessageOrderNo(), 'keyword2' => $this->getMessageContent(), 'keyword3' => date('Y-m-d H:i:s'), 'remark' => $this->getMessageRemark(), ]; } /** * @return mixed */ public function getMessageOrderNo() { return $this->message_order_no; } /** * @param mixed $message_order_no */ public function setMessageOrderNo($message_order_no): void { $this->message_order_no = $message_order_no; } /** * @return mixed */ public function getMessageTitle() { return $this->message_title; } /** * @param mixed $message_title */ public function setMessageTitle($message_title): void { $this->message_title = $message_title; } /** * @return mixed */ public function getMessageContent() { return $this->message_content; } /** * @param mixed $message_content */ public function setMessageContent($message_content): void { $this->message_content = $message_content; } /** * @return mixed */ public function getMessageRemark() { return $this->message_remark; } /** * @param mixed $message_remark */ public function setMessageRemark($message_remark): void { $this->message_remark = $message_remark; } } 微信推送消息类 <?php namespace App\Services\ThirdApi\Wechat; use App\Lib\Err; use EasyWeChat\Factory; /** * 微信推送 * * @author 11 */ class WechatPush { use Err; protected $app; public function __construct() { $config = [ 'app_id' => config('yansongda.wechat.app_id'), 'secret' => config('yansongda.wechat_secret'), 'response_type' => 'array', ]; $this->app = Factory::officialAccount($config); } /* * 推送微信模板消息 * * //{{first.DATA}} * //业务单号:{{keyword1.DATA}} * //办理进度:{{keyword2.DATA}} * //时间:{{keyword3.DATA}} * //{{remark.DATA}} * * @param MessageBusinessProgress $message * @param string $openid * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @throws \GuzzleHttp\Exception\GuzzleException */ public function push(InterfaceMessage $message, string $openid) { $result = $this->app->template_message->send([ 'touser' => $openid, 'template_id' => $message->get_template_id(), 'url' => '', 'miniprogram' => [], 'data' => $message->get_push_data(), ]); return $result; } } 用户 openid 查找类 UserIdToOpenId.php <?php namespace App\Services\ThirdApi\Wechat; use App\Lib\Err; use App\Models\User; use App\Models\UserWx; /** * 处理http. * * @author 11 */ class UserIdToOpenId { use Err; public function find_openid($user_id) : ?string { $user = User::find($user_id); if ($user && $user->union_id) { $wx_record = UserWx::query()->where('unionid', $user->union_id)->first(); if ($wx_record && $wx_record->openid ) { return $wx_record->openid; }else { $this->set_err('用户未关注公司微信公众号,或关注记录没有保存openid字段'); } }else { $this->set_err('用户不存在,或用户没有union_id'); } return null; } } 总结 1、修改后,可维护性极大提高,总共也不知道多少行了,花去的时间至少是写修改前代码的 3 倍不止。 2、从代码中可以看出,每个类功能单一,这是 solid 原则的最基本原则,已经实现。 3、具体过程就是分析出有哪些对象,然后让对象之间互相交互。 4、面向对象就是先写出高层代码,不考量具体实现,假定有一个类能够实现。 5、然后把任务分解为一个个的类,直到不能继续分解任务了,再考量如何实现。 6、比如当前这个需要,可以构造一个message 的具体类,里面有对应这个消息模板的字段,然后这个类有个方法叫做push,参数是user_id。为了set和get写的方便,我还用了phpstorm的功能:code - generate - getter and setter 7、这个就是最核心的抽象,想象这个类非常聪明,它竟然能自己把自己发送出去,这样就可以了。 8、为了实现这个目标,给这个类加成员变量,是实际发送消息的类,这样就真的自己可以发送自己了。具体方式就是把自己传给实际发送消息的类。 9、之前还需要把 user_id 转变成 openid,不要自己实现,必须再把任务分配给其他类,保持单一职责。 10、而为了能让实际发送消息类能不需要自己去分辨模板有哪些字段,可以让消息类自己有个拼凑发送字段的方法。 11、实际上,获取openid的类也可以再修改,比如它的目的是获取openid,所以可以有个方法是get_open_id,然后构造方法带一个用户id这样。 12、对比一下修改前的代码就可以知道PHP面向对象,这里经过了大量的思考,大量的修改。当然消耗的时间也是成数倍增长的。 13、修改之后的代码是可以写单元测试的。这里可以 mock 微信的返回格式来测试其余的代码。 14、之前的过程代码就很难测试。因为访问了实际的微信服务器。 15、所以,为了让自己的代码通过单元测试,你只能精心的进行面向对象编程。 16、反过来,不在乎单元测试,则各种可能都有,代码可能好,也可能不好,因为没人强制。而只要为了早下班,不加班,同时催的急,就只能面向过程了,毕竟简单直接,无需思考各种对象交互。也就是修改前的代码。 17、其实只要多写多练多实践,面向对象也就慢慢习惯了,并没有特别难以理解的地方。 (编辑:PHP编程网 - 钦州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐


浙公网安备 33038102330484号