2010-05-07 3 views
0

이 가상의 예는 내가 계속 노력하고 있어도 과거에 얻을 수없는 몇 가지 문제를 보여줍니다 !! ... 원래 코드가 사용자가 그리드의 셀을 클릭 할 때 트리거되는 UI로 코딩 된 긴 이벤트 핸들러라고 가정합니다. 의사 코드로 표현 그건 : "! 아,이 코드는 디버깅을 쉽게 이해하기 쉬울 것이다 전략 패턴에 리팩토링, 쉽게 나중에 확장"이 코드를 어떻게 리팩토링합니까?

if Condition1=true then 
begin 
    //loop through every cell in row, 
    //if aCell/headerCellValue>1 then 
    //color aCell red 
end 
else if Condition2=true then 
begin 
    //do some other calculation adding cell and headerCell values, and 
    //if some other product>2 then 
    //color the whole row green 
end 
else show an error message 

나는이보고 말 알 겠어.

그리고 코드를 여러 절차로 쉽게 구분할 수 있습니다.

문제는 궁극적으로 범위와 관련이 있습니다. 가상 코드가 격자 속성, 셀에 표시된 값을 광범위하게 사용한다고 가정하고, 심지어 내장 된 격자 방법까지도 가정합니다. UI에서 그리드 구성 요소를 참조하지 않고 어떻게 다른 유닛으로 이동합니까? OOP를 가치있게 만드는 느슨한 결합에 대한 모든 "규칙"을 깨뜨릴 수 있습니까? ...

정말 응답을 기다리고 있습니다. 감사합니다. 언제나처럼 - Al C.

답변

8

코드를 별도의 루틴에 리팩토링한다고해서 반드시 모든 것을 분리하는 것은 아닙니다. 리팩터링하는 이벤트 핸들러와 동일한 클래스에 속하는 새로운 메소드에 리팩터링 할 수 있습니다. 이러한 메서드는 현재 코드에 이미있는대로 모눈 구성 요소에 동일한 액세스 권한을 갖습니다.

당신은 에 일을하는 해당 이벤트에 대한 코드를 작성하는 것을 그 형태에 격자입니다. 다른 이벤트에 대한 응답으로 이러한 작업을 수행 할 필요가 있는지 실제로 예상합니까? 또는 다른 형태로 다른 그리드에서 실행합니까? 그렇지 않다면, 모든 것을 분리하는 것은 학문적 훈련 일 뿐이며 제품에 아무런 도움이되지 않습니다. 응용 프로그램 별 코드를 작성하는 것이 좋습니다.

그런 다음, 그것은 당신의 고려 아웃 루틴에 매개 변수를 추가하는 것입니다 할 수있는 방법을 분리하십시오.루틴은 정확히 인 그리드 모른 채 그리드로 작업해야하는 경우, 다음의 매개 변수로 격자를 통과 :

if Condition1 then 
    ColorCellsRedAboveRatio(Grid, 1.0) 
else if Condition2 then 
    ColorRowsGreenAboveProduct(Grid, 2) 
else 
    Error; 
+1

똑같은 표를 같은 방식으로 나타내야 할 필요가있는 경우 동일한 규칙을 존중하고 여러 양식에서 코드를 독립적 인 단위로 옮기는 것이 좋습니다. 허락한다면, 그리드를 프레임에 넣고 프레임을 재사용하면 같은 목적을 달성 할 수 있습니다 ...하지만 프레임의 큰 팬이 아닙니다. –

+1

@Ken, "여러 줄의 동일한 격자 ..."는 모순입니다.하나의 컨트롤은 두 가지 형태로 존재할 수 없습니다. 동일한 방식으로 처리해야하는 두 개의 그리드를 가질 수 있지만 여전히 두 개의 다른 컨트롤이며,이 시점에서 일반적인 처리를 별도의 루틴으로 분해 할 가치가 있습니다. –

+0

"눈금"을 "일부 시각적 컨트롤"이 아닌 "데이터보기"로 읽습니다. 나는 그리드의 정의가 후자에 국한 될만큼 길게 프로그램하지는 않았지만 모호함을 지적 해 주셔서 감사합니다. 일부 사람들은 그 점을 이해하지 못할 것이라고 생각하지 않았습니다. –

2

먼저 무엇보다도 값을 참값과 비교하지 마십시오. 그것은 사실이 수에 비교

if Condition1 then 
begin 
end else if Condition2 then 
begin 
end; 

의, 최악의 경우, 값 사실 경우에도 실패합니다. Delphi-PRAXiS.net 커뮤니티 포럼에는이 이상한 모양의 동작을 재연하는 예제가 나와 있습니다. (독일 언론사의 'Über den Umgang mit Boolean')

이 코드는 사용자 정의 페인트 이벤트 좋을 것이다 : 직접 귀하의 질문에 대해서는

. 이것은 모든 셀에 호출되고 올바른 색상으로 직접 페인트합니다. 그리고 다시 칠해도 정확한 색상으로 그립니다. 귀하의 경우에는 셀을 한 번만 그리면 어떤 이유로 든 그리드가 다시 칠해지면 색상이 손실됩니다.

