2012-09-19 3 views
4

나는이 사이트에서 새로운 사람이며, 이것이 나의 첫 번째 질문이다.Struts2 - 여러 메소드로 작업 하시겠습니까?

저는 웹 사이트를해야하는데, 저는 java와 Struts2를 사용하고 있습니다. 그러나 저는 Struts2에 익숙합니다.

내 사이트에서 Facebook에 요청을하고 OAuth로 인증을 받아야합니다.

조치 페이지의 실행 메소드에서 모든 프로세스 (인증 및 보호 자원 요청)를 수행 중이며,이 프로세스는 매우 복잡하며 Facebook과 내 웹간에 많은 리디렉션이 있습니다. 나는 여러 가지 방법으로 작업을 작성하지 마십시오 : "실행"하고 실행하려는 작업 (예 : "createUser")은 충분해야합니다 "(에서 http://freeopenidea.blogspot.com.es/2010/04/struts2-best-practices.html).

대부분의 코드는 다른 순간에 내 사이트의 다른 부분에서 호출 될 수 있습니다. 처음 연결할 때이 과정을 수행하지만이 작업을 수행하여 연락처 목록을 새로 고칠 수 있습니다.

1 - 필요한 메서드에 대해 분리 된 클래스 (동작이 아님)를 만들고 "execute"메서드에서 호출해야합니까?

2 - 코드를 작업 페이지에 보관해야하지만 "실행"과 다른 방법으로 사용해야합니까? 그리고 내가 할 일이있을 때마다이 페이지를 불러라.

어디서 코드를 넣을지 모르겠다. (나는 알고있다. 나는 accessToken을 저장해야만한다. 단지 코드를 붙여 넣기 만하면되지만 복잡함을 보여주기 위해 붙여 넣기 만한다.)

public String execute() throws Exception{ 
    if (code!=null){ 
     Verifier verifier = new Verifier(code); 
     //get the accessToken to do requests 
     Token accessToken = service.getAccessToken(EMPTY_TOKEN, verifier); 
     OAuthRequest requestList = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); 
     service.signRequest(accessToken, requestList); 
     Response responseList = requestList.send(); 
     if (responseList.getCode() == 200){ 
     //I get the Friends List 
     JsonParse parser = new JsonParse(); 
     JSONObject json = (JSONObject) JSONSerializer.toJSON(responseList.getBody()); 
     JSONArray datos = json.getJSONArray("data"); 
     for (Object o : datos) 
     {//for every friend of the list I do this 
      JSONObject elem = (JSONObject) o; 
      String id = elem.getString("id");     
      OAuthRequest requestFriend = new OAuthRequest(Verb.GET,"https://graph.facebook.com/"+id); 
      service.signRequest(accessToken, requestFriend); 
      Response responseFriend = requestFriend.send(); 
      if (responseFriend.getCode() == 200){ 
       JsonParse parserAux = new JsonParse(); 
       PerfilContacto pcBean = parserAux.parseFacebookElement(responseFriend.getBody()); 
       pcDAO.insertarContacto(pcBean); 
      } 
     } 
     } 
     return SUCCESS; 
    }  
    else return ERROR;  
} 

답변

3

IMO는 동작 방법에서 너무 많은 코드입니다. 작업은 웹과 비즈니스 계층 사이의 계층을 처리해야하며 그 밖의 작업은 거의 필요하지 않습니다. 특히 하드 코딩 된 클래스 인스턴스화를 통해 이러한 수준의 연결을 사용하면 작업 논리를 개별적으로 테스트하기가 매우 어려워집니다.

기본적으로 모든 코드를 서비스로 옮깁니다. 조치는 서비스 상호 작용에만 관련됩니다. 프레임 워크는 code의 존재를 확인합니다. 이 서비스는 Struts 2 외부에서 테스트됩니다. 조치는 모의 서비스로 테스트됩니다.

완전히 테스트되었지만 내 코드가 아래에 더 가깝다고 판단됩니다. 하나의 유형의 복잡성을 다른 유형의 복잡성과 교환하지만 여러 가지 이점을 제공합니다. 각 방법은 집중적이고 읽기 쉽습니다. 서비스 호출은 분리되어있어 다른 모드의 서비스 실패를 테스트 할 수 있습니다. 이는 시스템 동작 및 기능을 세밀하게 표현한 것입니다. 우리가 측정을 고려하면

