其中一个设计的反面教材 -- Log4J

宏哥 发布于 2012/06/28 14:38
阅读 557
收藏 1

我忘记这个家伙到底有多大了, 但是我用C语言来表达,就是这样:

#define LOG_INFO 1
#define LOG_NOTICE 2
#define LOG_DEBUG 4
#define LOG_FATAL 8
#define LOG_ALL 15

#define D_PRINTF(fmt,arg...){\
        if((g_debug_level|LOG_FATAL )& fmt){\
                fprintf(stderr,arg); \
        }\
}
可以强制LOG_FATAL打印, 如果应用程序员写入日志,定向stderr即可.
可以指定 log level,用于控制运行时是否输出日志.

我不知道为什么 Log4J这种东西, 为什么大得和bullshit差不多?
是不是因为用了OOP和设计模式?

以下是问题补充:

@宏哥:下面给出了PHP,Python的实现. 永不用java. (2012/06/28 16:23)
加载中
0
xmdeepdata
xmdeepdata
你用得太少了。我见过有人用它来控制流程(例如:DEBUG模式访问测试数据库,INFO以上访问正式数据库),哈哈,虽然有点狗血,但是居然很管用。
0
宏哥
宏哥

引用来自“yzjiang”的答案

你用得太少了。我见过有人用它来控制流程(例如:DEBUG模式访问测试数据库,INFO以上访问正式数据库),哈哈,虽然有点狗血,但是居然很管用。

if ( g_debug_level |  LOG_DEBUG ){

    访问测试数据库

}else{

    访问真实数据库

}

0
Andre.Z
Andre.Z

把上面的翻译一下,变成别的语言,log4a、log4b、log4c。。。。成了
下面这2个怎么算?
http://www.oschina.net/p/zlog
http://www.oschina.net/p/log4cplus

0
逝水fox
逝水fox

log4j是有一些反应OO和设计模式设计思想的东西在里面。但这不是他里面类多和包大的根本原因。我觉得宏哥说的太绝对了。往简单的说功能确实是。因为log4j定位是给别人用的做功能支持,他必须要适应不同的需求,比如不同的配置方式,不同的输出格式(他不止输出文本行的,也有XML格式),给使用者能够方便扩展的空间,考虑的就相对的更繁琐。

有些时候确实觉得有些开源项目功能太繁琐不想用他自带的包,自己也会写个公司自己用的日志类之类的工具类,就像宏哥范例给的那样确实简单,一两个静态方法搞定,没什么复杂的继承关系,但是是否适合其他公司用,就无法保证了。也许需求变了又要重新写代码。OO和模式理解了确实用的恰到好处的话,确实能解决一些经常变化需求的东西。还是那句话,不能为要用模式而套模式。

一楼那种用日志等级来控制程序的流程,就像是用异常来控制程序的流程一样的,虽然有些时候确实方便了自己,但是后面接手的人看代码的时候就难说了,而且控制流程也不是一开始设计它们的本意。

0
宏哥
宏哥

引用来自“Andre.Z”的答案

把上面的翻译一下,变成别的语言,log4a、log4b、log4c。。。。成了
下面这2个怎么算?
http://www.oschina.net/p/zlog
http://www.oschina.net/p/log4cplus

所以说,开源基本上都是闭门造车.  造出一堆麻烦.解决的问题,其实都是很简单的问题.

先把他们复杂化,然后造出很多类, 搞出很多类之间的乱伦关系.基本上都是这个模式.

0
宏哥
宏哥

引用来自“逝水fox”的答案

log4j是有一些反应OO和设计模式设计思想的东西在里面。但这不是他里面类多和包大的根本原因。我觉得宏哥说的太绝对了。往简单的说功能确实是。因为log4j定位是给别人用的做功能支持,他必须要适应不同的需求,比如不同的配置方式,不同的输出格式(他不止输出文本行的,也有XML格式),给使用者能够方便扩展的空间,考虑的就相对的更繁琐。

