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

使用switchwithGetType是实现多态性的错误方法,因为它只检查派生最多的类(破坏可扩展性)。

在您希望Manager对行为负责的特定情况下,您可以使用dynamic关键字和重载方法。但这将再次违反 SOLID,因为它不开放用于扩展。

不要以这种方式违反 SOLID,而是尝试找到一种方法来使用虚拟方法来执行特定于类型的操作。

于 2012-05-03T13:54:05.507 回答