액션

public String execute() throws Exception { 
    fbService.updateFriends(code); 
    return SUCCESS; 
} 

FB 서비스는

public void updateFriends(String code) { 
    Token accessToken = getAccessToken(code); 
    Response response = getFriends(accessToken); 
    if (response.getCode() == 200) { 
     processFriends(accessToken, response); 
    } 
} 

private void processFriends(Token accessToken, Response response) { 
    JSONObject json = (JSONObject) JSONSerializer.toJSON(response.getBody()); 
    JSONArray datos = json.getJSONArray("data"); 
    for (Object o : datos) { 
     JSONObject friend = (JSONObject) o; 
     processFriend(friend); 
    } 
} 

private void processFriend(Token accessToken, JSONObject friend) { 
    Response response = getFriendGraph(accessToken, friend.getString("id")); 
    if (response.getCode() == 200){ 
     PerfilContacto pcBean = new JsonParse().parseFacebookElement(response.getBody()); 
     pcDAO.insertarContacto(pcBean); 
    } 
} 

//~ Service interaction 

private Response getFriends(Token accessToken) { 
    return sendSignedGetRequest(PROTECTED_RESOURCE_URL, accessToken); 
} 

private Response getFriendGraph(Token accessToken, String id) { 
    return sendSignedGetRequest("https://graph.facebook.com/" + id, accessToken); 
} 

private Token getAccessToken(String code) { 
    return service.getAccessToken(EMPTY_TOKEN, new Verifier(code)); 
} 

private Response sendSignedGetRequest(String url, Token accessToken) { 
    OAuthRequest request = new OAuthRequest(Verb.GET, url); 
    service.signRequest(accessToken, request); 
    return request.send(); 
} 

, 우리는 다음과 끝.원래

: 재 작업

Average Function NCSS:  24.00 
Average Function CCN:  6.00 
Program NCSS:    25.00 

:

Average Function NCSS:  3.63 
Average Function CCN:  1.38 
Program NCSS:    31.00 

은 궁극적으로 의미 중요한 LOC의

  • 수는 많이 증가하지 않았다.
  • 각 기능은 4 줄 길이 (읽기 쉬운) <입니다.
  • 각 함수의 순환 복잡도는 < 2입니다 (테스트하기 쉽고 이유가 있습니다).
  • 프로그램이하는 일을 더 잘 읽고 더 빨리 이해할 수 있습니다.

트레이드 오프 우리가 복잡성의 유형입니다 (합리적인 IDE 또는 텍스트 편집기 주어진 문제가되지 않을한다) 이상의 메소드를 가지고있다. 그러나 :

  • 우리가 선택할 수있는 깊이로 읽을 수 있습니다.
  • 훨씬 더 세밀하게 테스트 할 수 있습니다.
  • 우리가 놓친 성공/실패 모드를 식별 할 수 있습니다.
  • 우리는 기능을보다 쉽게 ​​교환 및/또는 확장 할 수 있습니다.
+0

이것은 좋은 대답입니다! 인증 정보를 넣어야하는 부분에 대한 조언이 있습니까? OAuth 인증 요청을 하나의 패키지로 그룹화하고이 패키지를위한 스택에 struts 인터셉터를 넣어서이 비트를보다 깔끔하게 처리 할 수있는 것처럼 보입니다. – chad

+0

@chad 아마도 Verifier와 auth가 어떻게 작동하는지에 달려 있습니다. 세션 중에 accessToken이 변경되지 않으면 로그온하는 동안 액세스 토큰을 초기화하고 다시는 걱정할 필요가 없습니다. 변경해야한다면, 인터셉터가 필요로하는 액션에 accessToken을 설정합니다 (인터페이스, 주석 등으로 ​​표시 할 수 있음). –

+0

Dave Newton에게 특별히 답변 해 주셔서 감사합니다. 비슷한 코드에 맞게 코드를 수정 했으므로 이제는 매우 명확합니다. 이제 FB 인증 문제를 해결해야하지만 또 다른 주제입니다. 인터셉터를 사용하라는 제안을 조사 할 것입니다. 고맙습니다 :) – IsabelPM

관련 문제