2017-03-09 8 views
2

私は、多数のデバッグレベルロギングステートメントを持つライブラリに基本クラスを持っています。このライブラリはさまざまなアプリケーションで使用され、基本クラスはサブクラス化されています。私はそれを使用している特定の派生クラスに応じて基本クラスのログレベルを設定できるようにしたい。それを達成するための有用なイディオムは何ですか?例えばLog4Jの派生クラスに基づいて、基本クラスのログを設定するにはどうすればよいですか?

、次は出発点である:

DerivedAのためではなく、 DerivedBのロギングをオンにする方法はありません上記の
class Base { 
    static Logger logger = Logger.getLogger(Base.class); 
    protected final void foo() { 
     logger.debug("foo"); 
    } 
} 

class DerivedA extends Base { 
    public void boo() { 
     foo(); 
    } 
} 

class DerivedB extends Base { 
    public void boo() { 
     foo(); 
    } 
} 

代わりに、私は次のような何かをする必要があります:

abstract class Base { 

    abstract protected Class getDerivedType(); 
    protected final void foo() { 
     Logger logger = Logger.getLogger(getDerivedType());   
     logger.debug("foo"); 
    } 
} 

class DerivedA extends Base { 
    public void boo() { 
     foo(); 
    } 
    @Override protected Class getDerivedType() { 
     return DerivedA.class; 
    } 
} 

class DerivedB extends Base { 
    public void boo() { 
     foo(); 
    } 
    @Override protected Class getDerivedType() { 
     return DerivedB.class; 
    }  
} 

…上記仕事私は私のloggerオブジェクトは静的なことができないという事実が好きではないんが

log4j.logger.a.DerivedA=debug 
log4j.logger.a.DerivedB=info 

:上記の、私は、派生クラスに応じて私のlog4j.propertiesファイル異なるログレベルで持つことができますこれ以上はなく、各メソッドの内部で再定義する必要があります。また、派生クラスが抽象メソッドを定義して、ログをカスタマイズできる以外の理由で具体的な型を指定しなければならないというのは不自然です。

上記は慣用的ですか、そうでない場合は、同じ効果を達成するためのより良い方法はありますか?

一般に、コンテキストに基づいてロギングを設定する方法はありますか? (この場合コンテキストは派生クラスですが、呼び出しスタック、つまりロギングが発生する特定のメソッドを呼び出すメソッドでもあります)。あるいは、このレベルのロギング設定が本当にサポートされていないか、あるいは悪い考えですか?非静的ロガーと

答えて

2

一つの可能​​な解決策:

public class Base { 
    protected Logger logger = Logger.getLogger(Base.class); 

    protected final void foo() { 
     logger.debug("foo"); 
    } 
} 

class DerivedA extends Base { 
    { 
     logger = Logger.getLogger(DerivedA.class); 
    } 

    public void boo() { foo(); } 
} 

class DerivedB extends Base { 
    { 
     logger = Logger.getLogger(DerivedB.class); 
    } 
    public void boo() { foo(); } 
} 

loggerは静的ではありませんしかし、この構造はそれほど複雑で元のものです。


代替ソリューション:サブクラスがgetLogger()抽象メソッドを実装する必要は(彼らは単に静的ロガーを返すことができ)、この方法は、ロギングの基本クラスで使用されています。ここで、ロガーは静的にすることができます。

public abstract class Base { 
    protected abstract Logger getLogger(); 

    protected final void foo() { 
     getLogger().debug("foo"); 
    } 
} 

class DerivedA extends Base { 
    private static final Logger logger = Logger.getLogger(DerivedA.class); 

    public void boo() { foo(); } 

    protected Logger getLogger() { return logger; } 
} 

class DerivedB extends Base { 
    private static Logger logger = Logger.getLogger(DerivedB.class); 

    public void boo() { foo();} 

    protected Logger getLogger() { return logger; } 
} 

どちらの方法も現在のプロパティファイルで機能します。

関連する問題