0

クラス「SomeClass」があります。

namespace Namespace
{
    class SomeClass
    {
        // something
    }
}

および属性「SomeAttribute」:

class SomeAttribute : System.Attribute { }

タスク: SomeAttribute 'public const string Type' フィールドですべてのクラス マーケットに追加します。変更されたクラスは次のとおりである必要があります。

class SomeClass
{
    // something
    public const string Type = @"Namespace.SomeClass";
}

更新:

メッセージトランザクションには次のアプローチを使用しています。

class Manager
{
    // message has 3 parts:
    // string message = String.Format("{0}{1}{2}",
    //     typeof(SomeClass).ToString(),
    //     splitter,
    //     Manager.Serialize(someClassObj)
    // )
    public static string GetType(string message) { /* some code */ }
    public static string Serialize(SomeClass message) { /* XML serialization */ }
    public static SomeClass Deserialize(string message) { /* deserialization */ }
}

class Logic 
{
    public void ProcessMessage(string message)
    {
        switch (Manager.GetType(message))
        {
            case SomeClass.Type:
                {
                    SomeClass msg = Manager.Deserialize(message) as SomeClass;
                    // send message to binded objects
                }
                break;
            case ClassInheritedFromSomeClass.Type:
                {
                    // the same
                }
                break;
            // etc.
        }
    }
}

更新 2:

メッセージの詳細。現時点では、次のアプローチを使用しています。

public class BaseMessage
{
    public const string Type = @"Messages.BaseMessage";
}

public class LoginMessage : BaseMessage
{
    public new const string Type = @"Messages.Client.LoginMessage";

    public string Nickname { get; set; }
    public string Password { get; set; }
}

結論

最良のケースは、Manger を次のように変更することだと思います。

class Manager
{
    // create event table

    public Action<BaseMessage> this[string eventName]
    {
        get 
        {
            if (!m_eventTable.ContainsKey(eventName))
            {
                m_eventTable.Add(eventName, new Action<BaseMessage>(message => { }));
            }
            return m_eventTable[eventName]; 
        }
        set
        {
            m_eventTable[eventName] = value;
        }
    }

    public void Send(BaseMessage message, string messageName)
    {
        if (m_eventTable.ContainsKey(messageName) && this[messageName].Method != null)
        {
            this[messageName].Invoke(message);
        }
    }

    private Dictionary<string, Action<BaseMessage>> m_eventTable = new Dictionary<string, Action<BaseMessage>>();
}
4

1 に答える 1

0

switchwithを使用するGetTypeことは、最も派生したクラスのみをチェックする (拡張性を損なう) ため、ポリモーフィズムを実装するための間違った方法です。

Manager特定のケースで、に動作の責任を負わせたい場合は、dynamicキーワードとオーバーロードされたメソッドを使用できます。しかし、これは拡張用に開かれていないため、再び SOLID に違反します。

このように SOLID に違反するのではなく、仮想メソッドを使用して型固有のアクションを実行する方法を見つけてください。

于 2012-05-03T13:54:05.507 に答える