문제

다음은 제가 객체지향 프로그래밍을 처음 배우기 시작한 이래로 제가 씨름해 온 문제입니다."적절한" OOP 코드에서 로거를 어떻게 구현해야 합니까?

이는 코드의 다른 모든 개체가 액세스할 수 있도록 하는 메서드가 있는 개체를 의미합니다.이 메소드는 로깅에 사용할 콘솔/파일/무엇이든 출력하므로 이 객체는 로거 객체가 됩니다.

전역 변수는 나쁘기 때문에 로거 개체를 전역 변수로 설정하고 싶지 않습니다. 그렇죠?그러나 우리는 또한 모든 단일 개체에서 호출하는 모든 단일 메서드의 매개 변수에 로거 개체를 전달하는 것을 원하지 않습니다.

대학에서 제가 이 문제를 교수님께 이야기했을 때 그는 실제로 제게 대답을 해주실 수 없었습니다.실제로 이 기능을 구현할 수 있는 패키지(예: Java)가 있다는 것을 알고 있습니다.하지만 내가 궁극적으로 찾고 있는 것은 이것을 OOP 방식으로 적절하게 구현하는 방법에 대한 지식입니다.

도움이 되었습니까?

해결책

하다 전역 변수는 로거를 전역 변수로 설정하려고 합니다. ~ 아니다 나쁜.적어도 본질적으로 나쁘지는 않습니다.로거는 전역적으로 접근 가능한 객체를 적절하게 사용하는 좋은 예입니다.더 많은 정보를 원하시면 싱글턴 디자인 패턴을 읽어보세요.

다른 팁

매우 잘 고안된 몇 가지 솔루션이 있습니다.일부에는 OO를 우회하고 다른 메커니즘(AOP)을 사용하는 것이 포함됩니다.

로깅은 실제로 OO에 그다지 적합하지 않습니다(괜찮습니다. 모든 것이 그렇지는 않습니다).직접 구현해야 한다면 각 클래스 상단에 "Log"를 인스턴스화하는 것이 좋습니다.

개인 최종 로그=새 로그(this);

그러면 모든 로깅 호출이 간단해집니다.log.print("안녕");

싱글톤보다 사용하기가 훨씬 쉽습니다.

로거가 어떤 클래스를 전달하는지 파악하고 이를 사용하여 로그에 주석을 달도록 하세요.그러면 로그 인스턴스가 있으므로 다음과 같은 작업을 수행할 수 있습니다.

log.addTag("청구서");

그리고 로그는 각 항목에 bill 태그를 추가하여 디스플레이에 대한 더 나은 필터링을 구현할 수 있습니다.

log4j와 전기톱은 즉시 사용 가능한 완벽한 솔루션입니다. 학술적인 내용만 다루는 것이 아니라면 이를 사용하십시오.

전 세계적으로 접근 가능한 로거는 테스트하기가 어렵습니다."중앙 집중식" 로깅 기능이 필요한 경우 프로그램 시작 시 이를 생성하고 로깅이 필요한 클래스/메서드에 삽입하세요.다음과 같은 것을 사용하는 메소드를 어떻게 테스트합니까?

public class MyLogger 
{
    public static void Log(String Message) {}
}

모의로 대체하는 방법은 무엇입니까?

더 나은:

public interface ILog 
{
    void Log(String message);
}

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

저는 항상 싱글톤 패턴을 사용하여 로깅 개체를 구현했습니다.

싱글턴 패턴을 볼 수 있습니다.

로거를 싱글톤 클래스로 생성한 다음 정적 메서드를 사용하여 액세스합니다.

이를 위해서는 OOP보다는 AOP(Aspect-Oriented 프로그래밍)를 사용해야 한다고 생각합니다.

실제로는 싱글톤/글로벌 방법이 잘 작동한다고 생각합니다.바람직하게는 전역적인 것은 다른 리스너(관찰자 패턴)를 연결할 수 있는 프레임워크일 뿐입니다.하나는 콘솔 출력용, 하나는 데이터베이스 출력용, 하나는 Windows EventLog 출력용 등입니다.

하지만 과잉 설계에 주의하세요. 실제로 전역 메소드만 사용하는 단일 클래스가 꽤 잘 작동할 수 있다는 것을 알았습니다.

또는 귀하가 작업하는 특정 프레임워크가 제공하는 인프라를 사용할 수도 있습니다.

그만큼 엔터프라이즈 라이브러리 로깅 애플리케이션 블록 Microsoft의 Pattern & Practices 그룹에서 제공하는 내용은 OOP 환경에서 로깅 프레임워크를 구현하는 좋은 예입니다.그들은 로깅 애플리케이션 블록을 구현한 방법에 대한 훌륭한 문서를 보유하고 있으며 모든 소스 코드를 직접 검토하거나 수정할 수 있습니다.

다른 유사한 구현이 있습니다: log4net, log4j, log4cxx

Enterprise Library Logging Application Block을 구현한 방식은 정적을 갖는 것입니다. Logger 실제로 로그 작업을 수행하는 다양한 메서드가 있는 클래스입니다.패턴을 보고 있다면 이는 아마도 싱글턴 패턴을 더 잘 활용하는 것 중 하나일 것입니다.

