使用通用逻辑时是否有模板方法模式的替代方案?

Is there an alternative to Template Method pattern when using common logic?

我有问题。项目中的大部分解决方案都遵循 Template Method 设计模式。同时,随着业务逻辑的复杂化,解决方案也越来越扑朔迷离。

比如有一些Copier接口:

public interface Copier {

    void copy() {
        copyA();
        copyB();
    }
}

部分class可以通过这种方式实现该接口:

public class MusicCopier implements Copier {

    @Override
    protected void copyA() {
        SomeUtils.copy(new File(...), new File(...)));
    }

    @Override
    protected void copyB() {
        // three arguments here
        SomeUtils.copy(new File(...), new File(...)), new File(...));
    }
}

public class DocumentsCopier implements Copier {

    @Override
    protected void copyA() {
        SomeUtils.copy(new File(...), new File(...)));
    }

    @Override
    protected void copyB() {
        // three arguments here
        SomeUtils.copy(new File(...), new File(...), new File(...)));
    }
}

然后在某处使用这些 classes 是这样的:

Copier musicCopier = new MusicCopier();
Copier documentsCopier = new DocumentsCopier();

musicCopier.copy();
documentsCopier.copy();

等伟大的。这里出现了用抽象 class 替换接口并将主要逻辑放在那里的想法。然后摘要 class 将如下所示:

public abstract class Copier {

    protected void copy() {
        copyA();
        copyB();
    }
    
    protected void copyA() {
       SomeUtils.copy(getASource(), getADest()));
    }

    protected void copyB() {
       SomeUtils.copy(getBSource(), getBDest(), getBExcluded()));
    }
    
    // and these terrible methods overridden in superclasses:
    protected void getASource() {}
    protected void getBSource() {}
    protected void getADest() {}
    protected void getBDest() {}
    protected void getBExcluded() {}
    // protected void getOrSetWTF() {}
}

因此,subclasses 将如下所示:

public class MusicCopier extends Copier {

    @Override
    protected void getASource() { /* pass some path here */}
    
    @Override
    protected void getBSource() {/* pass some path here */}
    
    @Override
    protected void getADest() {/* pass some path here */}
    
    @Override
    protected void getBDest() {/* pass some path here */}
    
    @Override
    protected void getBExcluded() {/* pass some path here */}
}

等原来我们是在“设置逻辑”,现在都在一个抽象中了class。 而且越复杂,“get”(或“set”?)的次数就越多。所有这些都造成了混乱,这样的代码写起来简直令人不快——尤其是当项目很大并且开发人员必须“配置 superclasses”时。

在某些子class中,我需要在copyA()copyB()中做一些其他事情。然后我必须完全覆盖这些方法:

@Override
protected void copyA() {
    doSomethingHere();
    
    SomeUtils.copy(new File(...), new File(...)));
    
    doSomethingHereTo();
}

或者将这些“doSomething”方法也放在抽象 class 中,然后 override/implement 将它放在子classes 中。

是否有模式或它们的组合可以帮助摆脱这种丑陋的设计?

我建议不要覆盖很多方法,每个方法 return 一条信息,将这些方法组合起来,这样一个包含它们的对象就可以作为结果被 return 编辑在一种方法中。

在我看来这个信息是相关的,所以为什么不将它们全部放在一个“RoutingInfo”-class 或其他东西中。

您可以将 class 重构为只有几个“template-methods”,其中 return 个包含相关信息的对象。