代码之家  ›  专栏  ›  技术社区  ›  Rorick

日志语句阻止重构:如何帮助这一点?

  •  3
  • Rorick  · 技术社区  · 14 年前

    我有一些比较大的遗留方法需要重构。它符合michaelfeathers的“有效地处理遗留代码”中指定的“项目符号方法”类型,因此可以以相当直接的方式将它拆分为几个顺序方法。但是它的每一个连续步骤都会输出一些日志消息,形成该消息需要比该步骤本身更多的数据。所以当我尝试提取方法时,我最终得到的方法有,比如说,6个参数。如果我删除了那些日志语句,那么我将拥有一个只有一个参数的方法。所以我实际上不能重构任何东西。我不能直接删除日志语句。

    方法的一部分如下所示:

    // much of code before
    Device device = getDevice(deviceID);
    boolean isFirstRegistration = false;
    
    if (device == null) {
        /*logger.trace(
                "DeviceId", deviceID,
                "ADM", adminCode,
                "Phone", clientData.getPhone()
        );
        logger.info("First registration of the device. Device ID - " + deviceID);*/
        isFirstRegistration = true;
    } else {
        /*logger.trace(
                "DeviceId", deviceID,
                "ADM", adminCode,
                "Phone", clientData.getPhone()
        );
        logger.info("Device ID - " + deviceID
                + " has been previously registered by adminCode: "
                + device.getAdminCode());*/
    }
    // much of code after
    

    如您所见,注释掉了日志记录语句。在这种情况下,我可以提取方法 boolean isFirstRegistration(String deviceId) boolean isFirstRegistration(String deviceId, String adminCode, ClientData clientData) . 这并不是最极端的情况,只是第一眼看到的情况。你知道我应该如何重构这样的方法吗?

    2 回复  |  直到 14 年前
        1
  •  6
  •   Carl Manaster pakore    14 年前

    萌芽类。将日志记录转换为助手类,并根据需要向其提供所需的所有数据。

    更新: myLogger.setDevice(device) 一旦设备被填充;类似地,对于adminCode、clientData等,给出logger日志方法,如 traceDeviceAdminCodeAndPhone() logFirstRegistration() ,其中它使用自己的实例变量。在变量发生变化的任何地方,再次将它们输入记录器。现在,将记录器传递给要提取的方法,再加上新方法直接需要的任何参数(但仅此而已),记录器仍然可以从提取的方法中报告所需的内容。

    另外,如果您的记录器开始觉得您的方法过于熟悉,另一种方法是将方法提取到一个新类中,并将一些局部变量转换为实例变量;然后,记录器可以简单地向新类请求值,而不是保留它们本身。但是logger类作为一个助手可能是一个更小、影响更小的重构。这是好是坏取决于你想去哪里。

        2
  •  3
  •   Sandor Murakozi    14 年前

    Mapped Diagnostic Context

    一些确实支持它的框架是Log4J、SLF4J,但我想在“非Java”世界中也应该存在类似的东西。

    我想你至少可以用它来代替跟踪信息,这样会得到很多好处:

    • 不需要传递仅用于日志记录的参数
    • 更大的灵活性-什么/什么时候/如何被记录在日志配置(它所属的地方)中进行控制。

    需要注意的一点是:键/值对通常存储在线程局部变量中,这会导致一些可能的陷阱:

    • 如果经常切换线程,它可能不会工作得太好/不容易使用
    • 通常清理(删除不需要的值)是您的任务,而不是由框架自动完成。