题记:
最近都没怎么好好写题记了,公司感觉太忙了。唉~~
恩,这篇文章贴出来有几点可以学习。
学习的地方:
1日志的重要性。在服务器编程中,日志TM重要了,所以,,,
2怎么设计一个日志类。
3通过这个实例,可以感受设计模式在日常中怎么体现出来的:
这里讲了个依赖倒置。
http://www.itlead.com.cn/article/html/266/2012-03-28/content-8169.shtml
现在的项目越来越复杂,谁也不能保证自己的项目在运行过程中不出现错误,出现错误并不可怕,问题是要及时的排除错误,让项目更加健壮并继续运行。排除这些错误就需要获取错误信息,信息从哪里来呢,一个设计良好的项目,肯定记录了项目运行的日志。那么我们怎么样来设计这个日志类呢?
对于不同的人可能设计出来的方案就不一样,至于孰好孰坏是仁者见仁智者见智。关公面前耍大刀,我也来卖弄下,出出洋相,下面的Log演化过程见证了我的程序员历程,来介绍我的希望大家指正。
1.入行初始感觉写代码很神奇,没有理解封装概念,哪里需要记录日志就在那里写个方法,最后发现很多时候就是复制黏贴,突然有一天项目经理说“现在我们的日志不打算记录在文本文件里面,要把它记录到数据库中”,听后我瞬时崩溃!没有办法一个个改呗,好是费劲还可能有漏网之鱼。
Public void WriteLog() { //代码 }
2.吃一堑长一智,这回我学乖了,意识到了其实记录日志的操作是一样的,于是干脆把它提去出来放在一个单独的类中,然后在项目中使用。
Public class Logger { Public void WriteLog() { //代码 } }
每一处调用方式如下:
Logger log=new Logger(); log. WriteLog();
提取出来后,自我感觉良好,小小满足了下。
3.得瑟、真的不能得瑟啊、一得瑟就有问题,新的要求来了。有时候真的觉得经理的要求是不可理喻 "这个日志类你不能写的太死了,要保证它的可扩展性,我现在可能是要记录在数据库,可能在下一次部署的时候要记录在文本文件或者其它文件格式里面了"。我现在又用不着,至于吗?能解决现在的问题不就可以了吗,要求真多。 没有办法啊,继续冥思苦想……翻阅资料,最后还真的找到了一条设计原则:依赖倒置,具体依赖抽象,抽象不依赖具体。
前面的设计就是每个使用到Logger类的类都是依赖它,这明显不符合依赖倒置原则吗?那为了解除这种耦合、满足依赖倒置原则,只能让类依赖抽象。.net中这种抽象的选择之一就是接口。那就定义一个日志接口,然后日志类实现接口。
Interface ILogger { void WriteLog(); } Public class DBLogger: ILogger { Public void WriteLog() { //代码 } }
每一处调用方式如下:
ILogger log=new DBLogger(); log. WriteLog();
咋一看好像还像那么回事,再仔细一看,还是不行,每一处用到的地方还是要使用ILogger log=new DBLogger(),如果现在要改成File Logger记录日志、还是要在每一个使用的地方更改。烦啊、怎么这么多问题呢!无奈长叹一声。
不过有问题就有解决的办法,既然每次要切换记录日志方式时都要改变实例化日志类的方式、那么就把这个实例化对象的代码 ILogger log=new DBLogger();封装起来,这叫封装变化点,仔细再一想着不就是简单工厂模式吗? 那就动手吧。
Public class LoggerFactoy { Public static ILogger GetLogger(string logType) { //根据logType来实力化具体的类 } }
每一处调用方式如下:
ILogger log= LoggerFactoy. GetLogger(“DBLog”); log. WriteLog();
这下看上去比原来的要好点了。不过还是要传个参数、每次切换日志类型的时候还是要改代码。那能不能不传参数了,那就用配置文件配置使用的日志类型吧
Public class LoggerFactoy { Public static ILogger GetLogger() { string logType=ConfigurationManager.…… //根据logType来实力化具体的类 通过反射来实例化日志对象 } }
每一处调用方式如下:
ILogger log= LoggerFactoy. GetLogger(); log. WriteLog();
好到目前为止Logger类基本上设计完成了,下面是一个简单的设计图