我正在用C#编写一个MSN Messenger客户端,并选择为MSNP协议编写自己的解析器,因为我查看了其他客户端的源代码,但我发现代码不符合我的惯常标准 - 特别是线程同步已经非常缺乏思想。
起初,我编写了一个通用解析器,它接受“规则”,告诉它如何解析命令。
例如,我设置了一条规则,规定命令代码“VER”具有事务ID和参数列表。
这项工作正常,但它始终是一个临时解决方案。我的目的是制作一个完全成熟的解析器,分别查看每个命令和参数。
例如
如果命令代码为“VER”,则创建一个VersionCommand类,并将事务ID和接受的协议列表一起传递给它。
然后我的代码可以很容易地解释命令而不会搞乱参数索引等(verCmd.TrId& verCmd.AcceptedProtocols)
我担心的是,为每种命令类型使用单独的类会浪费资源。
所以我的问题是 - 这是浪费吗?有没有其他基于命令的协议实现采取类似的方法?我想做什么先例,或者这是一个愚蠢的想法?
答案 0 :(得分:1)
你的建议并不浪费;相反,你只是在“功能丰富”和“简单”(关于界面和解析)之间进行权衡。
我们已经完成了你提出的 lot 。关键问题:我可以这么简单(例如,像平面解析“跳转表”),还是我的解析需求和实现需要基础设施来允许未来特定于应用程序的扩展?
根据问题的答案,我们做了两个,一个很多:
如果“否”,你有一个(平面)解析的离散(长)列表,你“尝试”解析命令(带有参数),失败,然后直接到下一次尝试等等,直到你完全放弃了所有二十(或一些数字)“被测试”的命令。 好处 :平坦,简单,每个命令都可以拥有自己的自定义参数(因为每个解析尝试都可以验证特定于该命令的参数)。 不要求您为每个命令设置一个类(但如果需要,可以使用)。例如,你可以有一个单 MyCommand
类,它试图用20种不同的方式解析自己,以暗示20种不同参数的枚举命令类型。
如果“是”,您正在投资一个框架。通常,这是为了获得可以以特定于应用程序的方式扩展的“引擎”。在我们的例子中,它还倾向于反映几个命令层次结构,其中每个层次结构可以按特定于应用程序的方式“扩展”到命令。而且,由于这些是独立的层次结构,我们在重用状态和逻辑(使用不同层次结构的公共基类)方面获得了巨大的好处。在这种情况下,每个层次结构的“基础”“嗅探”命令,如果匹配,则确定哪个派生大多数实例应该执行解析和实例化。这个戏剧性简化了解析,因为您对不同的层次结构有不同的数据处理需求(并且该代码在基础中建立),并且您没有一个怪物解析器。通常,我们为每个命令类型都有一个派生类,它有自己的自定义参数要求。这些派生类分组在“层次结构”中,这些层次结构可能(或可能不)共享公共基类(例如,“树”或“森林”模型)。
如果您希望协议相对有限/不变,使用一致的命令参数和类型,“flat”效果很好。如果您想要特定于应用程序的可扩展性,请继续投资于每个类的一个命令类型的基础结构 - 在初始实现的“步法”之后,它工作得很好,特别是当您后来意识到您的参数不正确并且您需要改变实施(这种情况一直发生)。使用one-command-per-class(它还包含特定于命令的解析,而不是超级怪物主解析器)更容易 更容易,尽管我承认它很多更多代码来实现该基础架构。