zoukankan      html  css  js  c++  java
  • 模板方法模式 + 观察者模式 + 简单工厂模式 + 单例模式 + 适配器模式实现一个简单的数据表读写

    实现功能:

    依据类的cache属性,对数据表的读要缓存起来,对数据表的写需要清除缓存.

    数据表根据属性字段来决定是否缓存

    可以更换数据库链接方式,比如可以随时更换为mysql或mysqli()

    当插入数据时给出一个通知或者提示,可以外部配置通知

    一.数据操作接口

    /**
     * Interface db
     */
    
    interface dbInterface
    {
        // 此处为简便起见,只定义读取所有记录和写入记录
        public function all();
        public function create(array $attributes);
    }
    

      

    二.数据库实现类(单例模式)

    1.mysqli

    class DbMySQLi implements dbInterface
    {
        private $link;
        private static $instance;
        private $table;
    
        private function __construct()
        {
            $this->link = mysqli_connect('localhost', 'root', 'root', 'test');
        }
    
        public static function getInstance()
        {
            if (is_null(self::$instance)) {
                self::$instance = new self();
            }
            return self::$instance;
        }
    
        public function setTable($table)
        {
            $this->table = $table;
        }
    
        /**
         * @return array|null
         */
        public function all()
        {
            $res =  mysqli_query($this->link, "select * from {$this->table}");
            $data = [];
            while ($row = mysqli_fetch_assoc($res)) {
                $data[] = $row;
            }
            return $data;
        }
    
        /**
         * @param array $attributes
         * @return bool|mysqli_result
         */
        public function create(array $attributes)
        {
            $keys   = array_keys($attributes);
            $values = array_values($attributes);
            foreach ($keys as $key => $val) {
                $keys[$key] = "`{$val}`";
            }
    
            foreach ($values as $key => $val) {
                $values[$key] = "'{$val}'";
            }
    
            $insertKey = implode(',', $keys);
            $insertValue = implode(',', $values);
    
            mysqli_query($this->link, "insert into {$this->table}($insertKey) values({$insertValue})");
            return mysqli_insert_id($this->link);
        }
    
        public function closeLink()
        {
            if ($this->link) {
                mysqli_close($this->link);
            }
        }
    }
    

      

    2.mysql

    class DbMySQL implements dbInterface
    {
        private $link;
        private static $instance;
        private $table;
    
        private function __construct()
        {
            $this->link = mysql_connect('localhost', 'root', 'root', 'test');
        }
    
        public static function getInstance()
        {
            if (is_null(self::$instance)) {
                self::$instance = new self();
            }
            return self::$instance;
        }
    
        public function setTable($table)
        {
            $this->table = $table;
        }
    
        /**
         * @return array|null
         */
        public function all()
        {
            $res =  mysql_query("select * from {$this->table}", $this->link);
            $data = [];
            while ($row = mysql_fetch_assoc($res)) {
                $data[] = $row;
            }
            return $data;
        }
    
        /**
         * @param array $attributes
         * @return bool|mysqli_result
         */
        public function create(array $attributes)
        {
            $keys   = array_keys($attributes);
            $values = array_values($attributes);
            foreach ($keys as $key => $val) {
                $keys[$key] = "`{$val}`";
            }
    
            foreach ($values as $key => $val) {
                $values[$key] = "'{$val}'";
            }
    
            $insertKey = implode(',', $keys);
            $insertValue = implode(',', $values);
    
            mysql_query("insert into {$this->table}($insertKey) values({$insertValue})", $this->link);
            return mysql_insert_id($this->link);
        }
    
        public function closeLink()
        {
            if ($this->link) {
                mysql_close($this->link);
            }
        }
    }
    

      

    三.配置类

    class Config
    {
        const DB_TYPE = 'mysql';
    }
    

      

    四.cache接口(适配器模式)

    interface Cache
    {
        public function clearCache();
        public function setCache($data);
        public function getCache();
        public function getKey();
    }
    

      

    文件缓存实现,此处用trait特性实现适配:

    trait FileCacheTrait
    {
        public function clearCache()
        {
            @unlink($_SERVER['DOCUMENT_ROOT'] . '/cache-' . $this->getKey() . '.php');
        }
    
        public function setCache($data)
        {
            $file = $_SERVER['DOCUMENT_ROOT'] . '/cache-' . $this->getKey() . '.php';
            $cache = '<?php' . "
    ";
            $cache .= 'return ';
            $cache .= var_export($data, true);
            $cache .= ';';
            file_put_contents($file, $cache);
        }
    
        public function getCache()
        {
            $file = $_SERVER['DOCUMENT_ROOT'] . '/cache-' . $this->getKey() . '.php';
            if (is_file($file)) {
                return require $file;
            }
            return false;
        }
    
        public function getKey()
        {
            return md5($_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING']);
        }
    }
    

      

    五.通知(观察者)

    接口:

    interface ObserverInterface
    {
        public function fire(Model $model);
    }
    

      

    实现:

    class Observer implements ObserverInterface
    {
        public function fire(Model $model)
        {
            $model = $model->model();
            echo "创建{$model->name}, id:{$model->id}";
        }
    }
    

      

    六.Model虚拟类:通用数据操作

    abstract class Model
    {
        protected $observers = []; //被观察者数组
        protected $db;
        protected $model;
        protected $cache = false;
    
        public function __construct()
        {
            // 简单工厂模式
            if (Config::DB_TYPE == 'mysql') {
                $this->db = DbMySQLi::getInstance($this->table());
            } else {
                $this->db = DbMySQL::getInstance($this->table());
            }
            $this->db->setTable($this->table());
        }
    
        public function all()
        {
            if ($this->cache && $cache = $this->getCache()) {
                return $cache;
            }
            $data = $this->db->all();
    
            if ($this->cache) {
                $this->setCache($data);
            }
            return $data;
        }
    
        public function create(array $attributes)
        {
            $insertId = $this->db->create($attributes);
            // 清除缓存
            if ($this->cache) {
                $this->clearCache();
            }
    
            $this->fill(array_merge($attributes, ['id' => $insertId]));
    
            // 如果有设置created被观察者,直接调用
            if (isset($this->observers['created'])) {
                $this->observers['created']->fire($this);
            }
    
            return $insertId;
        }
    
        public function __destruct()
        {
            $this->db->closeLink();
        }
    
        public function addObserver($key, ObserverInterface $observer) {
            $this->observers[$key] = $observer;
        }
    
        public function fill(array $attributes)
        {
            $this->model =  (object) $attributes;
        }
    
        public function model()
        {
            return $this->model;
        }
    
        abstract public function table();
    }
    

      

    七.model实现类

    class User extends Model implements Cache
    {
        // 配置缓存可用
        protected $cache = true;
        use FileCacheTrait;
    
        public function table()
        {
            return 'user';
        }
    }
    

      

    八.App类:从外部负责给model绑定被观察者

    class App
    {
        public static function observer(Model $model)
        {
            $model->addObserver('created', new Observer($model));
        }
    }
    

      

    调用:

    $user = new User();
    App::observer($user);
    $user->create(['name' => 'test']);
    

     

    附加:

    如果要用闭包调用,则Model类对应部分改为:

    // 如果有设置created被观察者,直接调用
            if (isset($this->observers['created'])) {
                if ($this->observers['created'] instanceof Closure) {
                    call_user_func($this->observers['created'], $this);
                } else {
                    $this->observers['created']->fire($this);
                }
            }
    

      

    App改为:

    class App
    {
        public static function observer(Model $model)
        {
            $model->addObserver('created', function () use($model) {
                echo "创建{$model->model()->name}, id:{$model->model()->id}";
            });
        }
    }
    

      

  • 相关阅读:
    install jprofiler for ubuntu
    android manifest相关属性
    install nginx for ubuntu
    Android shape
    mobile web for no cookie session
    Android布局属性
    什么是强类型,强类型集合
    radl (三) (转)
    几个.net 基础问题,自己回答了一些,请大家指教
    c#接口和抽象类的区别
  • 原文地址:https://www.cnblogs.com/itfenqing/p/8728735.html
Copyright © 2011-2022 走看看