2

http post/get using xml メッセージを使用するアプリケーション インターフェイスがあります。インターフェイス システムは、結果コードと要求されたデータを含むメッセージを返します。結果コードは、タイプ (ログイン、要求...) ごとにグループ化されたコードとサブコードの 3 つの部分です。一部のコード/サブコードは、ログイン成功などのメッセージであり、その他は無効なログインや無効なメッセージ リクエストなどの例外です。

結果コードを処理し、必要に応じてメッセージで例外をスローする方法を見つけようとしています。結果コードが情報のみの場合は、戻りメッセージのメッセージを API コンシューマーに適用するだけです。私は責任の連鎖を見ていますが、それを乗り越えようとして脳のブロックに遭遇しています.

サンプルコード
タイプ....コード..サブコード....説明
ログイン...0.....0....成功要求
ログイン...0.....nn .........ログイン成功。有効期限まで残り「nn」日
Login...21....1..........ログインに失敗しました。(ユーザーID/パスワードが間違っています)。
Login...21....4..........すでにログインしています
Login...21....5....システムリソースが利用できません。セキュリティ オブジェクトの割り当てに失敗しました
Request.50....2........service 無効な構文
Request.50....3....service 無効な属性
Request. 50....4........service バッチファイルは既に存在します

結果コード (コード、サブコード) を含む結果メッセージ:
loginmanagerresult 0、0 は情報提供、 すべて
正常

<?xml version="1.0" encoding="UTF-8"?>  
    <loginmanagerresult sessionname="ALBHMROC9040RL1" code="0" subcode="0">
        <loginresult code="0" subcode="24855" sectoken="f1044f0aaad65ef2e28d4edc0663716f00000000"></loginresult>
    </loginmanagerresult>

オブジェクトを次のようにデシリアライズしました: 変更、拡張\継承はできませんが、追加のプロパティ\関数はありません。

public class LoginResult
{

    private string code = "";
    [XmlAttribute("code")]
    public string Code
    {
        get { return code; }
        set { code = value; }
    }

    private string subCode = "";
    [XmlAttribute("subcode")]
    public string SubCode
    {
        get { return subCode; }
        set { subCode = value; }
    }

    private string secToken = "";
    [XmlAttribute("sectoken")]
    public string SecToken
    {
        get { return secToken; }
        set { secToken = value; }
    }

}

[XmlRoot("loginmanagerresult")]
public class LoginManagerResult
{

    private string sessionName = "";
    [XmlAttribute("sessionname")]
    public string SessionName
    {
        get { return sessionName; }
        set { sessionName = value; }
    }

    private string code = "";
    [XmlAttribute("code")]
    public string Code
    {
        get { return code; }
        set { code = value; }
    }

    private string subCode = "";
    [XmlAttribute("subcode")]
    public string SubCode
    {
        get { return subCode; }
        set { subCode = value; }
    }

    private LoginResult loginResult = null;
    [XmlElement("loginresult", IsNullable = true)]
    public LoginResult LoginResult
    {
        get { return loginResult; }
        set { loginResult = value; }
    }

    private QueryCapabilitiesResult queryCapabilitiesResult = null;
    [XmlElement("querycapabilitiesresult", IsNullable = true)]
    public QueryCapabilitiesResult QueryCapabilitiesResult
    {
        get { return queryCapabilitiesResult; }
        set { queryCapabilitiesResult = value; }
    }

    private GetMotdResult getMotdResult = null;
    [XmlElement("getmotdresult", IsNullable = true)]
    public GetMotdResult GetMotdResult
    {
        get { return getMotdResult; }
        set { getMotdResult = value; }
    }

    private LogOutResult logOutResult = null;
    [XmlElement("logoutresult", IsNullable = true)]
    public LogOutResult LogOutResult
    {
        get { return logOutResult; }
        set { logOutResult = value; }
    }


}
4

1 に答える 1

0

あなたが実装しようとしているのは「パターンマッチング」メカニズムです.Chain of Responsibilityパターンは、OOPの同じものの別の名前です。C# には構造パターン マッチングを行う組み込みの方法はありませんが、SO や他の場所で調べることができますが、一般的なアイデアがいくつかあります

これが 1 回限りのことである場合は、(述語、アクション) のペアのように見えるルールのリストを作成してみてください。次に、Match メソッドがルールを 1 つずつ調べ、Predicate が true を返す最初のルールが一致し、その Action が実行されます。

なぜこれが責任の連鎖よりも優れているのでしょうか? 多くのオブジェクトを追加する必要はありません。匿名ラムダを使用して述語とアクションを指定すると、ルール リストがコードの 1 ページに収まり、読みやすく、変更しやすく、レビューしやすくなります。

さらに改善できる簡単な例を次に示します。さらにルールを追加する場合は、いくつかの一般的な述語または述語の一部、およびいくつかのアクションまたはアクションの一部を名前付きデリゲートに抽出することで、読みやすさをさらに向上させることができます。

public class LoginResult
{
    public string Code { get; set; }
    public string SubCode { get; set; }
    public string SecToken { get; set; }
}

public static IDictionary<Predicate<LoginResult>, Func<LoginResult, string>> rules =
    new Dictionary<Predicate<LoginResult>, Func<LoginResult, string>>
        {
            { lr => lr.Code == "0" && lr.SubCode != "0", result => "Login successful, days left till expiration: " + result.SubCode },
            { lr => lr.Code == "0", _ => "Login successful" },
            { lr => lr.Code == "21", _ => ThrowInvalidOperation("Login failed. (Userid/password wrong).") },
        };

static string ThrowInvalidOperation(string message)
{
    throw new InvalidOperationException(message);
}

static string Match(LoginResult result)
{
    foreach (var rule in rules)
    {
        if (rule.Key(result))
        {
            return rule.Value(result);
        }
    }

    throw new ArgumentException("Matching rule not found", "result");
}
于 2012-09-01T04:00:08.510 に答える