用State模式建立向导的实践。。。

简介:
向导就是类似于安装软件时,一大堆下一步的那个窗体。每一个上一步下一步意味着窗体上的控件需要改变,相关的按钮的功能等也需要改变。在制作一个向导时,最初设计中,我用的enum来表示每一个步骤。比如:
switch(stepEnum) 

case StepEnum.FirstStep: 
    //some work 
    break; 
case StepEnum.SecondStep: 
    //some work 
    break: 
//... 
default: 
    //... 
}
这样的设计,使得整个代码中充斥着大量的switch...case语句,并且使得每个步骤涉及到的控件布局,逻辑处理等代码混在一起。很是丑陋,无法忍受。于是我想用试着用state模式来除掉这些坏掉的味道。
State模式用[GOF]的话来说,使允许一个对象在其内部状态改变时改变它的行为。我定义一个抽象的步骤类来取代原有的枚举结构,各步骤继承与这个抽象类。其定义如下:
public abstract class InitWizardStepState 

        public abstract void AddControlToContainer(Control container); 
        public abstract bool CouldGoToNext(); 
        public abstract InitWizardStepState GoToNextStep(); 
        public abstract InitWizardStepState GoToPreStep(); 
        public abstract bool IsFirstStep { get;} 
        public abstract bool IsLastStep { get;} 
}
 
通过这样的设计,将每一个步骤的逻辑判断和UI设计都封装在了StepState中。避免了在主窗口中使用枚举类来判断各个操作。简化了主窗口的代码,实现了相关的隔离,除掉了坏掉的味道。同时,利用单件模式,降低反复上一步,下一步付出的代价。基本达到了目的。
但是实践就是实践,没有经典问题那么的纯粹,有些问题很是折磨人。比如步骤转换的控制是由谁控制。步骤转换并不是一个简单的由1-->2-->3-->...的过程。而根据用户输入和选择的不同,可能存在1-->3-->...这样的路径,也可能有1-->2(1)-->3-->...这样的路径。设计中是将状态的转移控制封装在了InitWizardStepState类中(使用GoToNextStep和GoToPreStep来控制)。比如:在1步骤是获取需要转移和需要删除的文件列表,2步骤处理转移文件,3步骤处理删除文件。如果1步骤中,用户并没有输入转移文件,就可以跳过2直接进到3中。直接封装在步骤中可以使得这种处理可以在内部完成。但我越来越觉得这不是一个良好的决定。因为并不符合开闭原则。如果我需要建立一个新的向导,这个向导的次序和相关处理与老步骤不同。我如果还想使用原先的步骤类,我必须修改里面的逻辑,而并不是利用继承建立新的步骤即可。说明这个设计不够良好。
导致这个问题出现的原因,我想是因为在步骤转换是存在着数据的转移.比如在1步骤中获得了某个路径,在2步骤中需要获得这个路径,就将路径需要由步骤1传个步骤2。这其实就与state模式的应用范围产生了偏差。在state模式中,要求作为state的对象可以不依赖于其他对象而独立变化。所以我一直不确定我所谓的state是不是真正的state。
在下一步工作中,想继续改造上面的结构。即把各个步骤所需的(输入和输出的数据)放在一个类中,作为一个context存在。比如:以上面的转移文件和删除文件为例,建立context如下:
public class Context 

        public string[] deleteFileList; 
        public string[] moveFileList; 
}
 
然后将决定上下步骤的部分从StepState中提取出来。放在主窗口中完成。进一步降低了步骤类之间的耦合。同时增加各步骤类于Context之间的联系。比如:
将public abstract void AddControlToContainer(Control container);
改为public abstract void AddControlToContainer(Control container,Context context);
这样可以更好的保持可扩展性和可重用性。









本文转自 duguguiyu 51CTO博客,原文链接:http://blog.51cto.com/duguguiyu/363383,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
存储 前端开发 JavaScript
State 状态管理最佳实践
【10月更文挑战第1天】本文深入浅出地介绍了前端开发中的状态管理概念,强调其在构建复杂单页应用(SPA)中的重要性。文章详细阐述了状态管理的核心原则,如单一源真理、状态不可直接修改及状态变更透明,并对比分析了如Redux、Vuex和MobX等常用状态管理库。通过具体代码示例,指出了状态分散和非原子操作等常见问题及其解决方案,为开发者提供了实用指导。
142 1
|
4月前
|
缓存 前端开发
ProFlow 流程编辑器框架问题之创建一个自定义节点如何解决
ProFlow 流程编辑器框架问题之创建一个自定义节点如何解决
53 1
|
7月前
|
网络协议 网络安全
在Windos Server 2016 版本配置网络参数和接入工作组网络
在Windos Server 2016 版本配置网络参数和接入工作组网络
jira学习案例24-用useAuth切换登录与非登录状态
jira学习案例24-用useAuth切换登录与非登录状态
147 0
jira学习案例24-用useAuth切换登录与非登录状态
jira学习案例5-用状态提升分享组件状态1 原
jira学习案例5-用状态提升分享组件状态1 原
52 0
jira学习案例5-用状态提升分享组件状态1 原
jira学习案例5-用状态提升分享组件状态1
jira学习案例5-用状态提升分享组件状态1
81 0
jira学习案例5-用状态提升分享组件状态1
jira学习案例7-用状态提升分享组件状态3
jira学习案例7-用状态提升分享组件状态3
99 0
jira学习案例7-用状态提升分享组件状态3
jira学习案例98-跨组件状态管理
jira学习案例98-跨组件状态管理
109 0
jira学习案例98-跨组件状态管理