父包装子类方法

时间:2019-06-20 18:31:38

标签: java oop inheritance design-patterns abstract-class

我让这些Worker类做一些工作:

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

我希望所有doWork()方法都由同一操作包装。

一种实现方法是创建一个抽象类,如下例:

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();

出于某些原因,我宁愿不使用继承。有没有更好的解决方案来进行这种包装?

2 个答案:

答案 0 :(得分:4)

使用可以在接口中定义的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(); 
  

我希望所有doWork()方法都由同一操作包装。

我个人并不喜欢在API方面公开两个方法的设计,而类的客户端只能调用其中的一个。那是误导。
为避免这种情况,我可能会使用composition和decorator(因为两个doWork()方法之间的签名不同,所以不使用常规的decorator)。

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(); 

答案 1 :(得分:2)

您所描述的情况似乎正是应用Template Method设计模式的确切上下文。但是,这种模式确实需要继承。

还有其他选择。但是,它非常适合您的要求,我会毫不犹豫地称它们为“更好”的解决方案。

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

在应用此模式时,您的WorkWrapper将成为上下文,而IWorker将使抽象策略的角色与其实施作为具体策略

在代码中:

class WorkWrapperContext {
    private IWorker strategy;

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

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