6

更新:もう1つの質問を追加しました(質問#4)。

こんにちは、みんな、

私は自分でカスタムメールユーティリティを構築しています。ここで、単一責任の原則に従うために、次のクラスが必要です: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はいつでもプロバイダーを変更できるため、戦略パターンを効果的に実装しますか?

EmailObjectは、関連する電子メール情報を含むPOJOです。

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

    // setters and getters for all
}

クライアントコードは次のようになります。

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

私の質問は次 のとおり

です。1。戦略パターンを実装しましたか?
2.このデザインは良いですか?MailProviderがEmailObjectを認識することは意味がありますか?
3.後で添付ファイルが必要な新しいEmailObjectがあった場合はどうなりますか?
4.クライアントコードは、MailSenderを作成する前に特定のMailProviderを取得する必要があります...これは意味がありますか?

4

2 に答える 2

7

では、質問を見ていきましょう。

1) 漠然と、はい。「アルゴリズム」または「戦略」があり、それらから選択できると主張することができます。ただし、私は戦略パターンをアルゴリズムに関連するものと考えています。たとえば、検索結果を取得するさまざまな方法。ここでは、メール送信の役割を委任するさまざまなエージェントを扱っています。これは一般的な設計ですが、必ずしも戦略と呼ぶかどうかはわかりません。いずれにせよ、デザイン パターンは思考を支援するためのものであり、特定の名前に縛られるためのものではありません。

2) デザインは妥当だと思います。特に EMailObject については、実際のクラスではなくインターフェイスを使用します。さらに、新しいだけでなく、メール オブジェクトのファクトリが必要です。また、各プロバイダーがパッケージの詳細を含む独自の「メール オブジェクト」を提供する可能性も非常に高くなります。「封筒」ではなく中身を送ります。

3) これは、クラスではなくインターフェイスを使用するもう 1 つの正当な理由です。また、メタデータや場合によっては添付ファイルがドメイン (電子メール) の正当な部分であるため、それらのゲッター/セッターを含めたい場合があります。

于 2009-05-17T23:13:15.417 に答える
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 に渡す必要があります。このステートメントは、次のようなものに変換できます。「クライアントは、電子メール サービスに電子メールの送信を要求し、電子メール データを渡し、トランスポート (電子メールを送信する方法) を選択します」。それでいいと思いますが、毎回トランスポートを指定したくない場合は、「...サービスは構成されたトランスポートを使用してメールを送信します」に変更し、プロバイダーのインスタンス化を構成に移動できます。

于 2009-05-18T00:18:57.007 に答える