## 常見的設計模式有哪些?
簡單說下單例模式,注冊樹模式,適配模式,策略模式,觀察者模式。
**單例模式**
記住三私一公,最容易考察現場擼碼的題。
**工廠模式**
~~~
//簡單工廠模式
//適用場景:創建對象比較少,業務邏輯不太復雜
<?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框架的生命周期