Java 将不同操作委托给不同类的设计模式
我有一个类ABC,它可以执行操作a()、b()和c()(操作==方法),这些都是密切相关的。我也有simimar的DE和FGH课程。将来,可能会添加带有附加操作的新类。类从不共享操作(例如,没有类ADF) 我的程序应该能够执行所有这些操作,并且计时是“一种随机的”,这意味着我事先不知道什么时候/多少次执行哪个操作 我通过创建一个包装类“OperationInvoker”来解决这个程序。我的程序只能访问这个调用程序,并且每个操作都有一个方法。这样做的好处是封装:如果创建或编辑了新操作或现有操作,则只需编辑包装器类 我的问题是“巨大”包装器是否是解决此问题的最佳模式 我研究了观察者模式,我认为这不是一个合适的情况,因为类ABC,DE,FGH。。。从来没有任何共同利益。类似地,如果需要执行操作A,所有注册的类都将接收事件A,并且只有一个类(即ABC)实际对该事件感兴趣。所有其他已注册的类将放弃该事件。在所有的注册和观察过程中,这似乎是过度消耗/开销 委托模式也遇到了同样的问题:我没有很多类以不同的方式执行相同的操作,因此没有必要使用灵活的委托系统 是否还有其他更好的模式,或者这只是一个简单的委托包装器类的例子 编辑:有人问ABC到底做什么。嗯,我有一个描述soapweb服务的WSDL文件。我使用工具将此文件转换为java类。这意味着我无法控制这些类的内容,因为它们是自动生成的。因此,我编写了一个类WebServiceInvoker,它充当这些web服务的包装器。这个包装类有3个方法:DoWebServiceA、DoWebServiceB和DoWebServiceC 随着程序的扩展,越来越多的wsdl文件进入画面。当然,没有一个web服务做同样的事情。它们没有全部捆绑在一个大的wsdl文件中的唯一原因是,某些web服务在逻辑上不属于其他web服务。因此,我将学习以下课程:Java 将不同操作委托给不同类的设计模式,java,design-patterns,Java,Design Patterns,我有一个类ABC,它可以执行操作a()、b()和c()(操作==方法),这些都是密切相关的。我也有simimar的DE和FGH课程。将来,可能会添加带有附加操作的新类。类从不共享操作(例如,没有类ADF) 我的程序应该能够执行所有这些操作,并且计时是“一种随机的”,这意味着我事先不知道什么时候/多少次执行哪个操作 我通过创建一个包装类“OperationInvoker”来解决这个程序。我的程序只能访问这个调用程序,并且每个操作都有一个方法。这样做的好处是封装:如果创建或编辑了新操作或现有操作,则
- 可以调用web服务A、B和C的包装器类
- 一个可以调用web服务D,E
- 可以调用webservice F、G和H的包装器类
将来可能会出现更多的wsdl(从而出现包装类)。在所有其他包装器周围都有一个附加包装器的原因是,每个服务都需要使用“会话id”进行调用。所以每个包装器都需要知道这些信息。因此,超级包装器保存这些信息,并可以调用所有web服务。这也是一个非常好的api:使用web服务的程序对服务一无所知,它只有一个公共方法可通过superwrapper用于每个web服务。程序当然知道每个web服务返回的内容(列表、字符串、nothing…。为了便于代码维护,我建议将包装更改为以下内容:
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()
等。它强调操作由不同的类执行,但仍然允许通过传递操作
-实例来访问所有功能。看起来您有一个明确的体系结构,您试图避免泄漏到其他组件中。避免这种泄漏的自然方法是再增加一个分离度
本质上,如果你喜欢,你仍然可以保留一个巨大的包装,但是你需要考虑你想要暴露的东西,并且仅仅暴露它。看起来您想要公开的只是一个已知操作的列表,那么下面的内容怎么样:
// 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
。他们甚至可能不使用巨大的包装器。您想抽象出ABC和DE是由不同对象提供的这一事实吗?如果是这样,一个包装似乎不错。如果客户机知道ABC和DE是分开的,那么为什么不将它们传入(构造函数注入),可能是通过接口IABC和IDE?所有操作都需要一个共享参数:调用操作的用户的名称。包装器类似乎是存储此用户名的理想场所。我真的不需要我的程序不知道ABC和De是否是分开的,但我认为这也没有什么坏处(关注点的分离)。在我看来,ABC、De和FGH类做的事情非常不同。那么,共享处理真的有用吗?假设你有汽车、房子和比萨饼的课程。把它们一起处理是个好主意吗?或者,如果只区分类并单独处理每个类,会更容易吗?嗯,就我的想法。另一种可能适合的模式是使用代理,甚至可能是代理。@Korashen:每个操作都是一个web服务。每个web服务都有一个共享部分(创建soap主体,添加连接参数…),但每个都有很大的不同(有些返回真/假,有些有更复杂的响应,有些可能抛出错误…)。他们应该一起处理吗?在allOps类中,返回ABC以便调用方可以执行ABC.a()比在allOps中提供调用ABC.a()本身的方法a()有什么好处?@user1884155-根本没有-代码旨在