关于不可知的语言:在OOP上下文中正确登录

关于不可知的语言:在OOP上下文中正确登录

Proper Logging in OOP context

自从我开始学习面向对象的编程以来,这就是我一直在苦苦挣扎的问题:一个人应该如何用"适当的" OOP代码实现记录器?

我的意思是,一个对象具有一种方法,我们希望代码中的所有其他对象都可以访问; 此方法将输出到console / file / every,我们将使用它进行日志记录-因此,此对象将是logger对象。

我们不想将记录器对象建立为全局变量,因为全局变量不好,对吧? 但是我们也不想让在每个对象中调用的每个方法的参数中都通过logger对象。

在大学里,当我提起这件事给教授时,他实际上无法给我答案。 我意识到实际上有一些软件包(例如Java)可以实现此功能。 不过,我最终要寻找的是如何正确地并以OOP方式自己实现这一点的知识。


您确实希望将记录器建立为全局变量,因为全局变量还不错。至少,它们并不是天生的坏。记录器是正确使用全局可访问对象的一个??很好的例子。如果需要更多信息,请阅读有关Singleton设计模式的信息。


有一些经过深思熟虑的解决方案。其中一些涉及绕过OO,并使用另一种机制(AOP)。

日志记录并不能很好地适合OO(没关系,并非所有事情都可以)。如果您必须自己实现它,建议您在每个类的顶部实例化" Log":

private final log = new Log(this);

然后您所有的日志记录调用都是微不足道的:log.print(" Hey");

这比单例更易于使用。

让记录器确定您要传入的类,然后使用该类来注释日志。由于您有了日志实例,因此可以执行以下操作:

log.addTag(" Bill");

日志可以将标签帐单添加到每个条目,以便您可以对显示进行更好的过滤。

log4j和电锯是一种完美的即用型解决方案-如果您不只是在学习,请使用它们。


全球可访问的记录器是测试的难题。如果需要"集中式"日志记录工具,请在程序启动时将其创建,然后将其注入需要日志记录的类/方法中。
您如何测试使用类似以下内容的方法:

1
2
3
4
public class MyLogger
{
    public static void Log(String Message) {}
}

如何用模拟代替它?

更好:

1
2
3
4
5
6
7
8
9
public interface ILog
{
    void Log(String message);
}

public class MyLog : ILog
{
    public void Log(String message) {}
}

我一直使用Singleton模式来实现日志记录对象。


将记录器创建为单例类,然后使用静态方法访问它。


我认为您应该为此使用AOP(面向方面??的编程),而不是OOP。


我认为,在实践中,单例/全局方法很好用。最好全局对象只是一个框架,您可以将不同的侦听器(观察者模式)连接到该框架,例如一种用于控制台输出,一种用于数据库输出,一种用于Windows EventLog输出,等等。

不过要提防过度设计,我发现实际上只有一个带有全局方法的单个类可以很好地工作。

或者,您可以使用您提供的特定框架的基础结构。


您可以看一下Singleton模式。


我全都支持AOP和log4 *。这确实帮助了我们。
例如,谷歌给我这篇文章。您可以尝试在该主题上进行更多搜索。


为避免全局变量,我建议创建一个全局注册表,并在此注册您的全局变量。

对于日志记录,我更喜欢提供单例类或提供一些静态日志记录方法的类。

实际上,我将使用现有的日志记录框架之一。


(IMHO)"记录"的发生方式不是解决方案设计的一部分,它更是运行于任何环境(例如Java中的System和Calendar)的一部分。

您的"好"解决方案是尽可能松散地耦合到任何特定日志记录实现的解决方案,因此请考虑接口。我将在此处查看有关Sun如何解决该问题的示例,因为他们可能提出了一个非常好的设计,并为您提供了学习的全部机会!


使用静态类,它具有最少的开销,并且可以在简单的程序集引用中从所有项目类型访问

请注意,单例是等效的,但涉及不必要的分配

如果您使用多个应用程序域,请注意,可能需要一个代理对象才能从主域以外的域访问静态类。

另外,如果您有多个线程,则可能需要锁定日志记录功能以避免交错输出

仅IMHO日志记录是不够的,这就是为什么我写CALM的原因

祝好运!


也许以透明的方式插入Logging宁愿属于"面向方面的编程"习惯用法。但是我们在这里谈论OO设计...

我认为Singleton模式可能是最有用的:您可以通过LoggingService类的公共静态方法从任何上下文访问Logging服务。

尽管这看起来很像一个全局变量,但事实并非如此:它被正确地封装在singleton类中,并且不是每个人都可以访问它。这使您即使在运行时也可以更改日志记录的处理方式,但可以保护日志记录免受"恶意"代码的影响。

在我工作的系统中,我们创建了多个Logging'singletons',以便能够区分来自不同子系统的消息。这些可以在运行时打开/关闭,可以定义过滤器,可以写入文件...命名。


