`
dcj3sjt126com
  • 浏览: 1825470 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

PHP常用设计模式单例, 工厂, 观察者, 责任链, 装饰, 策略,适配,桥接模式

    博客分类:
  • PHP
阅读更多
// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法
abstract class Tiger {
    public abstract function climb();
}

class XTiger extends Tiger {
    public function  climb() {
        echo '摔下来';
    }
}

class MTiger extends Tiger {
    public function climb() {
        echo '爬到树顶';
    }
}

class Client {
    public static function call(Tiger $animal) {
        $animal->climb();
    }
}

Client::call(new XTiger());
Client::call(new MTiger());

 

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头

// 共同接口
interface db {
    function conn();
}

// 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
    public function conn() {
        echo '连上了MySQL';
    }
}

class dbsqlite implements db{
    public function conn() {
        echo '连上了sqlite';
    }
}

// 客户端, 看不到dbmysql, dbsqlite的内部细节的, 只知道上两个类实现了db接口.

$db = new dbmysql();
$db->conn();          // 因为知道这个类实现了db接口, 所以知道有这个conn类

$sqlite = new dbsqlite();
$sqlite->conn();

// 我连我有哪些类我都不希望告诉客户端, 那么怎么进一步进行封装
// 发生连接的双方知道的越少越好, 你还知道我有两个类

  

// 简单工厂

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头

// 共同接口
interface db {
    function conn();
}

// 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
    public function conn() {
        echo '连上了MySQL';
    }
}

class dbsqlite implements db{
    public function conn() {
        echo '连上了sqlite';
    }
}

// 简单工厂
class Factory {
    public static function createDB($type) {
        if($type == 'mysql') {
            return new dbmysql();
        } elseif ($type=='sqlite') {
            return new dbsqlite();
        } else {
            throw new Exception("Error db type", 1);
        }
    }
}

// 客户端现在不知道对方到底有哪些类名了
// 只知道对方开放了一个Factory::createDB方法
// 方法允许传递数据库名称

$mysql = Factory::createDB('mysql');
$mysql->conn();

$sqlite = Factory::createDB('sqlite');
$sqlite->conn();

// 原本你知道服务器端的两个类名, 觉得你知道的太多, 再封装起来, 只给一个通道, 更好的适应变化
// 如果以后新增oracle类型, 怎么办?
// 我们PHP随手改了就行, 像JAVA打包一次很麻烦, 又要修改服务端内容
// 服务端要修改Factory的内容(在java, c++中, 改后还得再编译)
// 这个时候就想如何来改进呢
// 在OOD(面向对象设计)的法则中, 有重要的开闭原则--对于修改是封闭的, 对于扩展是开放的.
// 你可以新增一个源代码, 不要修改旧的代码

//现在用第二种办法, 叫工厂方法

 

// 共同接口
interface db {
    function conn();
}

interface Factory {
    function createDB();
}

// 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
    public function conn() {
        echo '连上了MySQL';
    }
}

class dbsqlite implements db{
    public function conn() {
        echo '连上了sqlite';
    }
}

class mysqliFactory implements Factory{
    public function createDB() {
        return new dbmysql();
    }
}

class sqliteFactory implements Factory {
    public function createDB() {
        return new dbsqlite();
    }
}

// 服务器端添加oracle类
// 前面的代码不用改
// 我就新增一个数据库驱动类和一个工厂, 这样就避免了对源代码的修改
class dboracle implements db {
    public function conn() {
        echo '连接上了oracle';
    }
}

class oracleFactory implements Factory {
    public function createDB() {
        return new dboracle();
    }
}


// 客户端开始, 对方给了两个api, 一个db的api, 一个是创造数据库的api
$fact = new mysqliFactory();
$db = $fact->createDB();
$db->conn();

$fact = new sqliteFactory();
$db = $fact->createDB();
$db->conn();

 

// 单例
// 一般来说一个中小型网站一个db去连接数据库就行了
// 想想, 能不能只有一个db类, 一个upload类, 一个cookie类
// 类肯定只有一个, 如何保证类的实例也只有一个

// 2个对象是同一个的时候才全等

// 单例模式

class single {
    protected static $ins = null;

    // 控制权限, 封锁new操作, 把大门关上了, 需要留一个小窗户
    // 方法前加final, 则方法不能被覆盖, 类前加final, 则类不能被继承
    final protected function __construct() {}
    // 防clone
    final protected function __clone(){}
    
    //留一个接口来new对象
    public static function getIns() {
        if(self::$ins == null) {
            self::$ins = new self();
        }
        return self::$ins;
    }
}

$s1 = single::getIns();
$s2 = single::getIns();

if ($s1 === $s2) {
    echo '是一个对象';
} else {
    echo '不是一个对象';
}

 

<!DOCTYPE HTML>
<html>

<head>
    <title>colour_blue</title>
    <meta name="description" content="website description" />
    <meta name="keywords" content="website keywords, website keywords" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style>
        div{
            margin:10px;
            width:500px;
            height:200px;
            border: 1px solid green;
        }
        #content {
        }
        #ad {
        }
    </style>
    <script>
        function t() {
            var sel = document.getElementsByTagName('select')[0];
//            alert(sel.value);
            if(sel.value == 'male') {
                document.getElementById('content').style.backgroundColor = 'gray';
                document.getElementById('ad').innerHTML = '汽车';
            } else if(sel.value=='female') {
                document.getElementById('content').style.backgroundColor = 'pink';
                document.getElementById('ad').innerHTML = '减肥';
            }
        }

        /**
         *
         * 观察上述代码, 如果新增了一个study区, 在切换时, 学习内容也要随之切换, 那么, 就需要改动T函数! 对于修改又开放了.
         * 思考---如果需要新监听footer区, 如何能不改原来的代码, 而只增加
         */
    </script>
</head>

<body>
    <h1>面向过程, 不用任务来切换</h1>
    <select name="" id="" onchange="t()">
        <option value="male">男式风格</option>
        <option value="female">女式风格</option>
    </select>

    <div id="content">我是内容</div>
    <div id="ad">我是广告</div>


</body>
</html>

 

// 比如登录, 在登录的时候出于安全考虑要记录上次登录时间
// 出于商业考虑, 给你推荐商品

class user implements SplSubject {
    public $lognum;
    public $hobby;

    protected $observers = null;

    public function __construct($hobby) {
        $this->lognum = rand(1, 10);
        $this->hobby = $hobby;
        $this->observers = new SplObjectStorage();
    }

    public function login() {
        // 操作session
        $this->notify();
    }

    public function attach(SplObserver $observer) {
        $this->observers->attach($observer);
    }

    public function detach(SplObserver $observer) {
        $this->observers->detach($observer);
    }

    public function notify() {
        $this->observers->rewind();
        while($this->observers->valid()) {
            $observer = $this->observers->current();
            $observer->update($this);
            $this->observers->next();
        }
    }
}

class secrity implements SplObserver {
    public function update(SplSubject $subject) {
        if($subject->lognum < 3) {
            echo '这是第'.$subject->lognum.'次安全登录';
        } else {
            echo '这是第'.$subject->lognum.'次登录,异常';
        }
    }
}

class ad implements SplObserver {
    public function update(SplSubject $subject) {
        if($subject->hobby == 'sports') {
            echo '台湾英锦赛';
        } else {
            echo '好好学习天天向上';
        }
    }
}

// 实施观察
$user = new user('sports');
$user->attach(new secrity());
$user->attach(new ad());

$user->login();

 

<!DOCTYPE HTML>
<html>

<head>
    <title>colour_blue</title>
    <meta name="description" content="website description" />
    <meta name="keywords" content="website keywords, website keywords" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style>
        div{
            margin:10px;
            width:500px;
            height:200px;
            border: 1px solid green;
        }
        #content {
        }
        #ad {
        }
    </style>
</head>

<body>
<h1>观察者模式</h1>
<select name="" id="">
    <option value="male">男式风格</option>
    <option value="female">女式风格</option>
</select>
<input type="button" onclick="t1()" value="观察尾部" />
<input type="button" onclick="t2()" value="别观察尾部了" />
<div id="content">我是内容</div>
<div id="ad">我是广告</div>
<div id="study">学习</div>


<script>
    // 服务器端
    var sel = document.getElementsByTagName('select')[0];
    sel.observers = {};

    sel.attach = function(key, obj) {
        sel.observers[key] = obj;
    }
    sel.detach = function(key) {
        delete this.observers[key];
    }
    sel.onchange = sel.notify = function(){
        for(var key in this.observers) {
            this.observers[key].update(this);
        }
    }

    // 客户端
        var content = document.getElementById('content');
    content.update = function(observer) {
        if(observer.value == 'male'){
            this.style.backgroundColor = 'gray';
        } else if(observer.value=='female'){
            this.style.backgroundColor = 'pink';
        }
    }
    sel.attach('content', content);

    var ad = document.getElementById('ad');
    ad.update = function(observer) {
        if(observer.value == 'male'){
            this.innerHTML = '汽车';
        } else if(observer.value=='female'){
            this.innerHTML = '减肥';
        }
    }
    sel.attach('ad', ad);

    // 客户端和服务端实现了解耦
    // 后面有一个学习区, 如果状态改变了, 学习区也要变化

    var study = document.getElementById('study');
    study.update = function(observer) {
        if(observer.value == 'male'){
            this.innerHTML = '学习计算机';
        } else if(observer.value=='female'){
            this.innerHTML = '学习美容';
        }
    }
    sel.attach('study', study);


    //如果想不观察尾部了
    function t1() {
        sel.atach('study', study);
    }
    function t2() {
        sel.detach('study');
    }
</script>
</body>
</html>

 

.html
<!DOCTYPE HTML>
<html>

<head>
    <title>colour_blue</title>
    <meta name="description" content="website description" />
    <meta name="keywords" content="website keywords, website keywords" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style>
        div{
            margin:10px;
            width:500px;
            height:200px;
            border: 1px solid green;
        }
        #content {
        }
        #ad {
        }
    </style>
</head>

<body>
<h2>责任链模式举报过程</h2>
<form action="10.php" method="post">
    <select name="jubao" id="">
        <option value="1">粗口</option>
        <option value="2">黄赌毒</option>
        <option value="3">分裂国家</option>
    </select>
    <button type="submit">举报</button>
</form>

</body>
</html>

.php
<?php
header('Content-type: text/html; charset=utf-8');

//版主
class board {
    protected $power = 1;
    protected $top = 'admin';

    public function process($lev) {
        if($lev <= $this->power) {
            echo '版主删贴';
        } else {
            $top = new $this->top;
            $top->process($lev);
        }
    }
}

class admin {
    protected $power = 2;
    protected $top = 'police';

    public function process($lev) {
        if($lev <= $this->power) {
            echo '管理员封账号';
        } else {
            $top = new $this->top;
            $top->process($lev);
        }
    }
}

class police {
    protected $power;
    protected $top = null;
    public function process($lev) {
        echo '抓起来';
    }
}


$lev = $_POST['jubao']+0;
$judge = new board();
$judge->process($lev);

 

.html
<!DOCTYPE HTML>
<html>

<head>
    <title>colour_blue</title>
    <meta name="description" content="website description" />
    <meta name="keywords" content="website keywords, website keywords" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style>
        div{
            margin:10px;
            width:500px;
            height:200px;
            border: 1px solid green;
        }
        #content {
        }
        #ad {
        }
    </style>
</head>

<body>
<h2>面向过程完成举报过程</h2>
<form action="09.php" method="post">
    <select name="jubao" id="">
        <option value="1">粗口</option>
        <option value="2">黄赌毒</option>
        <option value="3">分裂国家</option>
    </select>
    <button type="submit">举报</button>
</form>

</body>
</html>

.php
<?php
header('Content-type: text/html; charset=utf-8');
$lev = $_POST['jubao'];

//版主
class board {
    public function process() {
        echo '版主删贴';
    }
}

class admin {
    public function process() {
        echo '管理员封账号';
    }
}

class police {
    public function process() {
        echo '抓起来';
    }
}

if ($lev == 1) {
    $judge = new board();
    $judge->process();
} elseif($lev==2) {
    $judge = new admin();
    $judge->process();
} elseif($lev==3) {
    $judge = new police();
    $judge->process();
}

// 处理的不够优雅, 现在还是面向过程的写法, 面向过程和面向对象混合了
// 如果以后在两个等级中间要添加一个等级应该怎么办

 

.html
<!DOCTYPE HTML>
<html>

<head>
    <title>colour_blue</title>
    <meta name="description" content="website description" />
    <meta name="keywords" content="website keywords, website keywords" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style>
        div{
            margin:10px;
            width:500px;
            height:200px;
            border: 1px solid green;
        }
        #content {
        }
        #ad {
        }
    </style>
</head>

<body>
<h2>策略模式 和工厂方法的区别只是在逻辑上的区别, 也叫聚合</h2>
<form action="11.php" method="post">

    <input type="text" name="op1" />
    <select name="op" id="">
        <option value="add">+</option>
        <option value="sub">-</option>
        <option value="mul">*</option>
        <option value="div">/</option>
    </select>
    <input type="text" name="op2" />
    <button type="submit">计算</button>
</form>

</body>
</html>

.php
<?php
/**
 * Created by PhpStorm.
 * User: michaeldu
 * Date: 15/7/15
 * Time: 上午12:11
 */

interface Math {
    public function calc($op1, $op2);
}

class MathAdd implements Math{

    public function calc($op1, $op2)
    {
        return $op1 + $op2;
    }
}
class MathSub implements Math{

    public function calc($op1, $op2)
    {
        return $op1 - $op2;
    }
}
class MathMul implements Math{

    public function calc($op1, $op2)
    {
        return $op1 * $op2;
    }
}
class MathDiv implements Math{

    public function calc($op1, $op2)
    {
        return $op1 / $op2;
    }
}

//封装一个虚拟计算器, 统一计算接口

class CMath {
    protected $calc = null;

    public function __construct($type) {
        $calc = 'Math'. ucfirst($type);
        $this->calc = new $calc();
    }

    public function calc($op1, $op2) {
        return $this->calc->calc($op1, $op2);
    }
}

$type = $_POST['op'];
$cmath = new CMath($type);
echo $cmath->calc($_POST['op1'], $_POST['op2']);
// 装饰器模式 decorator

class article {
    protected $content;

    public function __construct($content)
    {
        $this->content = $content;
    }

    public function decorator() {
        return $this->content;
    }
}

$art = new article("好好学习");
echo $art->decorator();

// 文章需要小编加摘要

class BianArticle extends article {
    public function summary() {
        return $this->content.'小编加了摘要';
    }
}

$art = new BianArticle('好好学习');
echo $art->summary();

// 又请了SEO人员, 要对文章进行description处理...
class SEOArticle extends BianArticle {
    public function seo() {
        //...
    }
}

// 又有了广告部
class ADArticle extends  SEOArticle {
    // 层次越来越深, 目的却只是给文章加各种内容
}

  

// 装饰器模式做文章修饰功能

class BaseArt {
    protected $content;
    protected $art;

    public function __construct($content) {
        $this->content = $content;
    }

    public function decorator() {
        return $this->content;
    }
}

//编辑文章摘要

class BianArt extends BaseArt {
    public function __construct(BaseArt $art) {
        $this->art = $art;
    }
    public function decorator() {
        return $this->content = $this->art->decorator() . '小编摘要';
    }
}

// SEO
class SEOArt Extends BaseArt {
    public function __construct(BaseArt $art) {
        $this->art = $art;
    }
    public function decorator() {
        return $this->content = $this->art->decorator() . 'SEO关键词';
    }
}

$b = new SEOArt(new BianArt(new BaseArt('天天向上')));
echo $b->decorator();

$b = new BianArt(new SEOArt(new BaseArt('天天向上')));
echo $b->decorator();

// 装饰的先后顺序可以随便换, 新增多少个装饰者都很方便

// 基类负责创建对象
// 子类负责装饰

 

// 适配器模式

// 服务器端代码
class weather {
    public static function show() {
        $today = [
            'tep' => 28,
            'wind' => 7,
            'sun' => 'sunny',
        ];
        return serialize($today);
    }
}

// 客户端调用

$weather = unserialize(weather::show());
echo '温度: ',$weather['tep'],'<br />';
echo '风力: ',$weather['wind'],'<br />';
echo 'sun: ',$weather['sun'],'<br />';

// 来了一批手机上的java客户端 , 不认识PHP的串化行后的字符串, 怎么办?
// 把服务器端代码改了? 旧的客户端会受影响

// 旧的类和函数都不让修改, 如何来进行扩展

// 增加一个适配器
class AdapterWeather extends weather {
    public static function show() {
        //拿到旧数据
        $today = parent::show();
        // 然后开始转换
        $today = unserialize($today);
        $today = json_encode($today);
        return $today;
    }
}

// ==== java, python再来调用就不怕了, 通过适配器调用

$weather = AdapterWeather::show();
$w = json_decode($weather);
echo '温度: ',$w->tep,'<br />';
echo '风力: ',$w->wind,'<br />';
echo 'sun: ',$w->sun,'<br />';

// 没有修改旧的方法, 这样就没有影响旧的客户端
// 没有修改旧的类, 说明没有违反开闭原则

 

// 桥接模式 bridge 尝试

// 论坛给用户发信息, 可以是站内短信, email, 手机

// 本来只需要发站内短信, 后来又需要发email
// 一个类只做一件事, 我们把他做成一个接口或者抽象类, 具体的发送由具体的子类实现

interface msg {
    public function send($to, $content);
}

class zn implements msg {

    public function send($to, $content)
    {
        echo '站内信给', $to, ' 内容是: ', $content;
    }
}

// 有一天要改造, 要发email
class email implements msg {

    public function send($to, $content)
    {
        echo 'email给', $to, ' 内容是: ', $content;
    }
}

// 后来要发短信
class sms implements msg {

    public function send($to, $content)
    {
        echo '短信给', $to, ' 内容是: ', $content;
    }
}

// 后来内容也丰富了, 分普通, 加急, 特急
// 子类就爆炸了, 像数据的三范式一样, 如果完全遵循解耦是不行了
/*
class zncommon extends zn;
class znwarn extends zn;
class zndanger extends zn;

class emailcomm extends email;
class emailwarn extends email;
class emaildanger extends email;
....
*/

/**
 * 思考:
 * 信的发送方式是一个变化因素
 * 信的紧急程度是一个变化因素,
 * 为了不修改父类, 只好考虑2个因素的组织, 不停产生新类....
 */

 

abstract class info {
    protected $send = null;

    public function __construct($send) {
        $this->send = $send;
    }

    abstract public function msg($content);
    public function send($to, $content){
        $content = $this->msg($content);
        $this->send->send($to, $content);
    }
}

class zn {
    public function send($to, $content) {
        echo '站内给: ', $to, '内容是: ', $content;
    }
}

class email {
    public function send($to, $content) {
        echo 'email给: ', $to, '内容是: ', $content;
    }
}

class sms {
    public function send($to, $content) {
        echo 'sms给: ', $to, '内容是: ', $content;
    }
}

class commoninfo extends info{
    public function msg($content) {
        return '普通'. $content;
    }
}

class warninfo  extends info{
    public function msg($content) {
        return '紧急'.$content;
    }
}

class dangerinfo  extends info{
    public function msg($content) {
        return '紧急'.$content;
    }
}

// 用站内发普通信息
$commoninfo = new commoninfo(new zn());
$commoninfo->send('小明', '吃饭了');

//给小刚发紧急手机短信消息
$dangerinfo = new dangerinfo(new sms());
$dangerinfo->send('小刚', '失火了');

// 本来需要3x3个类
// 现在只需要3+3个类了
// 现在耦合了, view中不写逻辑, 数据库三范式, 老有相同的字段, 为了速度, 之前的设计模式都是在解耦, 现在反而增加了耦合, 是为了防止子类爆炸

 

分享到:
评论

相关推荐

    设计模式面面观(10):桥接模式(Bridge Pattern)-结构型模式

    创建型模式 (100%) 设计模式面面观(8):创建型模式总结 (100%) 设计模式面面观(9):适配器模式(Adapter Pattern)-结构型模式 (100%) 设计模式面面观(10):桥接模式(Bridge Pattern)-结构型模式 ...

    《设计模式实训教程》【PPT+类图与代码+样章】

    4.2.2桥接模式实例之跨平台视频播放器 4.2.3组合模式实例之杀毒软件 4.2.4装饰模式实例之界面显示构件库 4.2.5外观模式实例之文件加密 4.2.6享元模式实例之围棋棋子 4.2.7代理模式实例之日志记录代理 4.3实训...

    OBJECTIVE-C编程之道 IOS设计模式解析电子书+源代码

    责任链17.1 何为责任链模式17.2 何时使用责任链模式17.3 在RPG游戏中使用责任链模式17.4 总结第七部分 算法封装第18章 模板方法18.1 何为模板方法模式18.2 何时使用模板方法18.3 利用模板方法制作三明治18.4 保证...

    java设计模式选择题复习题.doc

    举出一个生活中使用装饰者模式的例子,用程序实现思路 举个生活中的例子,俗话说"人在衣着马在鞍",把这就话用装饰者模式的语境翻译一下 ,"人通过漂亮的衣服装饰后,男人变帅了,女人变漂亮了;"。对应 上面的类图...

    IOS设计模式全解析与Objective-C编程之道之 .pdf.zip

    iOS 设计模式,文字通过代码与例子,清晰的讲解了设计模式:工厂模式、单列、接口适配、桥接、中介者、观察者、抽象集合、迭代器、行为扩展、算法封装、责任链、装饰、访问者、模板方法、命令、性能与对象访问、代理...

    源码:阎宏设计模式光盘

    com.javapatterns.chainofresp 责任链模式 com.javapatterns.chainofresp.scheduler 专题:定时器与击鼓传花 com.javapatterns.command 命令模式 com.javapatterns.command.swingundo 专题:Swing库中的命令撤销...

    常用的几种设计模式代码,类图和实验截图

    几种常用的设计模式的代码,类图,实验截图。其中包括的设计模式有简单工厂模式、原型模式之创建工作周报、工厂方法模式日志记录器、适配器模式实例之算法适配等!!

    C++设计模式原理与实战视频课

    C++设计模式原理与实战视频课 1-1 课程介绍 1-2 导论UML和设计模式导论 2-1 简单工厂方法的定义场景与实现-针对接口编程的设计思想剖析 2-2 简单工厂实用工程技术:C++对象动态创建技术与配置化开发 2-3 单例模式的...

    【Java设计模式】(2)策略模式Strategy

    【Java设计模式】(2)策略模式Strategy

    C#23种设计模式_示例源代码及PDF

    责任链模式: 在责任链模式中,很多对象由每一个对象对其下家的引用而接起来形成一条 责任链模式 链。 请求在这个链上传递, 直到链上的某一个对象决定处理此请求。 客户并不知道链上的 哪 一个对象最终处理这个请求...

    浅析java常用的设计模式(doc-23页).doc

    浅析java常用的设计模式(doc 23页) 1、工厂模式:客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即 可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修 改。如:如何...

    DotNet设计模式—适配器、桥接与外观三模式之间的关系

    这几天一直在研究各种各样的设计模式,在学习适配器模式、桥接模式和外观模式模式的时候,发现他们之间存在着一定的关系,实际上模式不适单一存在的,在我们的现实编程生活中往往是几种模式结合使用的。1.适配器...

    DesignPattern.zip

    iOS 设计模式,桥接,观察者,装饰,工厂,适配,抽象工厂。。。。

    设计模式之适配器模式(Adapter Pattern)

    设计模式之适配器模式(Adapter Pattern) 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

    二十三种设计模式【PDF版】

    设计模式之 Chain of Responsibility(责任链) 各司其职的类串成一串,好象击鼓传花,当然如果自己能完成,就不要推委给下一个. 设计模式之 Mediator(中介) Mediator 很象十字路口的红绿灯,每个车辆只需和红绿灯交互...

    基于SpringBoot为基础做的Binlog,MQ数据适配,解析,校验,托管,异常捕获,为使用者提供监听器模式和责任链模式

    为了更好的 完善,提升,B/S架构系统的性能和实用性,系统...MQ数据适配,解析,校验,托管,异常捕获,为使用者提供两种方案,监听器模式和责任链模式并提供出 crud接口 使用者只需要按自己的需求同步到其它容器中即可

    javascript常用的设计模式

    本文主要介绍了javascript常用的设计模式:单例模式;工厂模式;适配模式;外观模式。下面跟着小编一起来看下吧

Global site tag (gtag.js) - Google Analytics