我让这些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();
出于某些原因,我宁愿不使用继承。有没有更好的解决方案来进行这种包装?
答案 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();
}
}