私はプロジェクトに取り組んでおり、現在log4jでいくつかのロギングの実装に取り組んでおり、ログの実装についてどうすればいいのか興味がありました。私がキックしている2つの実装は次のとおりです。
最初のオプション
そのクラスとすべてのサブクラスに対して、スーパークラスからの単一のログを使用します。
public abstract class AbstractFoo {
protected static Log LOG = LogFactory.getLog(AbstractFoo.class);
...
}
public class Foo extends AbstractFoo {
public void someMethod() {
LOG.info("Using abstract log");
}
}
2番目のオプション
クラス、スーパー、サブごとに個別のログを使用します。
public abstract class AbstractFoo {
private static Log LOG = LogFactory.getLog(AbstractFoo.class);
...
}
public class Foo extends AbstractFoo {
private static Log LOG = LogFactory.getLog(Foo.class);
public void someMethod() {
LOG.info("Using own log");
}
}
何がより理にかなっていて、なぜですか?
私もしません。代わりに、両方のケースで正しいクラスを使用するようにします。
public abstract class AbstractFoo {
protected final Log log = LogFactory.getLog(getClass());
...
}
public class Foo extends AbstractFoo {
public void someMethod() {
log.info("Using abstract log");
}
}
多くのロギングを実行していない場合(とにかく良い方法です)、代わりにメソッドを使用できます。
public abstract class AbstractFoo {
protected Log log() { return LogFactory.getLog(getClass()); }
...
}
これを頻繁に呼び出すクラスがある場合は、それをオーバーライドしてキャッシュされたインスタンスを提供できます。
これが私の解決策です(最終的な静的ロガー):
public abstract class AbstractFoo {
protected abstract Log getLogger();
public doSomething() {
getLogger().info("log something");
}
}
public class Foo extends AbstractFoo {
private static final Log log = Log.getLogger(Foo.class);
protected Log getLogger() {
return log;
}
public doSomethingElse() {
log.info("log somethingElse");
}
}
両方とも理にかなっています。アプリケーションによって異なります。
私は、より頻繁に使用されるプラクティスは、各クラスのプライベートロガーを持つことだと思います。これにより、クラスごとおよびパッケージごとにロギングを設定できます。 AbstractFoo
とFoo
は異なるパッケージに属している可能性があり、おそらくFoo
からのログのみを表示することを忘れないでください。
さらに、protected
フィールドを書きたい場合は、常に考え直してください。完全に禁止されているわけではありませんが、よく知られている悪い習慣です。コードが読みにくくなり、保守が難しくなります。
同じことは、コンストラクターで遊ぶことで実現できます。 Baseクラスレベルでロガーを追加し、すべてのから設定しますDerived super()を使用したクラス。コードがあります:
public abstract class AbstractFoo {
protected Log log; // base abstract class has a Log object.
public AbstractFoo(Log logger) { // parameterized constructor for logger, to be used by the derived class.
this.log = logger;
}
public doSomething() { // common method for all the derived classes.
log.info("log something");
}
// rest of business logic.
}
public class Foo extends AbstractFoo {
public Foo(){
super(LogFactory.getLog(AbstractFoo.class));
}
public void someMethod() {
log.info("Using own log"); // this uses its own logger.
}
}
抽象クラスでロガーを作成すると、ログはすべてAbstractFooから発信されたものとしてタグ付けされます。ログが発生した子クラスでタグ付けされたログを表示する/必要がある場合は、子クラスのロガーを作成します。