나는 log4*와 함께 AOP를 지지합니다.이것은 우리에게 정말 도움이 되었습니다.구글이 나에게 준 이 기사 예를 들어.해당 주제에 대해 더 자세히 검색해 볼 수 있습니다.

(IMHO) '로깅'이 발생하는 방식은 솔루션 설계의 일부가 아니라 Java의 시스템 및 달력과 같이 실행 중인 모든 환경의 일부입니다.

'좋은' 솔루션은 가능한 특정 로깅 구현과 느슨하게 결합된 솔루션이므로 인터페이스를 생각하십시오.나는 흔적을 확인해 볼 것이다. 여기 Sun이 꽤 좋은 디자인을 생각해 냈고 여러분이 배울 수 있도록 모든 것을 마련했을 때 어떻게 이 문제를 다루었는지에 대한 예를 들어보세요!

정적 클래스를 사용하면 오버헤드가 가장 적고 간단한 어셈블리 참조 내의 모든 프로젝트 유형에서 액세스할 수 있습니다.

싱글톤은 동일하지만 불필요한 할당이 포함됩니다.

여러 앱 도메인을 사용하는 경우 기본 도메인이 아닌 도메인의 정적 클래스에 액세스하려면 프록시 개체가 필요할 수 있습니다.

또한 스레드가 여러 개 있는 경우 출력 인터레이스를 방지하기 위해 로깅 기능을 잠가야 할 수도 있습니다.

IMHO 로깅만으로는 부족해서 이렇게 썼습니다. 침착한

행운을 빌어요!

어쩌면 투명한 방식으로 로깅을 삽입하는 것이 오히려 Aspect Oriented 프로그래밍 관용구에 속할 수도 있습니다.하지만 여기서는 OO 디자인을 이야기하고 있습니다.

제 생각에는 싱글톤 패턴이 가장 유용할 수 있습니다.LoggingService 클래스의 공개 정적 메서드를 통해 모든 컨텍스트에서 로깅 서비스에 액세스할 수 있습니다.

이는 전역 변수와 매우 비슷해 보이지만 그렇지 않습니다.싱글톤 클래스 내에 적절하게 캡슐화되어 있으며 모든 사람이 이에 액세스할 수 있는 것은 아닙니다.이를 통해 런타임 시에도 로깅이 처리되는 방식을 변경할 수 있지만 '악의적인' 코드로부터 로깅 작업이 보호됩니다.

제가 작업하는 시스템에서는 다양한 하위 시스템의 메시지를 구별할 수 있도록 여러 개의 로깅 '싱글턴'을 생성합니다.런타임 시 켜기/끄기 가능, 필터 정의 가능, 파일 쓰기 가능...원하는대로 말만 해.

나는 과거에 로깅에 액세스해야 하는 클래스에 대한 기본 클래스(또는 언어가 지원하는 경우 인터페이스)에 로깅 클래스의 인스턴스를 추가하여 이 문제를 해결했습니다.무언가를 기록할 때 로거는 현재 호출 스택을 보고 거기에서 호출 코드를 결정하여 로깅 문(소스 메서드, 사용 가능한 경우 코드 줄, 로깅한 클래스 등)에 대한 적절한 메타데이터를 설정합니다. 다수의 클래스에 로거가 있으며 자동으로 결정될 수 있는 메타데이터로 로거를 구체적으로 구성할 필요가 없습니다.

이것 하다 상당한 오버헤드를 추가하므로 프로덕션 로깅에 반드시 현명한 선택은 아니지만, 그러한 방식으로 설계하면 로거의 측면이 조건부로 비활성화될 수 있습니다.

현실적으로 나는 대부분의 경우 커먼즈 로깅을 사용하지만(Java에서 많은 작업을 수행함) 위에서 설명한 디자인에는 유익하다고 생각되는 측면이 있습니다.다른 사람이 이미 디버깅에 상당한 시간을 소비한 강력한 로깅 시스템을 갖는 것의 이점은 더 깔끔한 디자인으로 간주될 수 있는 것의 필요성보다 더 큽니다(특히 이 게시물에 세부 정보가 부족하다는 점을 고려하면 이는 명백히 주관적입니다).

Permgen 메모리 문제를 일으키는 정적 로거 관련 문제가 있습니다(적어도 저는 생각하다 그게 문제입니다.) 그래서 조만간 로거를 다시 방문하게 될 것 같습니다.

전역 변수를 피하기 위해 전역 REGISTRY를 만들고 거기에 전역을 등록할 것을 제안합니다.

로깅의 경우, 나는 싱글톤 클래스나 로깅을 위한 몇 가지 정적 메서드를 제공하는 클래스를 제공하는 것을 선호합니다.

실제로 저는 기존 로깅 프레임워크 중 하나를 사용하겠습니다.

또 다른 가능한 해결책은 로깅/저장 프로시저를 캡슐화하는 Log 클래스를 갖는 것입니다.그렇게 하면 인스턴스화할 수 있습니다. new Log(); 싱글톤을 사용하지 않고도 필요할 때마다.

데이터베이스를 통해 로깅하는 경우 주입해야 하는 유일한 종속성은 데이터베이스이기 때문에 이것이 제가 선호하는 솔루션입니다.잠재적으로 파일을 사용하는 경우 종속성을 주입할 필요가 없습니다.전역 또는 정적 로깅 클래스/함수를 완전히 피할 수도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top