过去,我通过将日志记录类的实例添加到需要访问日志记录的类的基类(或接口(如果语言支持)的话)来解决此问题。当您记录某些内容时,记录器会查看当前的调用堆栈,并从中确定调用代码,设置有关记录语句的适当元数据(源方法,代码行(如果可用),记录的类等)。多个类具有记录器,并且不需要使用可以自动确定的元数据来专门配置记录器。

这确实增加了相当大的开销,因此对于生产日志记录而言,它不一定是明智的选择,但是如果您以这种方式进行设计,则可以有条件地禁用记录器的各个方面。

实际上,我大部分时间都使用commons-logging(我在Java中做了很多工作),但是我在上面描述的设计中有一些方面是有益的。使用健壮的日志系统(其他人已经花费大量时间进行调试)的好处超过了对可以被视为更简洁设计的需求(显然这是主观的,尤其是鉴于本文中没有详细说明)。

我遇到了静态记录器的问题,导致了permgen内存问题(至少,我认为这就是问题所在),所以我可能很快会再讨论记录器。


另一种可能的解决方案是拥有一个Log类,该类封装了日志记录/存储过程。这样,您可以在需要时仅实例化new Log();,而不必使用单例。

这是我的首选解决方案,因为如果要通过数据库进行日志记录,则只需注入数据库。如果您正在使用文件,则无需注入任何依赖项。您也可以完全避免使用全局或静态日志记录类/函数。


来自Microsoft的Pattern&Practices组的企业库日志记录应用程序块是在OOP环境中实现日志记录框架的一个很好的例子。他们拥有一些有关如何实现其日志记录应用程序块的出色文档,所有源代码均可供您自己查看或修改。

还有其他类似的实现:log4net,log4j,log4cxx

他们实现企业库日志记录应用程序块的方式是拥有一个静态Logger类,该类具有许多实际执行日志操作的方法。如果您正在研究模式,那么这可能是Singleton模式的更好用途之一。


推荐阅读

    linux控制台编程命令?

    linux控制台编程命令?,系统,工具,环境,命令,名称,标准,不了,工作,发行,基础,s

    linux编程常用命令?

    linux编程常用命令?,系统,工作,信息,命令,地址,管理,工具,网络,基础,目录,lin

    linux常用命令c语言?

    linux常用命令c语言?,系统,工作,信息,管理,基础,命令,地址,目录,简介,时间,li

    linux命令行模式登录?

    linux命令行模式登录?,系统,密码,信息,状态,情况,终端,环境,管理,电脑,位置,l

    linux命令行退出登录?

    linux命令行退出登录?,状态,平台,软件,异常,密码,系统,命令,程序,模式,文件,l

    linux命令行设置语言?

    linux命令行设置语言?,系统,管理,环境,国家,工具,电脑,软件,文化,底部,语言,l

    linux登录系统的命令?

    linux登录系统的命令?,系统,工作,地址,名称,网络,密码,信息,服务,软件,资料,l

    linux使用命令改语言?

    linux使用命令改语言?,系统,工作,管理,电脑,设备,字符集,中文,命令,语言,虚

    linux远程登录的命令?

    linux远程登录的命令?,地址,密码,系统,名称,服务,网络,命令,软件,工作,服务

    linux命令行登录上网?

    linux命令行登录上网?,网络,系统,工具,设备,地址,最新,工作,数据,网址,信息,l

    c语言写linux命令?

    c语言写linux命令?,系统,工具,代码,智能,工作,环境,情况,位置,命令,文件,如何

    linux汇编语言命令?

    linux汇编语言命令?,系统,地址,代码,数据,网络,平台,平均,位置,灵活,工作,汇

    linux汇编语言命令?

    linux汇编语言命令?,系统,地址,代码,数据,网络,平台,平均,位置,灵活,工作,汇

    编程解析linux命令?

    编程解析linux命令?,系统,标准,基础,设备,发行,电脑,工具,密码,名字,适当,如

    linux用户登录的命令?

    linux用户登录的命令?,系统,信息,工作,地址,时间,密码,名称,命令,电脑,软件,l

    linux命令用账号登录?

    linux命令用账号登录?,密码,系统,管理,地址,软件,联系方式,状态,用户,用户

    linux使用命令的方法?

    linux使用命令的方法?,系统,信息,工具,标准,数据,命令,左下角,目录,文件夹,

    linux命令是什么语言?

    linux命令是什么语言?,系统,环境,代码,传播,管理,语言,操作系统,源码,自由,

    linux命令界面登录?

    linux命令界面登录?,系统,工具,密码,数字,设备,终端,软件,工作,服务,状态,lin

    linux命令行图形编程?

    linux命令行图形编程?,系统,不了,情况,密码,工具,地方,百度,管理,图形界面,