1

クライアント/サーバーからシリアル化されたデータを受け取ります。データが逆シリアル化されると、コマンド ハンドラーに入りreceivedData.ActionますClientMessage

Command._handlers[receivedData.Action].Handle(receivedData.Profile);

コマンド ハンドラーは、クライアント メッセージを処理し、クライアントに提供する必要がある応答を返します。

次のように、クライアント メッセージの列挙型があります。

public enum ClientMessage
{
    INIT = 1,
    NEW_PROFILE,
    UPDATE_PROFILE_EMAIL,
    UPDATE_PROFILE_PASSWORD,
    UPDATE_PROFILE_PHONE,
    UPDATE_PROFILE_DATE,
    UPDATE_PROFILE_SECRET_ANSWER,
    UPDATE_PROFILE_POSTAL_CODE,
    UPDATE_SUCCESS,
    PING,
    PONG,
    QUIT
}

私が苦労しているのは、すべてのアクションを記述する方法です。たとえば、次のようになります。

  • クライアントが送信するものと、サーバーが応答するものに対して別の列挙型を用意する必要がありますか?
  • または、すべてのメッセージを含む単一の列挙型を使用し、要求に従ってそれに従う必要がありますか?
  • または、メッセージを定義して処理するにはどうすればよいですか?

これは、より良いビューを提供するために、現在私のサーバー/クライアントが行っていることです。

  1. サーバーの起動
  2. クライアント接続
  3. クライアントが認証をサーバーに送信
  4. サーバーはクライアントを検証し、接続された承認メッセージを送信します
  5. クライアントはそこからサーバーへのプロファイルの送信と更新を開始します

これはおおよその例にすぎません。

IPacketHandler

public interface IPacketHandler
{
    MyCommunicationData Handle(ProfileData profile);
}

指示

public class Command
{
    public static Dictionary<ClientMessage, IPacketHandler> _handlers = new Dictionary<ClientMessage, IPacketHandler>()
    {
        {ClientMessage.INIT, new Init()},
        {ClientMessage.NEW_PROFILE, new NewProfile()},
        {ClientMessage.UPDATE_PROFILE_EMAIL, new UpdateEmail()},
        {ClientMessage.UPDATE_PROFILE_PASSWORD, new UpdatePassword()},
        {ClientMessage.UPDATE_PROFILE_PHONE, new UpdatePhone()},
        {ClientMessage.UPDATE_PROFILE_DATE, new UpdateDate()},
        {ClientMessage.UPDATE_PROFILE_SECRET_ANSWER, new UpdateSecretAnswer()},
        {ClientMessage.UPDATE_PROFILE_POSTAL_CODE, new UpdatePostalCode()},
        {ClientMessage.UPDATE_SUCCESS, new Success()},
        {ClientMessage.PING, new Ping()},
        {ClientMessage.PONG, new Pong()},
        {ClientMessage.QUIT, new Quit()},
    };
}

INIT の例

public class Init : IPacketHandler
{
    public MyCommunicationData Handle(ProfileData profile)
    {
        // Some verification to auth the client here 
        // bla bla
        // return response
        return new MyCommunicationData() { Action = ClientMessage.CONNECTED };
    }
}

PS: 私のタイトルがずれていて、より良い提案がある場合はお知らせください。または、更新していただける場合は、これを英語で説明する方法がわかりませんでした.

4

2 に答える 2

1

あなたの質問が、私が理解しているようにクラスと相互作用を設計する方法に関するものである場合、私は、アプリケーションの詳細に完全に依存していますが、この大きな列挙型を、それらが何をするかをより説明する個別の小さなものに分けます。 、およびあなたの意図、例えばProfileAction、文字列を渡すだけのように。ActionResultPingStatus

また、OO 設計における単一の責任の原則に固執することにも関係しています。オブジェクトは単一の責任を持つ必要があります。現在の列挙型には複数の責任があります。

このような問題では、.NET フレームワークが何をするかを調べると役に立ちます。たとえば、Ping クラスを見て、PingStatus 列挙やその他の列挙をどのように使用するかを調べます。

于 2012-10-07T16:34:32.423 に答える
0

列挙型をまったく使用するかどうかはわかりません。それらはコードの断片の中で優れており、伝達された価値として公開されていますが、優れているとは言えません。

私にとっては、神のプロパティを持つメッセージではなく、メッセージごとに異なるクラスが必要です。

于 2012-10-11T22:47:13.623 に答える