我知道有一个调用函数来完成这些工作,我对使用这种行为的“正确性”总体感兴趣。 我的问题是: 我有一个服务对象女巫包含我认为服务的方法。 我想要做的是改变这些服务的行为而不用以后的入侵。 例如:
class MyService {
public ServiceResponse ServeMeDonuts() {
do stuff...
return new ServiceResponse();
}
2个月后,我发现我需要为新的客户端应用程序提供相同的服务,我还需要做一些额外的事情,比如设置标志,制作或更新某些数据,或者以不同方式编码响应。我能做的就是弹出它并丢弃一些IF。在我看来,这并不好,因为它意味着与经过测试的代码的交互,并可能导致以前的服务客户端不想要的行为。
所以我来添加一些内容到我的注册表,告诉系统“NewClient”有不同的行为。所以我会做这样的事情:
public interface Behavior {
public void preExecute();
public void postExecute();
}
public class BehaviorOfMyService implements Behavior{
String method;
String clientType;
public void BehaviorOfMyService(String method,String clientType) {
this.method = method;
this.clientType = clientType;
}
public void preExecute() {
Method preCall = this.getClass().getMethod("pre" + this.method + this.clientType);
if(preCall != null) {
return preCall.invoke();
}
return false;
}
...same for postExecute();
public void preServeMeDonutsNewClient() {
do the stuff...
}
}
当系统会做这样的事情时
if(registrySaysThereIs different behavior set for this ServiceObject) {
Class toBeCalled = Class.forName("BehaviorOf" + usedServiceObjectName);
Object instance = toBeCalled.getConstructor().newInstance(method,client);
instance.preExecute();
....call the service...
instance.postExecute();
....
}
我对代码的正确性以及思维和方法的正确性并不特别感兴趣。实际上我必须用PHP做这个,我觉得这是一种流行音乐编程,我必须出于商业原因“唱歌”,即使我玩POP我真的很想唱这本书,所以把我的更多放在一边或者更少的灵感类比我真的想知道你对这个问题的看法,因为它的实际必要性和技术方法。
由于
答案 0 :(得分:1)
适用Aspect Oriented Programming的好例子。使用AOP,您可以将aspects
附加到事件或方法,以便在事件之前或之后处理额外的逻辑。
使用aspectwerkz的示例与您的情况非常相似,基本上是围绕服务执行添加post和pre方法处理程序。
我对PHP中的AOP并不熟悉,但有些项目可以使用this one.
答案 1 :(得分:1)
在我看来,这并不好 意味着与经过测试的代码和 可能导致不想要的行为 以前的服务客户。
这就是您进行自动化测试的原因。你想要的东西可以用AOP来完成,但实际上,真的不应该这样做,因为它会使代码很难维护(这是AOP的一般问题以及它没有引起太多关注的原因)。
这只是让代码变得更糟的另一个例子,因为害怕破坏有用的东西。最后,任何更改都可能会破坏事物,并且经历痛苦的扭曲以某种方式将更改与“好”代码隔离开来,但让它们工作也只会以痛苦结束。
答案 2 :(得分:0)
您需要的是一个代理服务器,您可以独立于被代理的对象定义一些其他行为。 E.g:
public class ServiceHandler implements InvocationHandler {
private final Object target;
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new ServiceHandler(target));
}
public ServiceHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// define preexecute behaviour
Object result = method.invoke(target, args);
// define postexecute behaviour
return result;
}
}
然后您将按如下方式使用它:
public static void main(String[] args) {
Service serviceImpl = new ServiceImpl();
Service service = (Service) ServiceHandler.createProxy(serviceImpl);
// use service
}