首页 / 知识
关于不可知的语言:在OOP上下文中正确登录
2023-04-16 19:00:00

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和电锯是一种完美的即用型解决方案-如果您不只是在学习,请使用它们。
全球可访问的记录器是测试的难题。如果需要"集中式"日志记录工具,请在程序启动时将其创建,然后将其注入需要日志记录的类/方法中。
如何用模拟代替它? 更好:
我一直使用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类,该类封装了日志记录/存储过程。这样,您可以在需要时仅实例化 这是我的首选解决方案,因为如果要通过数据库进行日志记录,则只需注入数据库。如果您正在使用文件,则无需注入任何依赖项。您也可以完全避免使用全局或静态日志记录类/函数。 来自Microsoft的Pattern&Practices组的企业库日志记录应用程序块是在OOP环境中实现日志记录框架的一个很好的例子。他们拥有一些有关如何实现其日志记录应用程序块的出色文档,所有源代码均可供您自己查看或修改。 还有其他类似的实现:log4net,log4j,log4cxx
他们实现企业库日志记录应用程序块的方式是拥有一个静态 |
最新内容
相关内容
linux控制台编程命令?
linux控制台编程命令?,系统,工具,环境,命令,名称,标准,不了,工作,发行,基础,shell编程(掌握Linux命令行工具)1、在开始Shell编程之前,我们需要linux编程常用命令?
linux编程常用命令?,系统,工作,信息,命令,地址,管理,工具,网络,基础,目录,linux基本操作命令linux常用命令有pwd命令、cd命令、ls命令、cat命linux常用命令c语言?
linux常用命令c语言?,系统,工作,信息,管理,基础,命令,地址,目录,简介,时间,linux常用的20个命令?系统管理相关命令:df、top、free、quota、at、linux命令行模式登录?
linux命令行模式登录?,系统,密码,信息,状态,情况,终端,环境,管理,电脑,位置,linux,按了ctrl+alt+F1,进入了类似纯命令行的界面,让输入login信linux命令行退出登录?
linux命令行退出登录?,状态,平台,软件,异常,密码,系统,命令,程序,模式,文件,linux怎么退出命令行Ctrl + d 相信这个快捷键在很多交换式情景下linux命令行设置语言?
linux命令行设置语言?,系统,管理,环境,国家,工具,电脑,软件,文化,底部,语言,linux命令行下怎样改变语言1、将内容改为:LANG=zh_CN.UTF-8LANGUAGlinux登录系统的命令?
linux登录系统的命令?,系统,工作,地址,名称,网络,密码,信息,服务,软件,资料,linux系统下的Login,Logout,Reboot,Halt,Exit,Poweroff,Shutdownlinux使用命令改语言?
linux使用命令改语言?,系统,工作,管理,电脑,设备,字符集,中文,命令,语言,虚拟机,请问linux虚拟机装好以后怎么把英文改成中文?1、vmware设置中linux远程登录的命令?
linux远程登录的命令?,地址,密码,系统,名称,服务,网络,命令,软件,工作,服务器,远程登陆LINUX的命令是什么?填写登录用户名在弹出的SSH用户身份linux命令行登录上网?
linux命令行登录上网?,网络,系统,工具,设备,地址,最新,工作,数据,网址,信息,linux系统下怎么连接网络1、虚拟机linux如何联网首先需要打开虚拟c语言写linux命令?
c语言写linux命令?,系统,工具,代码,智能,工作,环境,情况,位置,命令,文件,如何在C语言编程中调用linux系统终端下的命令1、C语言有一个system函linux汇编语言命令?
linux汇编语言命令?,系统,地址,代码,数据,网络,平台,平均,位置,灵活,工作,汇编语言指令的基本格式是什么1、有以下几种基本格式:标号,又称为指令