이 코드는 결국 UI와 구성 요소와 관련된 문자열입니다. 양식에이 표가 없으면이 코드가 필요하지 않습니다. 그리드 행에서 검색된 값을 계산 만 수행하고 논리 결과를 반환하는 외부 장치로 전달하는 것이 일을 분리하는 데 할 수있는 일이 있습니다. 폼의 UI 코드는이 결과를 가져와 표시 방법 (예 : 색상 등)을 결정하고 정보를 그리드에 배치해야합니다.

+0

표현을 "True"와 비교하는 것과 관련하여 다음과 같은 좋은 예가 있습니다. "if Boolean (2) then"이 실행됩니다. "부울 (2) = True이면"실행되지 않습니다. –

+0

응답 해 주셔서 감사합니다. 독자들에게 더 명확해질 것이라고 생각했기 때문에 나는 "= 사실"을 가지고 있었지만, 그 점에 감사드립니다. 나는 다른 점에 너무 감사한다 - 소년은 그것을 바르게 평가한다! 시간이 지나면 그리드를 다시 칠하기 때문에 문제를 추적하는 데 몇 시간을 소비하는지 말할 수 없습니다. 수업은 배웠다. –

0

당신은 UI 따라 단위를 추출하기 위해 고려할 수 있습니다. 방법이 길고 수업에서 몇 가지 물건을 추출하려는 경우 전략을 추출하는 것이 합리적입니다.

Rob은 전략 절차에 필요한 컨텍스트를 전달할 수 있다고 제안했습니다. 적절한 추상 메소드를 가진 SheetRenderingStrategy를 소개하고 SubClasses를 적용 할 수 있습니다. 이 SpecialSellsStrategy를 강조 표시하십시오. 이러한 클래스는 여전히 UI의 일부이지만 의도를 명확히하고 모듈화를 향상시킵니다.

0

리팩토링에 대한 질문에 컨텍스트없이 대답하면 문맥없이 디자인에 대한 질문에 대답하는 것과 같습니다. 당신이 디자인을 바꾸고 있기 때문입니다. 나는 보통 "리팩토링하는 이유"로 시작합니다. 어쩌면 제가 초과하는 측정 기준을 가지고있을 수도 있습니다. (보세요, 10,000 라인을 가진 클래스, 확실히 그것은 더 적은 결합과 더 단단한 응집력으로 더 일관성 있고 더 응집력있는 클래스로 분할 될 수 있습니다.)

이벤트 처리기에서 수백 가지 if ... else 조건을 가진 많은 코드가있는 경우 자주 발생하는 것처럼 해당 이벤트 처리기에 대한 정보는 모두 잊어 버리 겠지만 사람이 최소 객체 지향 패턴 위에서 말했듯 :

당시로서는 DOA (이하, 파라미터) 경우 다른 경우 관측기는 (일반적으로는, 더 나은) b를 다른 경우 DOC C; ...

이제 doA, doB 및 doC가 다른 객체에서 함께 존재하면 (상태를 공유하고 일부 특정 필드 집합을 수정/제어) doA, doB 및 doC 메소드를 다른 객체로 이동시킬 수 있습니다. 목적. 일반적으로

그러나, 오히려 드릴 다운보다 이벤트 핸들러는 모든 것을 할 경우, 나는 또한 편리 다음 델파이 패턴 찾을 사례 별 개별 :

procedure TForm1.BigGuiControlRightButtonClick(Sender;...); 
begin 
    BigThingController.RightClickMenuHandler(Sender, ....) 
end; 

procedure TForm1.BigGuiControlDoSomeThing(Sender:TObject); 
begin 
    BigThingController.DoSomeThing; 
end; 

procedure TForm1.Print(Sender); 
begin 
    DocumentManager.Print(Document); 
end; 

내 TForm을 좋아을 방법은 명확하고 읽기 쉽습니다. 나는 많은 잡음과 많은 오류 검사 코드를보고 싶지 않다. 나는 조심스럽게 관리되고 수년간 디버깅 된 응용 프로그램이 읽을 수없는 스파게티를 완전히 엉망으로 만드는 경향이 있다는 것을 알게되었습니다. 리팩토링의 목적이 코드를보기 좋게 만 드는 것 이상의 것이라면 리팩토링도 약간의 측정 가능한 품질 목표를 가져야합니다. 결함, 충돌 등을 줄입니다. 때로는 리팩토링을 더 이상 유용하지 않거나 잘못된 방식으로 구현 된 기능을 제거하는 데 사용합니다. 따라서 필자의 코드는 완성되었을 때보다 정확하며, 코드 작성 방법의 이상에 적합하도록 리팩터링되지 않고 사용자가 경험하는 품질을 변경하지 않습니다. 나는 델파이 개발자이고, 나는 목표 지향적이며, 품질 지향적이며 실용적인 스타일러가 아닙니다. 다른 사람들은 여기 다를 수 있습니다.

관련 문제