2010-08-05 9 views
1

작업 대기열을 처리하는 QueueProcessor 클래스가 있습니다. 저는 많은 통계 자료로 이루어진 모든 작업에 대한 요약을 이메일로 보내고 싶습니다. 나는 이미 메일 클래스 (Zend_Mail)를 사용하고 있기 때문에 대부분의 전자 메일 작업은 나에게 추상화되어 있지만 요약 정보를 생성하는 코드를 어디에 넣어야하는지 파악해야한다. 기본적으로 처리 중에 데이터를 수집하고 데이터를 전자 메일에 적합한 형식으로 변환해야합니다.하나의 다른 클래스에 의해서만 사용되는 클래스를 갖게하는 것이 좋지 않습니까?

제 질문은 QueueProcessorSummaryEmail이라는 별개의 클래스를 만들어야합니까, 아니면 원래 클래스와 매우 밀접하게 결합되어 있기 때문에 나쁜 디자인으로 간주됩니까? I 했다는 그것의 자신의 클래스 한 경우, 나는 이메일을 생성하는 것이 데이터의 톤을 통과해야 할 것이다, 그러나 분리의 종류가 좋을 것입니다. 내가 수업을하지 할 경우, 모든 데이터는 QueueProcessor 클래스 내부에서 사용할 수 있지만 그것은 단지 하나 개의 클래스에서 처리 로직 및보고 생성 논리를 혼합 이상한 느낌. 나는 "보고서 생성 논리"를 말할 때

그리고 레코드에 대한

, 나는 HTML 인라인을 생성하고있어 의미하지 않는다; 나는 그 관점을 사용하고있다. 형식화한다는 것은 데이터를 가져 와서 전자 메일 보고서에서 사용할 수있는 데이터로 집계하는 것을 의미합니다.

+0

왜 QueueProcessorSummaryEmail을 내부 클래스의 QueueProcessor로 만들지 않습니까? 따라서 어떤 데이터도 전달할 필요가 없습니다. –

+2

C# StyleCop에서 파일 당 두 개 이상의 클래스에 대해 불만을 제기합니다. 어쨌든, 그것이 작동하고 상대적으로 버그가 없다면, 다른 버그와 기능으로 넘어 가지 않을까요? 패턴과 클래스 계층 구조 (고급 요소)에 대해 너무 많이 생각하면 민첩성을 유지할 수 있습니다. 코드에 대한 가장 중요한 변경 사항은 실제 고객이 기능 A)이 필요하고 버그 B)를 견딜 수 없다는 불평을하는 것입니다. 사용자가 아직 알지 못하는 사항입니다. 그래서, 그것을 끝내고, 그것을 꺼내서, 성숙한 후에 그것을 연마하십시오. –

+2

@Hamish Grubijan 너무 민첩하지 마십시오. 애자일은 그 자리를 지키고 장점이 있지만, 기술적 부채와 같은 것이 있습니다. 현재 활발하게 진행되고있는 애자일, 시그마 6 또는 다른 유행 관리 스타일이 현재 유행하고 있다는 판단을 완전히 내리지 않게하십시오. – BenAlabaster

답변

4

Ryeguy,

나의 제안은 QueueProcessor의 기능을 확장하기 위해 (같은 SummarizedQueryProcessor 말) 데코레이터 클래스를 생성하는 것입니다. 이것은 관심의 분리 정도를 높이고 단위 테스트를 단순화합니다.

테드

+1

+1 : 위임 및 전략 패턴. –

0

ryeguy,

내가는 QueueProcessor 클래스를 기본 추상 클래스를 확인한 다음 QueueProcessorSummaryMail 클래스를 만드는 것을 확장하는 유혹 할 것입니다.

확인, 기본적인 예 :

class QueueProcessor 
{ 
    // all your methods and properties 
} 

class QueueProcessorSummaryMail extends QueueProcessor 
{ 
    // add your custom properties and methods here 
} 

희망이 당신에게 주 아이디어를 제공합니다.

[편집은 물론 그 PHP 용이다. C#의 경우에도 추상 클래스 나 인터페이스를 사용합니다.

+0

나는 그것이 상속의 좋은 사용이라고 생각하지 않는다. 그것은 "is-a"관계가 아니다. – ryeguy

4

원래 클래스와 매우 밀접하게 결합되어 있기 때문에 나쁜 디자인으로 간주됩니까?

는 아니, 그건 문제가되지 않습니다. 서브 클래스 - 수퍼 클래스 디자인 또한 단단히 결합되어 있습니다.

처리 논리와보고 생성 논리를 하나의 클래스로 혼합하면 이상하게 느껴집니다. 보고/요약

대표단은 종종 의미가 있습니다. 보고 기능은 처리 방식보다 더 빠르게 변경되고 확장됩니다.

1

한 가지 방법은 인터페이스를 사용하여 디자인이 드 부부를 도와줍니다. 예를 들어 ISummaryDataProvider이라는 인터페이스를 만들고 QueueProcessor에 요약 데이터를 처리하는 다른 클래스의 데이터를 제공하는 데 필요한 속성 및 메서드와 해당 인터페이스를 구현할 수 있습니다.

그러면 QueueProcessorSummaryEmail에 대한 생성자는 ISummaryDataProvider을 매개 변수로 사용할 수 있습니다.그런 식으로 QueueProcessor이 아닌 다른 것으로 요약 데이터를 가져 오는 경우 새로운 데이터 소스가 을 구현하여 QueueProcessorSummaryEmail에 의해 올바르게 소비 될 수 있도록해야합니다.


나는 내 질문에 How should I model my code to maximize code re-use in this specific situation? 비슷한 객체 지향 설계 문제를 탐구. 대답 중 하나는 의존성 주입을 사용하여 제안했는데, 그 전에는 실제로 이해하지 못했습니다. 내 질문의 맨 아래에 느슨하게 결합 된 방식으로이 솔루션을 구현 한 방법을 알 수 있습니다. 귀하의 상황에 도움이되는 정보를 찾을 수 있습니다.

0

구조가 중요합니다. 실제로 클래스에 속하지 않는 논리 집합이있는 경우 다른 곳에서 리팩토링하면 장래에 mainatainability를 실제로 도울 수 있습니다.

내부 클래스를 지원하는 언어에서는 내부 클래스로 만들 수 있습니다. 나중에 메일을 분리하여 재사용 한 다음 Mail 클래스가 받아 들일 수있는 인터페이스와 큐 프로세서가 구현하는 인터페이스를 정의하는 시점에서 데이터를 전달해야 할 수도 있습니다.

0

어때?

public interface WorkProcessorI { 
    public void process(WorkQueue queue); // could also be something like "process(Task[] queue)" 
} 

public interface SummaryGeneratorI() { 
    public String[][] generateSummary(); // returns subscripted string array of name/values or whatever 
} 

public class QueueProcessor implements WorkProcessorI, SummaryGeneratorI { 
    public void process(WorkQueue queue) { 
     // process queue populating member values that will be used to generate the summary. 
    } 

    public String[][] generateSummary() { 
     // read values that were populated by the process(WorkQueue) method. 
    } 
} 

public class SummaryMail { 
    private String[][] summary = null; 
    public void setSummary(String[][] argSummary) { 
     this.summary = argSummary; 
    } 
    // to, from, server, cc, bcc, subject, Additional body text, ... 

    public void send() { 
     // sends email via whatever api you want. 
    } 
} 
관련 문제