2010-07-28 6 views
2

나는 리팩토링하고 싶은 비교적 큰 레거시 메서드를 가지고 있습니다. Michael Feathers의 "Legacy Code Effective With Effective With Legacy Code"에 명시된대로 "Bulleted method"유형에 적합하기 때문에 직선적 인 방식으로 여러 순차적 방법으로 분할 될 수 있습니다. 그러나 각각의 순차적 인 단계는 일부 로그 메시지를 출력하고 메시지 자체는 단계 자체보다 훨씬 많은 데이터를 필요로합니다. 그래서 메서드를 추출하려고 할 때, 결국 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)까지 증가합니다. 그리고 그것은 가장 극단적 인 경우는 아니며, 처음 엿볼 수 있습니다. 어떤 방법으로 리팩터링해야합니까?

+1

우리가 볼 수 있습니까? 로그 도우미 메서드가 추가 데이터를 가져 와서 로깅을 위해 메서드에 전달하는 단일 문자열/개체를 반환하도록 할 수 있습니다. 또는 로깅에 필요한 모든 항목을 하나의 배열이나 해시에 넣은 다음 전달하십시오. – CaffGeek

+0

리팩터링을 통해 무엇을 달성하려고합니까? –

+0

나는 그 방법의 부분과 유사한 스 니펫을 작성하려고 노력할 것이다. – Rorick

답변

6

새싹 류. 로깅을 헬퍼 클래스로 돌리고 필요할 때마다 필요한 모든 데이터를 제공하십시오.

업데이트 : 제시된 예를 들어 변수를 사용하여이, 내가 예를 들어, 부를 것이다, myLogger.setDevice(device) 즉시 장치가 채워진로; adminCode, clientData 등에 대해서도 마찬가지입니다. 로거 로그 메서드를 traceDeviceAdminCodeAndPhone()logFirstRegistration()과 같이 지정합니다. 여기서는 자체 인스턴스 변수를 사용합니다. 변수가 변하면 어느 곳에서나 로거에 다시 입력하십시오. 이제 추출하는 메소드와 새 메소드에서 직접 필요로하는 매개 변수 (더 이상은 필요하지 않음)에 로거를 전달하면 로거는 추출 된 메소드 내에서 필요한 것을 계속보고 할 수 있습니다.

또한 로거가 메서드에 너무 친숙한 것처럼 보이기 시작하면 대안을 새 클래스에 추출하고 일부 로컬 변수를 인스턴스 변수로 변환 할 수 있습니다. 로거는 단순히 새로운 클래스에 값을 요청할 수 있습니다. 하지만 로거 클래스는 도우미로서 작고 영향력이 적은 리팩터링 일 수 있습니다. 좋은지 나쁜지는 어디로 가고 싶은지에 달려 있습니다.

+0

이 질문에 대한 답변은 정확하지만 좀 더 자세한 내용을 사용할 수 있습니다. –

+1

@Peter 이에 따라 업데이트되었습니다. 그게 더 좋은가요? –

+0

예. 감사합니다. –

3

칼의 대답은 확실하지만 적어도 다른 좋은 옵션이 있다고 생각합니다.

로깅 프레임 워크 중 일부는 소위 Mapped Diagnostic Context을 지원합니다. 키 - 값 쌍을 저장할 수 있으며 프레임 워크는 구성 파일에 지정한 형식으로 로그 행에 추가 할 수 있습니다. 같은 데이터를 기록하는 것처럼 보이기 때문에 (적어도 흔적을 남기고) 나는 그것이 당신의 요구에 꽤 잘 맞을 것이라고 생각합니다.

지원하는 프레임 워크 중 일부는 Log4J, SLF4J이지만 "비 Java"세계에서도 유사한 것이 있어야한다고 생각합니다.

  • 이하, 청소기 코드
  • 필요가 없습니다 만 로깅에 필요한 PARAMS을 통과 :

    난 당신이/대신 추적의 메시지를 적어도 그것을 사용할 수 있고 꽤 많이 얻을 것이라고 생각

  • 균일하게 기록 된 메시지 (사용자가 지정한 패턴에 따라 프레임 워크에 의해 형식화 됨)
  • 더 유연함 - 기록되는 설정은 what/when/how가 제어됩니다.

한 가지를 주목해야합니다 :

  • 이 쉽게되지 않습니다/너무 잘 작동하지 않을 수 있습니다 : 키/값 쌍은 일반적으로 몇 가지 가능한 함정에 이르게 스레드 지역 변수에 저장됩니다 스레드를 자주 전환하는 경우에 사용하십시오.
  • 일반적으로 정리 (원하지 않는 값 제거)가 프레임 워크에 의해 자동으로 수행되는 것이 아니라 작업입니다.