理解23种设计模式(php)
tips:本文只介绍接口的设计模式,所以牵涉到模板的模板方法模式和builder设计模式不做介绍,感兴趣的参考该文:
https://www.cnblogs.com/zyrblog/tag/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/default.html?page=1
面向对象设计的原则:高内聚,低耦合,对扩展开放,对修改关闭的开闭原则;设计模式应该遵从该原则;设计模式更多的是面向对象编程的一种设计理念,很多时候并没有固定的格式,并且有一些设计模式之间的界限很模糊,需要掌握理念,融汇贯通,不要执着于定式
tips:以下都是示例代码,实际业务需求要复杂得多,仅作为入门学习
1、迭代器
特点: 对类的属性进行遍历,优点(隐藏遍历逻辑)
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function hasNext();public function next();public function add($user);public function delete($pointer);
}// 实现类
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{private $set = [];private $pointer = 0;public function hasNext(){if (isset($this->set[$this->pointer])) {return true;} else {return false;}}public function next(){return $this->set[$this->pointer++];}public function add($user){// 存在则不能添加if (in_array($user,$this->set)) {throw new \Exception('已存在');}array_push($this->set,$user);}public function delete($user){$key = array_search($user,$this->set);if ($key) {unset($this->set[$key]);// 处理指针if ($this->pointer < $key) {$this->pointer --;}return true;} else {return false;}}
}// 测试
$commonService = new CommonService();$commonService->add(4);$commonService->add(2);$commonService->add(3);while($commonService->hasNext()) {echo $commonService->next();}
// 结果
2、适配器
特点:根据不同的类型,选择执行对应的类型的成员方法 (适配不同的类型)
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function v220();public function v110();
}// 实现
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{public function v220(){echo 'this is 220 voltage';}public function v110(){echo 'this is 110 voltage';}
}// 测试适配器 假设电压是220伏
$v = 220;$commonService = new CommonService();$commonService->{'v'.$v}();
// 结果
3、普通工厂
特点:不包含抽象类
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function make();public function test();
}// 实现
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{public function make(){echo '制造一台设备'.PHP_EOL;}public function test(){echo '设备测试正常'.PHP_EOL;}public function out(){echo '设备发往山东'.PHP_EOL;}
}// 测试普通工厂$commonService = new CommonService();$commonService->make();$commonService->test();$commonService->out();
// 结果:
4、抽象工厂
特点:工厂是抽象类,包含抽象方法,功能相比普通工厂要复杂,需要实现抽象方法
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function make();public function test();public function out();
}// 抽象工厂类,实现工厂接口
<?phpnamespace App\Service;abstract class CommonServiceAbstract implements CommonServiceInterface
{protected $makeout;abstract public function toMake();public function make(){$this->toMake();echo $this->makeout;}public function test(){echo '设备测试正常'.PHP_EOL;}public function out(){echo '设备发往山东'.PHP_EOL;}
}// 实现抽象工厂内的抽象方法
<?phpnamespace App\Service;class CommonService extends CommonServiceAbstract
{public function toMake(){$this->makeout = "制造出一台汽车\n";}
}// 测试抽象工厂$commonService = new CommonService();$commonService->make();$commonService->test();$commonService->out();
结果
5、单例设计模式
特点:定义很简单,就是类只实例化一次的设计模式,节省服务器资源
// 单例类,通过静态属性$instance持久化保存类的实例
<?phpnamespace App\Service;class CommonService
{private static $instance;public static function instance(){if (!self::$instance) {self::$instance = new self();}return self::$instance;}public function hello(){echo "你好啊\n";}
}// 测试单例$instance = CommonService::instance();$instance->hello();$instance = CommonService::instance();$instance->hello();
// 结果 只有第一次进行了实例化,第二次不再进行实例化了
6、克隆模式
特点:克隆一个对象,克隆以后,原本对象和副本对象是完全独立互不干扰的,简单实用
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function say();
}// 实现
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{public function say(){echo '说话方法';}
}// 测试// 测试单例$clones = [new CommonService()];$clones[0]->say();
//结果
7、桥接模式
特点:在原有抽象类的基础上,增加新的方法(抽象方法),实现新的功能,如果包含抽象方法,则类似抽象工厂,能实现比抽象工厂更加复杂的功能;
// 接口<?phpnamespace App\Service;interface CommonServiceInterface
{public function make();public function test();public function out();
}// 桥接 增加了更为复杂的抽象方法,实现精细化的功能
<?phpnamespace App\Service;abstract class CommonServiceAbstract implements CommonServiceInterface
{protected $makeout;protected $body;protected $wheel;protected $chassis;public function toMake(){$this->makeout = $this->body.'--'.$this->wheel.'--'.$this->chassis;}abstract public function toMakeBody();abstract public function toMakeWheel();abstract public function toMakeChassis();public function make(){$this->toMake();echo $this->makeout."<br />";}public function test(){echo "设备测试正常<br />";}public function out(){echo '设备发往山东<br />';}
}// 实现
<?phpnamespace App\Service;class CommonService extends CommonServiceAbstract
{public function toMakeBody(){$this->body = '碳纤维车身';}public function toMakeWheel(){$this->wheel = '米其林轮胎';}public function toMakeChassis(){$this->chassis = '高韧性底盘';}
}// 测试$commonService = new CommonService();$commonService->toMakeBody();$commonService->toMakeWheel();$commonService->toMakeChassis();$commonService->make();$commonService->test();$commonService->out();
// 结果
8、策略模式
特点:功能与适配器模式类似,针对不同的策略类型,执行不同的方法,区别是:策略模式更复杂一些,将执行过程提炼成单独的工厂类,使得操作类和具体执行类解耦,本质上是外观设计模式+普通工厂的组合
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function make();public function test();public function out();
}// 策略类(操作类,外观模式)
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{private $tool;public function __construct($toolInstance){$this->tool = new $toolInstance();}public function make(){echo $this->tool->toMake();}public function test(){$this->wheel = '米其林轮胎';}public function out(){$this->chassis = '高韧性底盘';}
}// 策略类(两个执行类,普通工厂)
造车
<?phpnamespace App\Service;class CarService
{public function toMake(){echo '我造出了一辆汽车<br>';}
}造船
<?phpnamespace App\Service;class BoatService
{public function toMake(){echo '我造出了一艘船<br>';}
}// 测试
$commonService = new CommonService(CarService::class);$commonService->make();$commonService->test();$commonService->out();$commonService = new CommonService(BoatService::class);$commonService->make();$commonService->test();$commonService->out();
// 结果
9、组合模式
特点:将多个具有相同父类的子类组装在一起,并且所有子类具有相同的结构
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function add($item);public function out();
}// 子类1
<?phpnamespace App\Service;class CarService implements CommonServiceInterface
{private $out;public function add($item){$this->out = $item;}public function out(){echo $this->out;}
}// 子类2
<?phpnamespace App\Service;class CarService implements CommonServiceInterface
{private $out;public function add($item){$this->out = $item;}public function out(){echo $this->out;}
}// 子类2(组合类)
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{private $out;public function add($item){$this->out[] = $item;}public function out(){for($i=0;$i<count($this->out);$i++){echo $this->out[$i]->out();}}
}// 测试
$commonService = new CommonService();$car = new CarService();$car->add('我造出了一辆车');$boat = new BoatService();$boat->add('我造出了一艘船');$commonService->add($car);$commonService->add($boat);$commonService->out();
// 结果
10、装饰器模式
特点:给输出的东西增加一些点缀,采用递归,很实用,但是逻辑有点复杂
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function getColumns();public function getRows();public function getText($rowId);public function show();
}// 装饰类1(增加侧边修饰)
<?phpnamespace App\Service;class SideService implements CommonServiceInterface
{private $content;private $char;private $isInit;public function __construct($content,$char,$isInit){$this->content = $content;$this->char = $char;$this->isInit = $isInit;}public function getColumns(){if ($this->isInit){return strlen($this->content) + 2;} else {return $this->content->getColumns() + 2;}}public function getRows(){if ($this->isInit) {return 1;} else {return $this->content->getRows();}}public function getText($rowId){if ($this->isInit) {return $this->char.$this->content.$this->char;} else {return $this->char.$this->content->getText($rowId).$this->char;}}public function show(){if ($this->isInit) {echo $this->char.$this->content.$this->char.'<br>';} else {for($i=0;$i<$this->getRows();$i++){echo $this->char.$this->content->getText($i).$this->char.'<br>';}}}
}// 装饰类2(增加包边修饰)
<?phpnamespace App\Service;class SurroundingService implements CommonServiceInterface
{private $content;private $isInit;public function __construct($content,$isInit){$this->content = $content;$this->isInit = $isInit;}public function getColumns(){if ($this->isInit){return strlen($this->content) + 2;} else {return $this->content->getColumns() + 2;}}public function getRows(){if ($this->isInit){return 3;} else {return $this->content->getRows() + 2;}}public function getText($rowId){if ($this->isInit) {if ($rowId == 0) {return '+'.$this->makeLine('-',$this->getColumns()-2).'+';} else if ($rowId == 2) {return '+'.$this->makeLine('-',$this->getColumns()-2).'+';} else {return '||'.$this->content.'||';}} else {if ($rowId == 0) {return '+'.$this->makeLine('-',$this->getColumns()-2).'+';} else if ($rowId == $this->getRows() - 1) {return '+'.$this->makeLine('-',$this->getColumns()-2).'+';} else {return '||'.$this->content->getText($rowId-1).'||';}}}public function show(){if ($this->isInit) {for($i=0;$i<$this->getRows();$i++){if ($i == 0) {echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';} else if ($i == 2) {echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';} else {echo '||'.$this->content.'||<br>';}}} else {for($i=0;$i<$this->getRows();$i++){if ($i == 0) {echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';} else if ($i == $this->getRows() - 1) {echo '+'.$this->makeLine('-',$this->getColumns()-2).'+<br>';} else {echo '||'.$this->content->getText($i-1).'||<br>';}}}}private function makeLine($char,$len){$str = '';for($i=0;$i<$len;$i++){$str .= $char;}return $str;}
}// 测试$s0 = new SurroundingService('张同学',true);$s1 = new SideService($s0,'*',false);$s2 = new SurroundingService($s1,false);$s3 = new SurroundingService($s2,false);$s4 = new SideService($s3,'*',false);$s5 = new SurroundingService($s4,false);echo $s5->show();
// 结果
11、访问者模式
特点:访问属性的方法单独提取成为一个类,方便访问方法的修改;
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function add($item);public function visit($visit);
}// 实现
<?phpnamespace App\Service;class SideService implements CommonServiceInterface
{private $content;public function add($item){$this->content[] = $item;}public function visit($visit){return $visit->out($this->content);}
}// 访问类
<?phpnamespace App\Service;class CommonService
{public function out($item){return $item;}
}// 测试
$side = new SideService();$side->add('张三');$side->add('李四');$side->add('王五');$visit = new CommonService();dd($side->visit($visit));
// 结果
12、责任链模式
特点:问题如果在这层没办法处理,就传递到下一层,直到最终被解决或无法解决,利用递归实现添加责任链;
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function addNextResolve($next);public function resolve($problem);public function success();public function fail();
}// 责任链1(通用解决类)
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{private $next;private $problem;public function addNextResolve($next){$this->next = $next;return $next;}public function resolve($problem){$this->problem = $problem;if (is_numeric($problem)) {$this->success();} else {$this->fail();}}public function success(){echo '通过通用方法解决了问题';}public function fail(){echo '通用方法无法解决问题';if ($this->next) {$this->next->resolve($this->problem);}}
}// 责任链2
<?phpnamespace App\Service;class SideService implements CommonServiceInterface
{private $next;private $problem;public function addNextResolve($next){$this->next = $next;return $next;}public function resolve($problem){$this->problem = $problem;if (is_string($problem)) {$this->success();} else {$this->fail();}}public function success(){echo '通过 side 方法解决了问题';}public function fail(){echo 'side 方法无法解决问题';if ($this->next) {$this->next->resolve($this->problem);}}
}// 责任链3
<?phpnamespace App\Service;class SurroundingService implements CommonServiceInterface
{private $next;private $problem;public function addNextResolve($next){$this->next = $next;return $next;}public function resolve($problem){$this->problem = $problem;if (is_array($problem)) {$this->success();} else {$this->fail();}}public function success(){echo '通过 surrounding 方法解决了问题';}public function fail(){echo 'surrounding 方法 无法解决问题';}
}// 测试$common = new CommonService();$sideService = new SideService();$SurroundingService = new SurroundingService();$common->addNextResolve($sideService)->addNextResolve($SurroundingService);$common->resolve(true);
// 结果
13、外观模式 facade
特点:也叫门面设计模式,概念很好理解,通过对复杂的处理方法进行封装,对外暴露易于理解和操作的方法,使用很广,实现简单;
// 门面类
<?phpnamespace App\Service;class CommonService
{private $sb;private $sth;public function __construct($sb,$sth){$this->sb = $sb;$this->sth = $sth;}public function eat(){echo $this->sb.' 在吃 '.$this->sth.'<br>';}public function sleep(){echo $this->sb.' 睡在 '.$this->sth.'上<br>';}}// 测试$common = new CommonService('张三','面包');$common->sleep();$common->eat();
// 结果
14、 仲裁者模式
特点:通过仲裁者改变类的属性,类似与广播
// 仲裁者类 通过$this注入被仲裁者内,每个被注入的仲裁者该更状态,都会在仲裁者中分发给所有的被仲裁者;
<?phpnamespace App\Service;class CommonService
{public $sideService;public $surroundingService;public function __construct(){$this->sideService = new SideService(true);$this->surroundingService = new SurroundingService(true);$this->sideService->addMediator($this);$this->surroundingService->addMediator($this);}public function changeService(){$this->sideService->shift();$this->surroundingService->shift();}public function show(){echo $this->sideService->say().'<br>';echo $this->surroundingService->say().'<br>';}}// 被仲裁者1
<?phpnamespace App\Service;class SideService
{private $status;private $mediator;public function __construct($status){$this->status = $status;}public function say(){if ($this->status) {echo '开启状态';} else {echo '关闭状态';}}public function changeStatus(){$this->mediator->changeService();}public function addMediator($mediator){$this->mediator = $mediator;}public function shift(){$this->status = !$this->status;}
}
// 被仲裁者2
<?phpnamespace App\Service;class SurroundingService
{private $status;private $mediator;public function __construct($status){$this->status = $status;}public function say(){if ($this->status) {echo '开启状态';} else {echo '关闭状态';}}public function addMediator($mediator){$this->mediator = $mediator;}public function changeStatus(){$this->mediator->changeService();}public function shift(){$this->status = !$this->status;}}// 测试
$common = new CommonService();$common->show();$common->sideService->changeStatus();;$common->show();$common->surroundingService->changeStatus();;$common->show();
//结果
15、观察者
特点:根据传入的不同的观察者,执行不同的方法,还是比较容易理解的
// 观察者1
<?phpnamespace App\Service;class SideService
{public function say($word){echo 'side观察器说'.$word;}}// 观察者2
<?phpnamespace App\Service;class SurroundingService
{public function say($word){echo 'surrounding观察器说'.$word;}}// 普通类
<?phpnamespace App\Service;class CommonService
{public $observer;public $word;public function __construct($word,$observer){$this->word = $word;$this->observer = $observer;}public function show(){$this->observer->say($this->word);}}// 测试
$common = new CommonService('haha',new SideService());$common->show();
//结果
16、备忘录模式
特点:比较简单,把需要的信息保存下来,后面使用的时候再取出
// 接口
<?phpnamespace App\Service;interface CommonServiceInterface
{public function record($cache);public function recover();public function clear();
}// 实现
<?phpnamespace App\Service;class CommonService implements CommonServiceInterface
{public $cache;public function record($cache){$this->cache[] = $cache;}public function recover(){print_r($this->cache);}public function clear(){$this->cache = [];}
}// 测试$common = new CommonService();$common->record('获得100金币');$common->record('升级29级');$common->record('获得极品装备');$common->recover();$common->clear();$common->recover();
// 结果
17、状态模式
特点:根据不同的状态,执行不同的操作,跟观察者模式类似,区别是状态模式可以自己管理状态的维护,并且更加专注于状态控制,状态控制策略与仲裁者有相似之处
// 状态接口
<?phpnamespace App\Service;interface CommonServiceInterface
{function checkState($h);
}// 状态实现1
<?phpnamespace App\Service;class SideService implements CommonServiceInterface
{private $service;public function service($service){$this->service = $service;}public function say($word){echo 'side状态说你真好看'.'<br>';}public function checkState($h){if ($h>12) {$this->service->changeStateService(SurroundingService::class);}}
}// 状态接口实现2
<?phpnamespace App\Service;class SurroundingService implements CommonServiceInterface
{private $service;public function service($service){$this->service = $service;}public function say($word){echo 'surrounding状态说你真好看'.'<br>';}public function checkState($h){if ($h<=12) {$this->service->changeStateService(SurroundingService::class);}}
}// 状态管理类
<?phpnamespace App\Service;class CommonService
{public $h;public $stateService;public function __construct($h){$this->h = $h;$this->stateService = new SideService();$this->stateService->service($this);}public function changeStateService($class){$this->stateService = new $class();return $this->stateService;}public function say(){// 检测状态$this->stateService->checkState($this->h);$this->stateService->say('hello world');}
}// 测试
$common = new CommonService(11);$common->say();$common = new CommonService(13);$common->say();
// 结果
18、享元设计模式
特点:提取出具有相似的基础功能,由管理的类去实现调用,跟策略模式相似,区别是享元更加轻量化
// 功能1
<?phpnamespace App\Service;class SideService
{public function out(){echo 'this is side func<br>';}
}// 功能2
<?phpnamespace App\Service;class SurroundingService
{public function out(){echo 'this is surround func';}
}// 管理类
<?phpnamespace App\Service;class CommonService
{public $sideService;public $surroundingService;public $operate;public function __construct($operate){$this->sideService = new SideService();$this->surroundingService = new SurroundingService();$this->operate = $operate;}public function say(){// 检测状态if (property_exists($this,$this->operate)) {$this->{$this->operate}->out();} else {echo '这是普通输出<br>';}}
}// 测试
$common = new CommonService('sideService');$common->say();$common = new CommonService('notFundService');$common->say();
// 结果:
19、代理模式
特点:借鉴了服务器的代理模式,如果可以处理的,直接走目标服务器,如果处理不了的走代理再转发服务器,实现过滤的效果,跟享元模式类似,区别是代理模式更专注与过滤,而享元更关注于基础通用功能的提取
// 目标服务器类1
<?phpnamespace App\Service;class SideService
{public function out(){echo 'this is side func<br>';}
}// 目标服务器类2
<?phpnamespace App\Service;class SurroundingService
{public function out(){echo 'this is surround func';}
}// 代理类
<?phpnamespace App\Service;class CommonService
{public $allowService = ['sideService' => SideService::class, 'surroundingService' => SurroundingService::class];public $proxyService = SurroundingService::class;public $operate;public function __construct($operate){$this->operate = $operate;}public function proxy(){// 代理if ($this->isSupport()) {(new $this->allowService[$this->operate])->out();} else {(new $this->proxyService)->out();}}protected function isSupport(){return array_key_exists($this->operate, $this->allowService);}
}// 测试$common = new CommonService('sideService');$common->proxy();$common = new CommonService('notFundService');$common->proxy();
// 结果
20、命令模式
特点:把执行过的命令类,保存为history,需要的时候可以复现history存储的命令
// 画笑脸类
<?phpnamespace App\Service;class SideService implements CommonServiceInterface
{public function action($className = ''){echo '
理解23种设计模式(php)相关推荐
- 【一文快速理解23种设计模式】
软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.这就不得不提到面向对象OO. 面向对象OO = 面向对象的分析OOA + 面向对象的设计OOD + 面向对象的编程OOP 面向对象的 ...
- 以卖单车为例形象理解23种设计模式
对23种设计模式的初步理解 创建型模式 故事一:取单车 1.我可以通过摩拜单车工厂的Mobike(方法)和MobikeLite方式可以拿到不同类型的单车.-工厂方法模式 2.帮人借车,同事给我发短信叫 ...
- 设计_01_带你理解23种设计模式
文章目录 概念 意义 七大原则 划分 创建型设计模式之单例模式✳-01 定义 特点 结构 实现 问题:为什么推荐使用枚举实现单例? 枚举不能被反射或者反序列化的原因 应用场景 扩展 创建型设计模式之原 ...
- 深入理解23种设计模式(6) -- 桥接模式
基本介绍 桥接模式(Bridge模式)是指:将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变 是一种结构型设计模式 Bridge模式给予类的最小设计原则,通过使用封装.聚合及继承等行为让不同 ...
- 深入理解23种设计模式(14) -- 访问者模式
介绍 访问者模式 (Visitor Pattern) : 封装一些作用于某种数据结构的各元素操作,它可以在不改变数据结构的前提下定义作用于这些元素新的操作. 主要将数据结构与数据操作分离,解决数据结构 ...
- 追MM与设计模式(23种设计模式巧妙解析,趣味理解)
关注"java后端技术全栈" 回复"000"获取优质面试资料 瞎扯一会 大家好,我是老田,今天给大家分享如何通俗易懂的理解设计模式. 设计模式作为我们程序员必备 ...
- 23种设计模式通俗理解
23种设计模式通俗理解 1.根据目的来分 2.根据作用范围来分 3.GoF的23种设计模式的功能 1.FACTORY 工厂方法 2.BUILDER建造者模式 3.FACTORY METHOD抽象工厂 ...
- 23种设计模式总结篇【理解及应用】
23种设计模式的概念及应用总结 目录 一.概述 1.1 模式的三个层次 1.2 GOF设计模式的分类 二.创建型设计模式 2.1 单例模式(Singleton) 2.2 工厂方法和抽象工厂(Facto ...
- 一文快速理解23种经典设计模式
> 对经典的23种设计模式介绍,来判断适合哪种设计模式进行设计 23种设计模式: 第1 部分 适应设计模式 Iterator 模式 迭代器,松耦合 Adapter 模式 适配器模式,使用同样 ...
最新文章
- linux驱动:i2c驱动(三)流程图之注册设备
- java字符编码问题_java 字符编码问题
- java垃圾回收system_java应用性能调优之详解System的gc垃圾回收方法
- 【Android基础】序列化 Serializable vs Parcelable
- python装饰器类-Python 装饰器、类装饰器、属性装饰器
- 【组合数学】生成函数 ( 换元性质 | 求导性质 | 积分性质 )
- java 微信转账 ca_error_C#关于微信红包开发问题:CA证书出错,请登录微信支付商户平台下载证书...
- 了解***的初级阶段---网络信息探测技巧
- Junit_测试概述
- 数据结构与算法之完全二叉树的节点个数
- 数码相框项目之显示一张可放大、缩小、拖拽的图片
- android wpa2 wifi,让Android WiFi支持中文
- 美国称微软在华雇佣数百童工 中方调查否认
- dll反编译工具总结
- 统计报表币种金额_海关总署就全面发布以人民币计价统计数据答问
- 团队展示——我说的都队
- C++ 程序越过windows Defender检测
- 邮件发送错了怎么办?TOM VIP邮箱如何撤回邮件
- 【49.Auth2.0认证与授权过程-微博开放平台认证授权过程-百度开放平台认证授权过程-社交登录实现(微博授权)-分布式Session问题与解决方案-SpringSession整合-Redis】
- 使用 EPUB 制作数字图书(转发)
热门文章