2011-01-14 3 views
2

나는 물건을 다루는 invoke 함수가 있다는 것을 알고있다. 나는 그러한 행동을 사용하는 "정확성"에 전반적으로 관심이있다. 내 문제는 이것입니다 : 서비스 개체 마녀 서비스를 고려하는 방법이 포함되어 있습니다. 내가하고 싶은 일은 나중에 침입하지 않고 이러한 서비스의 동작을 변경하는 것입니다. 예를 들어 : 나는 새로운 클라이언트 응용 프로그램에 동일한 서비스를 제공 할 필요가 나는 또한 플래그를 설정처럼 특정 여분의 물건을 할, 또는 만들거나 특정 데이터를 업데이트 할 필요가 있음을 알 수 2개월 후Java에서 make runtime 결정된 메소드 호출을 호출 할 수 있습니까?

class MyService { 

     public ServiceResponse ServeMeDonuts() { 
     do stuff... 
     return new ServiceResponse(); 

} 

, 또는 다르게 응답을 인코딩 할 수 있습니다. 내가 할 수있는 것은 그것을 띄우고 일부 IF를 버리는 것이다. 필자가 생각하기에 이것은 테스트 된 코드와의 상호 작용을 의미하며 이전 서비스 클라이언트에 대해 원하지 않는 동작을 초래할 수 있기 때문에 좋지 않습니다.

그래서 저는 "NewClient"가 다른 동작을한다는 것을 알려주는 레지스트리를 레지스트리에 추가합니다. 시스템이 나는 사고와 접근 방법의 정확성과 같이 코드의 정확성에 특히 관심이없는 나는이

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(); 
     .... 
} 

같은 일을 할 때

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... 
    } 
} 

: 그래서 나는 같은 것을 할 수 있습니다. 사실 나는 PHP에서 이것을해야만합니다. 마녀입니다. 상업적 이유로 노래해야하는 프로그래밍의 팝 음악의 한 종류입니다. 팝을 연주해도 책에서 정말 노래하고 싶어합니다. 또는 영감을 덜 준 유추 실용적인 필요성 및 기술적 접근 방법에 대해이 문제에 대한 귀하의 의견을 정말로 알고 싶습니다.

감사

답변

1

니스 경우 Aspect Oriented Programming을 적용합니다. AOP를 사용하면 aspects을 이벤트 또는 메소드에 첨부하여 이벤트 전후의 추가 논리를 처리 할 수 ​​있습니다.

자바 here

aspectwerkz를 사용하여이 예를 들어 좋은 AOP here의 예와 또한 예제가 있습니다 귀하의 경우와 매우 유사하다, 기본적으로 서비스 실행 주위 포스트 및 사전 방법 핸들러를 추가하고있다.

내가 PHP에서 AOP 정말 익숙하지 않아요하지만 당신은 당신이 필요로하는 것은 당신이 객체가 프록시를 독립적으로 몇 가지 추가 동작을 정의함으로써 프록시입니다 this one.

+1

가 실제로 그 whatI 처음에 생각입니다 : 내가 게시하기 전에 AOP에 더 깊이 살펴했다하지 않은 이유를 궁금해 그래서 지금, "서비스가 행동을 할 수있는 것보다 객체 측면을 가질 수 있다면"지금은 재발견 같은 느낌 바퀴. 짧지 만 포괄적 인 답변 주셔서 감사합니다. –

0

처럼 사용할 수있는 몇 가지 프로젝트가 있습니다. 그것은 테스트 코드와 과의 상호 작용이 취소가 동작을 원하는 발생할 수 있습니다 수단으로서의 제 생각에는

public static void main(String[] args) { 
     Service serviceImpl = new ServiceImpl(); 
     Service service = (Service) ServiceHandler.createProxy(serviceImpl); 
     // use service 
    } 
1

이 잘되지 않습니다 : 예는 다음과 같이

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; 
    } 
} 

당신은 다음을 사용합니다 이전 서비스 클라이언트

그래서 자동 테스트가 있습니다. 당신이 원하는 것은 AOP로 할 수 있지만, 정말로 코드를 유지하기가 어렵 기 때문에 (정말로 AOP의 일반적인 문제이며, 많은 부분을 포착하지 않은 이유입니다).

그것은 작동 뭔가를 깨는 두려워 나쁜 코드를 만드는 또 다른 예입니다. 결국, 어떤 변화는 잠재적으로 문제를 일으킬 수 있고, 고통스러운 뒤틀림을 보는 것은 어떻게 든 "좋은"코드의 변경을 분리하고 아직이 잘 작동에만 불행으로 끝날 것 가지고.

+0

당신은 자동화 된 테스트에 대해 매우 잘하지만, 클라이언트가 다른 응용 프로그램, 서비스를 필요로 어쩌면 완전히 다른 응용 프로그램입니다 서비스의 경우에, 테스트가 거의 불가능하다 누군가가 뭔가 잘못된 것입니다 알게 될 때까지 약간의 시간이 긴 시간을 전달할 수 있습니다. 저는 KISS 원칙의 가장 큰 팬입니다. (바보로 유지하십시오.) 그래서 나는 일을 "더 잘"하기 전에 생각할 시간을 많이 벌었습니다. 어쨌든 나는 너의 의견을 존중한다. 감사합니다. –

+0

@Catalin : 그렇기 때문에 그러한 서비스가 매우 엄격하고 명확하게 정의 된 인터페이스를 갖는 것이 매우 중요합니다. 그런 다음 인터페이스 계약을 다루는 테스트 슈트를 가질 수 있습니다. 클라이언트가 계약에 의해 보장되지 않는 동작에 의존하는 경우에는 자신의 실수입니다. 물론 이러한 계약이 없었으며 "유기적으로"성장한 서비스를 상속 받았을 때 많은 도움이되지 않습니다. –

관련 문제