父包装子 class 方法

Parent wrapping child class method

我有这些 Worker classes 在做一些工作:

class WorkerOne implements IWorker {
    @Override
    public doWork(Resource resource){
     // do some work
    }
}

我希望所有 doWork() 方法都被同一个操作包裹。

实现它的一种方法是创建一个抽象 class,如下例所示:

abstract class WorkWrapper implements IWorker {
    @Override
    public doBetterWork(){
       Resource resource = // ...
       doWork(resource)
       resource .close();
    }
}


class WorkerOne extends WorkWrapper {

    protected doWork(Resource resource){
     // do some work
    }
}

并将 Worker 调用为:

WorkerOne worker = new WorkerOne();
worker.doBetterWork();

出于某些原因,我不喜欢使用继承。有没有更好的解决方案来做这个包装?

使用可以在接口中定义的 default 方法可以避免继承 (extends) 并坚持实现 (implements) :

class WorkerOne implements IWorker {
    @Override
    public void doWork(Resource resource){
     // do some work
    }
}

public interface IWorker {
    void doWork(Resource resource);

    default void doBetterWork(){
       Resource resource = // ...
       doWork(resource)
       reource.close();
    }
}

并像以前一样使用它:

IWorker worker = new WorkerOne();
worker.doBetterWork(); 

I want all doWork() methods to be wrapped by the same operation.

就我个人而言,我不太喜欢在 API 方面公开两种方法而 class 的客户端只应调用其中一种方法的设计。这是误导。
为了避免这种情况,我可能会使用组合和装饰器(不是传统的装饰器,因为两种 doWork() 方法的签名不同)。

public interface IWorker {
    void doWork(Resource resource);
}

class WorkWrapper{

    private IWorker decorated;
    public WorkWrapper(IWorker decorated){
       this.decorated = decorated;
    }
    @Override
    public doWork(){
       Resource resource = // ...
       decorated.doWork(resource);
       reource.close();
    }
}

class FooWork implements IWorker {

    @Override
    public doWork(Resource resource){
          // do something...
    } 
 }

现在没有歧义了:

WorkWrapper worker = new WorkWrapper(new FooWork());
worker.doWork(); // just this method is exposed now in WorkWrapper 

您可以将它与工厂结合起来,使事情变得更简单,并对客户端隐藏实现细节:

WorkWrapper worker = FooWork.createWrapperFor();
worker.doWork(); 

您所描述的情况似乎正是应用 Template Method 设计模式的确切背景。但是,该模式确实需要继承。

还有其他选择。但是,它非常适合您的要求,我会犹豫将它们称为 "better" 解决方案。

继承的明显替代方法是组合。在您的情况下,这意味着应用 Strategy 模式。

在应用此模式时,您的 WorkWrapper 将成为 上下文 ,并且 IWorker 将匹配 抽象策略的角色,其实现作为具体策略

在代码中:

class WorkWrapperContext {
    private IWorker strategy;

    WorkWrapperContext(IWorker strategy) { 
        this.strategy = strategy;
    }

    public void doBetterWorkOperation() {
        // do some stuff
        strategy.doWork();
    }
}