通过模板方法模式将逻辑与日志分开

时间:2016-05-28 14:05:15

标签: java design-patterns template-method-pattern

我可以将此模板方法模式用于记录和异常处理的单独逻辑,还是“不好的做法”?

例如我有这段代码:

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()的不同实现。

我想知道它是否值得,是不是“不良做法”。

1 个答案:

答案 0 :(得分:1)

如果模式解决了您遇到的问题,并且您确信以后不会引起更多问题,我认为没有任何问题。

我个人的偏好是装饰师模式。在“模板”版本中,Child扩展Parent,日志记录行为与逻辑没有真正区别,只是隐藏了。唯一的好处是它可以在Parent的多个子类型中重复使用。让他们真正分开意味着你可以独立地改变他们中的任何一个,而不需要客户知道。这就是“装饰者”版本可能起作用的方式:

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
        }
    }
}

现在,日志记录行为与“eat”行为完全分开。您可以拥有一个MyBehaviour日志,您可以拥有一个不会记录的MyBehaviour,并且您可以拥有一个MyBehaviour来执行您希望它执行的任何其他操作。客户永远不需要知道它有哪一个。

Prefer association over inheritance.