封装工具库的最佳实践

封装工具库的最佳实践_第1张图片
图片发自App


    我们在使用第三方库的时候通常使用直接加载依赖的方式来调用,比如使用日志工具--monolog。在这里我试图做这种使用第三方库的最佳实践。我们的设计考量标准就是代码的可维护、易用、性能等方面来考虑,从设计模式来说就是考虑高内聚低耦合。

    如果我们只是直接加载了日志类来调用,那么我们肯定要在类里面按照这个库的规则写大量的代码,这很难看。我们不如按照适合使用习惯的方式来封装调用的方法。于是

namespace app\Library\Utils;

use Monolog\Logger;

use Monolog\Handler\RotatingFileHandler;

use Monolog\Handler\StreamHandler;

use Monolog\Handler\FirePHPHandler;

/**

* Class Logger

* @package Libraries\Utils

* @author Bardeen

*/

calss Logger

{

    public static $CHANNEL_MAP = [

            'baidumap' => '/log/map/',

            'default' => '/log/normal/'

    ];

    private static $channel = [];

  /**

    * @param $channel

    * @param $message

    * @param $priority

    * @return $this

*/

    public function log($channel_name,$message,$context,$priority){

        //init

        if(!isset(self::$channel[$channel_name])){

            self::$channel[$channel_name] = new Logger($channel_name);

                $log_path = isset(self::$CHANNEL_MAP[$channel_name])?RUNTIME_PATH . self::$CHANNEL_MAP[$channel_name] . DS:RUNTIME_PATH . self::$CHANNEL_MAP['default'];

                self::$channel[$channel_name]->pushHandler(new RotatingFileHandler($log_path .$channel_name.".log", $priority));

        }

        $logger  = self::$channel[$channel_name];

        //action

        $context = is_array($context)?$context:[$context];

        $logger->addRecord($priority, $message, $context);

        return $this;

}

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function errorLog($channel,$message,$context){

        $priority = Logger::ERROR;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function warningLog($channel,$message,$context){

        $priority = Logger::WARNING;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function infoLog($channel,$message,$context){

        $priority = Logger::INFO;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function noticeLog($channel,$message,$context){

        $priority = Logger::NOTICE;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function criticalLog($channel,$message,$context){

        $priority = Logger::CRITICAL;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function alertLog($channel,$message,$context){

        $priority = Logger::CRITICAL;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function emergancyLog($channel,$message,$context){

        $priority = Logger::EMERGENCY;

        return $this->log($channel,$message,$context,$priority);

    }

}

    好,便利类封装好了,那我们是不是就可以直接加载依赖使用?不行!其实这个东西我们可以做的更好。打印日志从业务逻辑上来说应该是类的固有属性,从高内聚的角度来说我们应该使用聚合的方式,但是我们不使用传统的聚合方式而是使用php的新特性trait。这还不够,为了性能我们使用单例享元工厂来获取原生log类。于是有以下两个文件:

LoggerTrait.php

namespace app\Library\Utils;

use Monolog\Logger;

/**

* Class LoggerTrait

* @package Libraries\Utils

* @author Bardeen

*/

trait LoggerTrait

{

    /**

    * @param $channel

    * @param $message

    * @param $priority    * @return $this

*/

    public function log($channel,$message,$context,$priority){

        //init

        $logger_flyweight = FlyweightLogger::getInstance();

        $logger = $logger_flyweight::setChannel($channel,$priority);

        //action

        $context = is_array($context)?$context:[$context];

        $logger->addRecord($priority, $message, $context);

        return $this;

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function errorLog($channel,$message,$context){

        $priority = Logger::ERROR;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function warningLog($channel,$message,$context){

        $priority = Logger::WARNING;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function infoLog($channel,$message,$context){

        $priority = Logger::INFO;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function noticeLog($channel,$message,$context){

        $priority = Logger::NOTICE;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function criticalLog($channel,$message,$context){

        $priority = Logger::CRITICAL;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function alertLog($channel,$message,$context){

        $priority = Logger::CRITICAL;

        return $this->log($channel,$message,$context,$priority);

    }

    /**

    * @param $channel

    * @param $message

    * @return $this

*/

    public function emergancyLog($channel,$message,$context){

        $priority = Logger::EMERGENCY;

        return $this->log($channel,$message,$context,$priority);

    }

}


namespace app\Library\Utils;

use Monolog\Logger;

use Monolog\Handler\RotatingFileHandler;

use Monolog\Handler\StreamHandler;

use Monolog\Handler\FirePHPHandler;

class FlyweightLogger{

    public static $instance = null;

    public static $CHANNEL_MAP = [

        'baidumap' => '/log/map/',

        'default' => '/log/normal/'

    ];

    private static $channel = [];

    final private function __construct(){}

    final private function __clone(){}

    /**

    * @return QueueAggregate

*/

    final public static function getInstance(){

        if(null === self::$instance){

            self::$instance = new FlyweightLogger();

        }

        return self::$instance;

    }

    /**

    * @param null $service_name

    * @return Application|null

*/

    static function getChannel($channel_name){

        $return = false;

        isset(self::$channel[$channel_name]) && $return = self::$channel[$channel_name];

        return $return;

    }

    static function setChannel($channel_name,$priority){

        if(!isset(self::$channel[$channel_name])){

            self::$channel[$channel_name] = new Logger($channel_name);

            $log_path = isset(self::$CHANNEL_MAP[$channel_name])?RUNTIME_PATH . self::$CHANNEL_MAP[$channel_name] . DS:RUNTIME_PATH . self::$CHANNEL_MAP['default'];

            self::$channel[$channel_name]->pushHandler(new RotatingFileHandler($log_path .$channel_name.".log", $priority));

        }

        return self::$channel[$channel_name];

    }

}

好了,完美。现在我们可以用use来实现这个trait。

你可能感兴趣的:(封装工具库的最佳实践)