我有一个ABC类可以执行操作a(),b()和c()(operation == method),它们都是密切相关的。我也有类似DE和FGH的simimar类。将来,可能会添加新类以及其他操作。类永远不会共享操作(例如,没有类ADF)
我的程序应该能够执行所有这些操作,时间是"有点随机",这意味着我事先没有估计将执行哪些操作/多少次。
我通过创建一个包装类" OperationInvoker"来解决这个问题。我的程序只能访问这个调用程序,并且每个操作都有一个方法。这样做的好处是封装:如果创建了新操作或现有操作或编辑了新操作,则需要编辑包装类。
我的问题是,"巨大"包装器是解决这个问题的最佳模式吗?
我调查了观察者的模式我认为这不是一个合适的案例,因为ABC,DE,FGH这两个课程从来没有任何共同利益。例如,如果需要执行操作A,则所有已注册的类将接收事件A,并且只有1个类(即ABC)实际上对此事件感兴趣。所有其他注册课程将丢弃该活动。这似乎是所有注册和观察的过度/开销。
委托模式也遇到了同样的问题:我没有多个类以不同的方式执行相同的操作,因此没有必要使用灵活的委派系统。
是否有其他更好的模式,或者这只是一个委托包装类的简单案例?
编辑:有人问ABC究竟是做什么的。好吧,我有一个描述SOAP Web服务的WSDL文件。我使用工具将此文件转换为java类。这意味着我无法控制这些类的内容,因为它们是自动生成的。所以我编写了一个WebServiceInvoker类,它充当了这些Web服务的包装器。这个包装类有3个方法:做Web服务A,做Web服务B,做Web服务C.随着程序的扩展,越来越多的wsdl文件进入图片。当然,没有一个Web服务做同样的事情。它们并非全部捆绑在一个大型wsdl文件中的唯一原因是因为某些Web服务在逻辑上并不属于其他Web服务。所以我结束了以下课程:
将来可能会出现更多wsdl(以及包装类)。之所以在所有其他包装器周围有一个额外的包装器,是因为需要使用"会话ID"来调用每个服务。所以每个包装器都需要知道这些信息。因此,超级包装程序保存此信息,并可以调用所有Web服务。这也非常适合作为api:使用Web服务的程序对服务一无所知,它只通过超级包装器为每个Web服务提供了一种公共方法。该程序当然知道每个Web服务返回的内容(列表,字符串,没有...)。
答案 0 :(得分:1)
为了便于代码维护,我建议将包装器更改为:
public class Operations {
private ABC abcInst;
private DE deInst;
private FGH fghInst;
protected Operations(ABC abc, DE de, FGH fgh) {
this.abcInst = abc;
this.deInst = de;
this.fghInst = fgh;
}
public ABC getABC() { return abcInst; }
public DE getDE() { return deInst; }
public FGH getFGH() { return fghInst; }
}
这种方式不需要麻烦(除非添加了新课程),来自来电者的所有来电只需要额外的.getABC().a()
代替.a()
等。这强调了这一事实:操作由不同的类执行,但仍允许通过传递Operations
- 实例来访问所有功能。
答案 1 :(得分:1)
看起来你有一个明确的架构,你试图不泄漏到其他组件。避免这种泄漏的自然方法是增加一个分离度。
基本上,如果你愿意,你仍然可以保留一个巨大的包装器,但是你需要考虑你想要暴露的东西并且只暴露它。看起来您想要公开的是已知操作的列表,所以如下所示:
// Your setup - trimmed down.
interface ABC {
public void a();
public void b();
public void c();
}
interface DE {
public void d();
public void e();
}
interface FGH {
public void f();
public void g();
public void h();
}
// Your current wrapper.
class AllOps {
public ABC getABC() {
return null;
}
public DE getDE() {
return null;
}
public FGH getFGH() {
return null;
}
}
// One further degree of separation.
enum Op {
A {
@Override
void op() {
ops.getABC().a();
}
},
B {
@Override
void op() {
ops.getABC().b();
}
},
C {
@Override
void op() {
ops.getABC().c();
}
},
D {
@Override
void op() {
ops.getDE().d();
}
},
E {
@Override
void op() {
ops.getDE().e();
}
},
F {
@Override
void op() {
ops.getFGH().f();
}
},
G {
@Override
void op() {
ops.getFGH().g();
}
},
H {
@Override
void op() {
ops.getFGH().h();
}
};
// Hide the huge wrapper.
private static AllOps ops = new AllOps();
// Only expose the operations.
abstract void op();
}
public void test() {
Op.A.op();
Op.F.op();
}
不确定这是什么模式,但如果你只公开枚举,我认为你已经实现了断开连接。
可以添加其他操作作为以您喜欢的任何方式实现op
的新枚举。他们甚至可能不会使用巨大的包装。