父包装子 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();
}
}
我有这些 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();
}
}