## 常见的设计模式有哪些?
简单说下单例模式,注册树模式,适配模式,策略模式,观察者模式。
**单例模式**
记住三私一公,最容易考察现场撸码的题。
**工厂模式**
~~~
//简单工厂模式
//适用场景:创建对象比较少,业务逻辑不太复杂
<?php
//产品
class bike
{
public function product($destination)
{
print_r($destination);
}
}
class car
{
public function product($destination)
{
print_r($destination);
}
}
//工厂
class simpleFactory
{
public function createBike($obj)
{
return new $obj();
}
}
$factory = new simpleFactory();
$bike = $factory->createBike("bike");
$bike->product("hello,bike");
$car = $factory->createBike("car");
$car->product("hello,car");
?>
~~~
**观察者模式**
~~~
//观察者模式
//适用场景:订阅者通知
//自己对观察者模式对理解:
需求:有事情变化你要通知我
实现:
1、要通知对人必须在我这里注册,否则我不知道要通知谁。
2、想要获取通知的人必须遵守我的规则,实现我指定的通知事件,不然我没办法统一通知,(比如高考查分数,只支持电话查询,你非要微信查我肯定通知不到你)
3、事件发生的时候我会逐一通知你们。
<?php
//定义一个事件产生接口
abstract class genEvent
{
private $ob_servers = [];
//增加观察者
public function addObs($ob_server)
{
$this->ob_servers[] = $ob_server;
}
//通知
public function notify()
{
if(!empty($this->ob_servers))
{
foreach($this->ob_servers as $ob_server)
{
$ob_server->update();
}
}
}
}
//定义观察者接口
interface obServer{
public function update($event_info = null);
}
class obServer1 implements obServer{
public function update($event_info = null){
echo "观察者1 收到执行通知\n";
}
}
class obServer2 implements obServer{
public function update($event_info = null){
echo "观察者2 收到执行通知\n";
}
}
class event extends genEvent{
//事件触发
public function trigger()
{
$this->notify();
}
}
//实现
$event = new event();
$event->addObs(new obServer1());
$event->addObs(new obServer2());
$event->trigger();
?>
~~~
**适配器模式**
~~~
<?php
//定义抽象类
abstract class Toy
{
public abstract function openMouth();
public abstract function closeMouth();
}
//定义dog
class dog extends Toy
{
public function openMouth()
{
echo "Dog open Mouth\n";
}
public function closeMouth()
{
echo "Dog close Mouth\n";
}
}
//cat
class cat extends Toy
{
public function openMouth()
{
echo "Cat open Mouth\n";
}
public function closeMouth()
{
echo "Cat close Mouth\n";
}
}
//红枣狗可以自己判断开关
interface redTarget
{
public function doMouthOpen();
public function doMouthClose();
}
interface greenTarget
{
public function operateMouth($type=0);
}
//组成适配器
class redAdapter implements redTarget
{
private $adaptee;
//初始化对象
public function __construct(Toy $adaptee)
{
$this->adaptee = $adaptee;
}
//委派调用Adaptee的sampleMethod1方法
public function doMouthOpen()
{
$this->adaptee->openMouth();
}
public function doMouthClose()
{
$this->adaptee->closeMouth();
}
}
//组成绿色遥控
class greenAdapter implements greenTarget
{
private $adapter;
//初始化对象
public function __contruct(Toy $adapter)
{
$this->adapter = $adapter;
}
public function operateMouth($type = 0)
{
$type ? $this->adapter->openMouth() : $this->adapter->closeMouth();
}
}
//测试
class testDriver
{
public function run()
{
//实例化玩具狗
$dog = new dog();
$adapter_dog = new redAdapter($dog);
$adapter_dog->doMouthOpen();
$adapter_dog->doMouthClose();
}
}
$test = new testDriver();
$test->run();
?>
~~~
**注册树模式**
~~~
//创建单例
class Single{
public $hash;
static protected $ins=null;
final protected function __construct(){
$this->hash=rand(1,9999);
}
static public function getInstance(){
if (self::$ins instanceof self) {
return self::$ins;
}
self::$ins=new self();
return self::$ins;
}
}
//工厂模式
class RandFactory{
public static function factory(){
return Single::getInstance();
}
}
//注册树
class Register{
protected static $objects;
public static function set($alias,$object){
self::$objects[$alias]=$object;
}
public static function get($alias){
return self::$objects[$alias];
}
public static function _unset($alias){
unset(self::$objects[$alias]);
}
}
//调用
Register::set('rand',RandFactory::factory());
$object=Register::get('rand');
print_r($object);
~~~
## 创建型模式:
对类的实例化过程进行抽象,把对象的创建和使用分离。外界对于这些对象只需要知道它们共同的接口,不需要清楚具体实现细节,使整个系统更加符合单一职责原则。
### 工厂模式:
负责生产其他对象的类或方法。
### 简单工厂模式:
创建包含抽象方法的接口
不同的类继承接口实现抽象方法
新建工厂类包含静态方法,实现不同类的实例化。
调用工厂类:静态方法
单例模式:创建一个并且只能创建一个对象。
只需一个类的对象。(配置,session,db,cache,file)
## 结构性模式:
### 适配器模式: 解决类之间的兼容性问题。
将类的接口转化为特定样式接口,解决类之间的兼容性问题。便于统一管理。
如果代码依赖一些外部的api,或者依赖一些可能会经常更改的类,适用适配器模式。
类似中间类,例如避免基类名称改变后,子类名称也要改变。
组合模式:将对象组合成树形结构,用抽象类规范统一的对外接口。
## 行为型模式:
### 策略模式: 一种问题不同处理方式的封装,根据不同环境选择不同的策略。例如返回不同类型输出。
定义一组相同类型的算法,算法之间独立封装,相互代替。
这些算法是同一类型问题的多种处理方式。每个算法或者处理方法都是一个策略。
在应用中,可以根据不同的环境,选择不同的策略。
举例: 数组的不同的输出方式,可以根据输出环境的不同选择输出方式。
定义策略接口,
不同的策略类继承接口,
定义环境类, 限制构造方法必须为策略接口子类
定义环境类中的公共方法,实现策略接口中的方法
### 观察者模式:发布-订阅模式,被观察者和多个观察者的,一对多对象关系。
被观察者状态发生改变时,所有观察者都会收到通知,并自动更新。
实时事件处理系统,mvc模式的重要组成部分。
当订单创建后,系统发送邮件,短信,生成日志。
如果某订单不需要一部分更新,则造成代码臃肿。
被观察者接口:添加观察者,删除观察者,触发通知notify。
被观察者类:
观察者数组,
添加观察者方法,
删除观察者方法,
提供给观察者的通知方法getstate
订单变化方法addorder,改变状态调用notify
触发通知方法notify,遍历观察者数组,触发统一方法update,
观察者接口:统一处理方法update
观察者1: 继承update方法:调用getstate判断状态
观察者2:以此类推。
执行:
实例化 各个观察者类。
创建订单,添加注册者,然后执行addorder
删除观察者
- 消息队列
- 为什么要用消息队列
- 各种消息队列产品的对比
- 消息队列的优缺点
- 如何保证消息队列的高可用
- 如何保证消息不丢失
- 如何保证消息不会重复消费?如何保证消息的幂等性?
- 如何保证消息消费的顺序性?
- 基于MQ的分布式事务实现
- Beanstalk
- PHP
- 函数
- 基础
- 基础函数题
- OOP思想及原则
- MVC生命周期
- PHP7.X新特性
- PHP8新特性
- PHP垃圾回收机制
- php-fpm相关
- 高级
- 设计模式
- 排序算法
- 正则
- OOP代码基础
- PHP运行原理
- zavl
- 网络协议new
- 一面
- TCP和UDP
- 常见状态码和代表的意义以及解决方式
- 网络分层和各层有啥协议
- TCP
- http
- 二面
- TCP2
- DNS
- Mysql
- 锁
- 索引
- 事务
- 高可用?高并发?集群?
- 其他
- 主从复制
- 主从复制数据延迟
- SQL的语⾔分类
- mysqlQuestions
- Redis
- redis-question
- redis为什么那么快
- redis的优缺点
- redis的数据类型和使用场景
- redis的数据持久化
- 过期策略和淘汰机制
- 缓存穿透、缓存击穿、缓存雪崩
- redis的事务
- redis的主从复制
- redis集群架构的理解
- redis的事件模型
- redis的数据类型、编码、数据结构
- Redis连接时的connect与pconnect的区别是什么?
- redis的分布式锁
- 缓存一致性问题
- redis变慢的原因
- 集群情况下,节点较少时数据分布不均匀怎么办?
- redis 和 memcached 的区别?
- 基本算法
- MysqlNew
- 索引new
- 事务new
- 锁new
- 日志new
- 主从复制new
- 树结构
- mysql其他问题
- 删除
- 主从配置
- 五种IO模型
- Kafka
- Nginx
- trait
- genergtor 生成器
- 如何实现手机扫码登录功能
- laravel框架的生命周期