2009-05-17 5 views
6

업데이트 : 질문 4 개를 추가했습니다.전략 패턴을 사용하는 Java의 Emailer

안녕 모두,

나는 사용자 정의 이메일 유틸리티를 구축하고 있습니다. 이제 Single Responsibility Principle을 따르기 위해 MailerSender, MailProvider 및 EmailObject 클래스가 필요합니다. MailSender 대리자의 이상을, 아래를 체크 아웃 :

public class MailSender { 
    private IMailProvider mailProvider; 

    public void setMailProvider (IMailProvider provider) { 
     this.mailProvider = provider; 
    } 

    // option to set it up during construction 
    public MailSender (IMailProvider provider) { 
     this.mailProvider = provider; 
    } 

    public void sendEmail(EmailObject obj) { 
     if(mailProvider == null) 
      throw new RuntimeException("Need a mail provider to send email."); 

     try { 
      mailProvider.send(obj); 
     } catch (Exception e) { 
      // do something here 
     } 
    } 
} 

MailSender 전자 메일을 보내는 작업을 않는 IMailProvider의 이메일 제공자를 필요로한다. 아래에서 찾으십시오.

public interface IMailProvider { 
    public void sendEmail(EmailObject obj); 
} 

public class SMTPEmailProvider implements IMailProvider { 
    public void sendEmail(EmailObject obj) { 
     // use SMTP to send email using passed-in config 
    } 
} 

public class JMSEmailProvider implements IMailProvider { 
    public void sendEmail(EmailObject obj) { 
     // push emails to JMS queue to be picked up by another thread 
    } 
} 

위의 몇 가지 전략을 정의했지만 임의의 수로 확장 할 수 있습니다. MailSender는 언제든지 공급자를 변경할 수 있으므로 전략 패턴을 효과적으로 구현합니다.

MailSender sender = new MailSender(new SMTPMailProvider()); 
sender.send(new EmailObject()); 
sender.setMailProvider(new JMSMailProvider()); 
sender.send(new EmailObject()); 

내 질문

은 다음과 같습니다 :
1.
내가 전략 패턴을 구현 한

public class EmailObject { 
    private String to; 
    private String from; 
    private String cc; 
    private String subject; 
    private String body; 

    // setters and getters for all 
} 

클라이언트 코드는 다음과 같이 표시됩니다

EmailObject은 relavent 이메일 정보를 포함하는 POJO이다 ?
2.이 디자인이 좋은가요? MailProvider가 EmailObject를 인식하는 것이 합리적입니까?
3. 첨부 파일이 필요한 새 EmailObject를 나중에 만들었습니까?
4. 이제 MailSender를 만들기 전에 클라이언트 코드가 특정 MailProvider를 가져와야합니다.이 말이 맞는가요?

답변

7

자, 질문을 가보겠습니다.

1) 모호합니다. 당신은 당신이 그들 사이에서 선택할 수있는 "알고리즘"또는 "전략"이 있다고 주장 할 수 있습니다. 그러나 나는 전략 패턴을 알고리즘과 관련된 것으로 생각하는 것을 선호한다. 예를 들어, 검색 결과를 얻는 다른 방법. 여기에서는 이메일을 보내는 역할을 위임 한 여러 상담원을 다루고 있습니다. 그것은 일반적인 디자인이지만 필자는 반드시 전략이라고 부를 수 있을지 확신하지 못합니다. 어느 쪽이든, 디자인 패턴은 생각을 돕기위한 것이지 특정 이름으로 잠글 수는 없습니다.

2) 디자인이 합리적이라고 생각합니다. 나는 실제 클래스보다는 인터페이스를 사용할 것이고, 특히 EMailObject에 대해서 말이다. 또한 전자 메일 개체에 대한 팩토리가 있어야하며 새로 작성하지 않아야합니다. 또한 각 공급자가 패키지 세부 정보가 포함 된 자체 "전자 메일 개체"를 제공 할 가능성이 큽니다. "봉투"가 아닌 내용을 보내고 있습니다.

3) 클래스가 아닌 인터페이스를 사용하는 또 다른 이유가 있습니다. 그리고 메타 데이터와 잠재적으로 첨부 파일이 도메인의 합법적 인 부분 (전자 메일)이기 때문에 getter/setter를 포함 할 수 있습니다. 여기

+3

+1이 진술에 대해 : "어느 쪽이든, 디자인 패턴은 생각을 돕기위한 것이지 특정 이름으로 고정시키는 것이 아닙니다." 그것을 배우는 데는 어느 정도 시간이 걸렸습니다 : ^) – bedwyr

+0

나는 이것을 할 수있는 좋은 방법을 찾으려고 노력하고 있습니다. MailerSender는 구체적인 클래스 대신 EmailObject 인터페이스를 사용합니다. 공급자는 정보에 어떻게 접근합니까? 인터페이스는 구체적인 클래스의 정보에 대한 계약을 제공하지만 _added_ 정보로 새 객체를 만들면 어떻게됩니까? 첨부 파일이있는 전자 메일 (바이트 [] 데이터)과 기본 전자 메일 (to, cc, subject, body)의 경우? – djunforgetable

+0

모든 공급자가 익숙한 이메일을 결정하고 인터페이스에서 getter를 제공해야합니다. 공급자는 일반적으로 전자 메일 만 처리 할 수 ​​있으므로 전자 메일에 필요한 모든 것을 입력해야합니다. – Uri

0

가장 중요한 질문은 내 의견에 있습니다

  1. 당신은 실제 이메일을 보내지 않고 구성 요소를 테스트 할 수 있습니까?예 :

    MailSender sender = new MailSender(new FakeMailProvider()); 
    sender.send(new EmailObject()); 
    
  2. 나머지 응용 프로그램없이 이메일 제공 업체를 테스트 해 볼 수 있습니까? 예 :

    SMTPMailProvider provider = new SMTPMailProvider(); 
    provider.send(new EmailObject()); 
    

당신은 성공적으로 보낸 사람의 제공을 분리했다.

편집 : Q4. 클라이언트는 EmailObject를 보내기 전에 특정 MailProvider를 MailSender에 전달해야합니다. 이 진술은 다음과 같이 변형 될 수 있습니다. "클라이언트는 전자 메일 전송 서비스에 전자 메일을 보내고 전자 메일 데이터를 전달하고 전송 (전자 메일을 보내는 방법)을 선택하도록 요청합니다." 나는 괜찮다고 생각하지만, 매번 전송을 지정하고 싶지 않으면 "... 서비스가 구성된 전송을 사용하여 전자 메일을 전송"하고 공급자 인스턴스화를 구성으로 이동하도록 변경할 수 있습니다.

+1

클라이언트가 MailProvider를 MailSender에 전달해야한다는 것이 합리적이라고 생각하십니까? 공장이나 빌더 패턴을 사용하여이 문제를 해결할 수있는 방법이 있습니까? – djunforgetable

+0

축하합니다, 당신은 단지 의존성 주입의 필요성을 깨달았습니다! 내가 여기서 당신을 농담으로 생각하고 있다고 생각하지 마십시오. 이것은 프로그래머를위한 다음 단계와 같습니다. http://codebetter.com/blogs/jeremy.miller/archive/2008/11/11/evolution- of-a-developer-in-a-di-ioc.aspx – bbmud

+0

@bbmud cool! 하지만 DI/IoC 프레임 워크가 없으면 어떻게해야할까요? – djunforgetable

관련 문제