2010-04-28 2 views
1

코드 중복을 피하기 위해 제네릭 (또는 다형성)을 사용하는 데 도움이되는 질문을 방금 받았습니다. 저는 DRY 원칙을 따르려고 정말로 노력하고 있습니다.코드 복제가 발생하지 않도록 작업 대리인을 사용 하시겠습니까?

그래서 난 그냥

Sub OutputDataToExcel() 
    OutputData("Output DataBlocks", New Action(AddressOf OutputDataBlocks)) 
    OutputData("Output Numbered Inventory", New Action(AddressOf OutputNumberedInventory)) 
    OutputData("Output Item Summaries", New Action(AddressOf OutputItemSummaries)) 
End Sub 

Sub OutputData(ByVal outputDescription As String, ByVal outputType As Action) 
    OutputLine(outputDescription, 1) 
    outputType() 
    OutputLine("") 
End Sub 

나는이 문제는 실현 ...
Sub OutputDataToExcel() 

     OutputLine("Output DataBlocks", 1) 
     OutputDataBlocks() 
     OutputLine("") 

     OutputLine("Output Numbered Inventory", 1) 
     OutputNumberedInventory() 
     OutputLine("") 

     OutputLine("Output Item Summaries", 1) 
     OutputItemSummaries() 
     OutputLine("") 

End Sub 

내가 작업 대리자를 사용하여 다음과 같은 일이 코드를 다시 작성해야 ... 다음 코드로 실행 주걱. 나는 당신이 얼마나 신중히 DRY를 따르고 있는지 궁금 할뿐입니다. 이거 해줄 래?

세스

답변

4

"중간의 구멍"패턴이라고 불리는 것을 보았습니다. "실제 세계 기능 프로그래밍"책에 언급되어 있습니다. 여기에 링크가 있습니다.

http://enfranchisedmind.com/blog/posts/the-hole-in-the-middle-pattern/

참조, 나는 받은 Ocaml- 년에 사용했던 패턴이 있고 난 심지어에게 나는 "중간에 구멍 의"로 생각 펄에서 를 사용하는 것 무늬. 의 기본 아이디어는 두 조각의 코드가 거의 일치한다는 것을 제외하고는 작은 중간 부분을 제외하고는 모두 입니다. 이 아이디어는 일반 코드를 함수로 인수 분해하는 것으로 함수는 포인터를 인수로 취합니다. 공유 코드의 중간 부분은 함수 포인터를 호출하고, 는 단순히 독특한 부분을 포함하는 기능 에 대한 포인터와 결합 된 함수를 호출 합친되고있는 두 군데로 대체됩니다.

+1

중간 패턴의 구멍? 도넛 패턴이라고 부를 수 있을까요? 음 ... 도넛. –

1

내가 모든 시간을 사용하지만, 내가 코드 중복을 피하기 위해 작업 대리자를 사용했을 언급하지 않았다. 하나의 시나리오는 동일한 보일러 플레이트 코드를 피하기 위해 클라이언트 프록시 내부에서 WCF 호출을 래핑하는 것입니다.

private void InvokeAndHandleFaults(
     Action<Data, Context> wcfCall, 
     Data data, 
     Context context) 
    { 
     bool isSuccess = false; 

     try 
     { 
      wcfCall(data, context); 

      if (this.ChannelFactory.State != System.ServiceModel.CommunicationState.Faulted) 
      { 
       this.ChannelFactory.Close(); 
      } 

      isSuccess = true; 
     } 
     catch (FaultException ex) 
     { 
      HandleFault(ex); 
     } 
     finally 
     { 
      if (!isSuccess) 
      { 
       this.ChannelFactory.Abort(); 
      } 
     } 
    } 

예문과 관련하여 나는 액션을 사용하지 않았을 것입니다. 나는 액션을 사용하기 위해 리팩토링하지 않을 것입니다. 주로 실제 논리가 매우 간단하므로 많은 이점을 얻지 못하기 때문입니다. 반복되는 코드의 "복잡성"/ 크기가 커짐에 따라 대리인을 더 많이 사용하게 될 것입니다.

관련 문제