0

このテンプレート メソッド パターンを、ログ記録および例外処理とは別のロジックに使用してもよいですか、それとも「悪い習慣」ですか?

たとえば、次のコードがあります。

public abstract class Parent {
    private final Logger log = LoggerFactory.getLogger(getClass());

public void eat() {
    try {
        doEat();
    } catch (SomeException1 e) {
        log.debug("some text");
        throw new CustomException1();
    }
}

protected abstract void doEat();

public void sleep() {
    try {
        doSleep();
    } catch (SomeException2 e) {
        log.debug("some text");
        throw new CustomException2();
    }
}

protected abstract void doSleep();
}

そして私の子クラス:

public class Child extends Parent {
@Override
protected void doEat() {
    //some logic
}

@Override
protected void doSleep() {
    //some logic
}}

doEat()メソッドとの異なる実装はありませんdoSleep()

それが価値があるかどうか、それが「悪い習慣」であるかどうかを知りたいです。

4

1 に答える 1

1

パターンがあなたが抱えている問題を解決し、後でそれ以上の問題を引き起こさないと確信しているなら、私は何の問題も見ません.

ここでの私の個人的な好みは、Decorator パターンです。Childextendsの「テンプレート」バージョンではParent、ログの動作は実際にはロジックから分離されておらず、隠されているだけです。唯一の利点は、 の複数のサブタイプで再利用できることですParent。それらが真に分離されているということは、クライアントが知る必要なく、独立してそれらのいずれかを変更できることを意味します。これは、「Decorator」バージョンがどのように機能するかです:

public class Thing implements MyBehaviour {
    @Override
    public void eat() {
        //some logic
    }
}

次に、ロギングの場合:

public class LoggingThing implements MyBehaviour {
    public MyBehaviour delegate;

    public LoggingThing(MyBehaviour delegate) {
        this.delegate = delegate;
    }

    @Override
    public void eat() {
        try {
            delegate.eat();
        } catch (MyException e) {
            // extra behaviour
        }
    }
}

現在、ログの動作は「食べる」動作から完全に分離されています。MyBehaviourログを記録する を使用することも、ログを記録しMyBehaviourない を使用することもMyBehaviour、その他の実行したいことを実行する を使用することもできます。クライアントは、自分がどちらを持っているかを知る必要はありません。

継承よりも関連付けを優先します。

于 2016-05-28T14:22:08.947 に答える