有些时候确实觉得有些开源项目功能太繁琐不想用他自带的包,自己也会写个公司自己用的日志类之类的工具类,就像宏哥范例给的那样确实简单,一两个静态方法搞定,没什么复杂的继承关系,但是是否适合其他公司用,就无法保证了。也许需求变了又要重新写代码。OO和模式理解了确实用的恰到好处的话,确实能解决一些经常变化需求的东西。还是那句话,不能为要用模式而套模式。

一楼那种用日志等级来控制程序的流程,就像是用异常来控制程序的流程一样的,虽然有些时候确实方便了自己,但是后面接手的人看代码的时候就难说了,而且控制流程也不是一开始设计它们的本意。

只有简洁的东西,才能真正适应复杂的需求.

Keep it simple , but not simpler.

php 版本:

<?PHP

Class Log{

 

 

        public static function alert($s){

                Core::$log->add(Core::ALERT,$s);

        }

 

        public static function critical($s){

                Core::$log->add(Core::CRITICAL,$s);

        }

 

 

        public static function error($s){

                Core::$log->add(Core::ERROR,$s);

        }

 

        public static function warn($s){

                Core::$log->add(Core::WARNING,$s);

        }

 

        public static function notice($s){

                Core::$log->add(Core::NOTICE,$s);

        }

 

        public static function info($s){

                Core::$log->add(Core::INFO,$s);

        }

 

        public static function debug($s){

                Core::$log->add(Core::DEBUG,$s);

        }

 

        /*

         * Logging the Exception to allow debug

         * @param Exception

         * @return String string to descripe the exception

         */

        public static function e(Exception $e){

                $_msg = Core::exception_text($e);

                self::debug('Exception:'.PHP_EOL.$_msg);

                return $_msg;

        }

 

        /*

         * Output the excption and die

         * Debug and trace the exception

         * Ensure not to product debug on Production

         */

        public static function d(Exception $e){

                if(Core::$environment != Core::PRODUCTION){

                        Core::exception_handler($e);

                        ob_end_flush();

                        die();

                }

        }

}


0
宏哥
宏哥

引用来自“逝水fox”的答案

log4j是有一些反应OO和设计模式设计思想的东西在里面。但这不是他里面类多和包大的根本原因。我觉得宏哥说的太绝对了。往简单的说功能确实是。因为log4j定位是给别人用的做功能支持,他必须要适应不同的需求,比如不同的配置方式,不同的输出格式(他不止输出文本行的,也有XML格式),给使用者能够方便扩展的空间,考虑的就相对的更繁琐。

有些时候确实觉得有些开源项目功能太繁琐不想用他自带的包,自己也会写个公司自己用的日志类之类的工具类,就像宏哥范例给的那样确实简单,一两个静态方法搞定,没什么复杂的继承关系,但是是否适合其他公司用,就无法保证了。也许需求变了又要重新写代码。OO和模式理解了确实用的恰到好处的话,确实能解决一些经常变化需求的东西。还是那句话,不能为要用模式而套模式。

一楼那种用日志等级来控制程序的流程,就像是用异常来控制程序的流程一样的,虽然有些时候确实方便了自己,但是后面接手的人看代码的时候就难说了,而且控制流程也不是一开始设计它们的本意。

python 版本

import sys

INFO = 1

NOTICE = 2

DEBUG = 4

FATAL = 8

ALL = 15

 

#defalut log level DEBUG

loglevel = INFO

def p(runlevel,*args):

if sys.stderr:

if(runlevel&(loglevel|FATAL)):

print(*args,file=sys.stderr)

sys.stderr.flush()

#debug info

def D(*args):

p(DEBUG,*args)

 

#Info

def I(*args):

p(DEBUG,*args)

 

#Notice

def N(*args):

p(NOTICE,*args)

 

#Fatal

def F(*args):

p(FATAL,*args)

返回顶部
顶部