博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

剖析SharpDevelop:Command模式的应用

Posted on 2005-01-20 12:03  jeseeqing  阅读(4563)  评论(11编辑  收藏  举报

剖析SharpDevelopCommand模式的应用    

SharpDevelop是一个非常优秀的开源项目,其中有一些思想非常出色的,如插件结构,服务设计,设计模式的应用,UI与行为的抽离,以及可插入式的设计结构, 其中有些设计思想我已经应用到我以前开发过的一些项目中。由于我的文笔不好及工作太忙,所以一直没有写什么心得之类的笔记。现在有点时间,也来记录一下我的分析随笔,先来分析一下SharpDevelop中模式的应用,至于其非常优秀的插件结构,博客园已有兄弟作过分析了。

           在剖析Command模式之前,先来看一下.NET Framework中的菜单及工具栏处理存在的一些缺点:

1.            无法自动同步更新菜单项与工具项的状态以及相关的行为及特性,需要手动去处理两个事件,从而造成了相同的两个操作需要两次处理,也就造成了需要手动地同时维护多份相同的操作;

2.            无法重用菜单项这部分的功能,因为在dotnet中菜单项的单击需要集成在UI中;

3.            无法很好地扩展,如需要增加或删除菜单项,则需要更改原有的代码及UI部分的设计,从而违反了OCP(开闭)原则。按照OCP原则,当扩展相关的功能时,不应该修改原始的代码,而应该扩展该代码;

4.            无法将相关的消息当作原子状态处理,试想一下,如果一个系统不仅通过菜单、工具栏来操作用户接口,也可通过命令(如Visual Studio就可以通过输入命令而执行相关的操作)来执行,如果不将相关的操作抽象出来的话,维护这个操作的成本太大。并且如果想实现更进一步的控制比如精确到原子状态的权限控制,则很难实现。

我们可以运用Command模式,将菜单项相应的操作抽象出来,定义一个命令接口ICommand,此接口仅具有Run方法,可以作为任何命令的基接口。但是由于菜单还具有一些其它的特性,如是否可见,是否可用,文本,需要执行此菜单项的宿主,所以再定义了一个IMenuCommand接口继承此接口,加入了一些新的特性,并定义了一个实现IMenuCommand接口的抽象基类MenuCommand,其它类可以派生此类。由于我自已修改了SharpDevelop中的一些设计,所以可能有些与原版的不一样。

 
          ICommand
接口:是一个最基本的接口,代表一个动作的行为;

IMenuCommand接口:派生于ICommand接口,作为菜单项或工具项所实现的行为及特性来使用;

IStatusUpdate接口:描述一个能够更新状态的接口,当对象需要更新状态时将调用此接口,如菜单项需要动态地更新EnableVisible特性;

MenuCommand抽象基类:实现了IMenuCommand接口,任何菜单命令可以从此继承;

CustomCommandBarItem:继承于CommandBar组件的CommandBarButton类,类似于菜单项或工具项,实现了IStatusUpdate接口,以根据IMenuCommand接口的VisibleEnabled属性的改变而相应地更新其Enabled,Visible属性;

CustomCommandBarMenu:继承于CommandBar组件的CommandBarMenu类,类似于菜单条。           
    当我们在客户端需要创建命令时,只需写相关的类继承于MenuCommand         
        

           在这里使用了另外一个开源组件CommandBarCustomCommandBarItem类的构造函数通过传入一个IMenuCommand类的实例与IMenuCommand关联起来,将单击事件(OnClick方法)委托给ICommand接口的Run方法来执行,其Update方法用于更新状态。CustomCommandBarMenu类中的OnDropDown方法用于当打开菜单条时通过调用IStatusUpdateUpdate方法自动更新所有菜单项的状态。

           SharpDevelop处理所有插件的菜单中,此处的设计是支持的基础。

          

           如果更进一步,可以在SharpDevelop中加入类似于Visual Studio的“命令窗口”;如果是一个ERP系统或MIS系统,可以将权限控制写在IMenuCommand中的Enabled中,在执行Run方法之前先检测Enabled,如果Enabledfalse则禁止执行,我先前写过一个权限框架,通过AttributeReflect技术来实现权限的自动控制。

           Reference:

1.            吕震宇的设计模式系列文章

2.            GoFDesign Pattern