解释命令串

时间:2009-11-20 05:14:24

标签: design-patterns

说你必须解释像AABBCDEEFF这样的命令参数......并且想法是每个字符代表一个你必须在类上采取一些操作的命令,丑陋的解决方案是编写一个大的开关 - 案件,但我不想使用它,任何人都可以建议一个更优雅的解决方案?

4 个答案:

答案 0 :(得分:4)

创建一个方法地图,例如:map<char, func_ptr>,然后用“操作”填充它:

act_map['A'] = &my_class::func_a
....

for each c in str
  arc_map[c]()

真正的实施取决于您的语言。

但如果你有多达5-10个动作而不仅仅是使用开关。

答案 1 :(得分:2)

让一切尽可能简单。留在SWITCH。

答案 2 :(得分:1)

我的建议是切换,因为编译器会为你优化它。会有多少潜在的角色出现?

答案 3 :(得分:0)

对于C#,在更复杂的情况下,解决方案可以是实现和接口,或添加属性并使用反射来调用命令或方法。

好的,作为一个例子,我创建了一些C#代码

public class ExecuteSequence
    {
        Dictionary<string, Type> classes = new Dictionary<string, Type>();
        public void LoadClasses()
        {
            classes.Clear();
            //load all classes with attribute
            //this can be done at startup once, or on requested refresh
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                foreach (Type type in assembly.GetTypes())
                    foreach (object attribute in type.GetCustomAttributes(typeof(MethodAttribute), true))
                        if (attribute.GetType() == typeof(MethodAttribute))
                            classes.Add(((MethodAttribute)attribute).MethodName, type);
        }

        public string Execute(string sequence)
        {
            string retVal = "";
            foreach (char c in sequence)
                if (classes.ContainsKey(c.ToString()))
                {
                    IMethod method = (IMethod)Activator.CreateInstance(classes[c.ToString()]);
                    retVal += method.Execute();
                }

            return retVal;
        }
    }

    public class MethodAttribute : Attribute
    {
        private readonly string m_MethodName;
        public MethodAttribute(string methodName)
        {
            m_MethodName = methodName;
        }
        public string MethodName
        {
            get { return m_MethodName; }
        }
    }
    public interface IMethod
    {
        string Execute();
    }

    [Method("A")]
    public class MethodA : IMethod
    {
        public string Execute()
        {
            return "FOO";
        }
    }

    [Method("B")]
    public class MethodB : IMethod
    {
        public string Execute()
        {
            return "BAR";
        }
    }

您可以限制扫描的初始程序集列表,但如上所述,这应仅在启动时加载。

希望这有帮助。

相关问题