论道——工厂模式与装饰模式的融合
来源:互联网 发布:项目经理懂代码 知乎 编辑:程序博客网 时间:2024/05/23 00:01
[置顶] 论道——工厂模式与装饰模式的融合
分类: web 三层2013-11-06 16:30 393人阅读 评论(36) 收藏 举报
目录(?)[+]
在做项目之前总绝得需求为王很对,但是到自己的代码中,总是感觉不得要领,一直到我们做考试系统,大家讨论需求的时候,需求的各种乱,各种不知道怎么平衡,各种讨论,再到一个个的确定,一个个得多方平衡,才明白,需求就是一切!
今天给大家介绍一个特殊的需求,在做考试系统的过程中,我们的想要将题型的变化封装到dll里,设计模式里的装饰模式可以做到增加一个新的题型而不动代码,但是他有个弊端就是客户端要实例具体的题型类,我想将创建也 封装起来,就用简单工厂模式对装饰者做了个优化,现在给大家分享:
1,装饰模式第一版:
代码:
抽象页面
- <span style="font-size:18px">/// <summary>
- /// 装饰者——抽象的页面——组卷的抽象类
- /// </summary>
- public class AbstractPage
- {
- // public double Fraction;
- //展示页面
- public virtual void ShowPage()
- { }
- }</span>
问题页面
- <span style="font-size:18px">/// <summary>
- /// 装饰者模式——题的抽象展示页面
- /// </summary>
- public class QuestionsPage:AbstractPage
- {
- //每个题里都有一个页面——可以看做未具体题型在这里的暂存位置,将各个题型的作为另一个题型的属性
- protected AbstractPage LittleQuestionsPage;
- protected static double AllFraction;
- public double GetAllFraction()
- {
- return AllFraction;
- }
- //加入新的题型,做到题型的累加,将各个题型串联起来
- public void AddQuestionsPage(AbstractPage QuestionsPage)
- {
- this.LittleQuestionsPage = QuestionsPage;
- }
- //抽象的显示,显示具体的题型内的题型页面
- public override void ShowPage()
- {
- if (LittleQuestionsPage!=null)
- {
- LittleQuestionsPage.ShowPage();
- }
- }
- }</span>
其中一个具体的页面(选择题)
- <span style="font-size:18px"> /// <summary>
- /// 显示选择题——装饰者
- /// </summary>
- public class ChoiceQuestionPage : QuestionsPage
- {
- /// <summary>
- /// 构造类
- /// </summary>
- public ChoiceQuestionPage()
- {
- }
- //抽象的显示,显示具体的题型内的题型页面
- /// <summary>
- /// 显示选择题
- /// </summary>
- public override void ShowPage()
- {
- //较为关键代码——先显示自己包含的装饰者的装饰
- base.ShowPage();
- ///页面显示选择题——略
- }</span>
总结:
整个的装饰模式相当于将每个纸片打孔,让他可以和具体的纸片用钩子连接起来,这样牵动最后一个纸片,就会带出所有的纸片,直到纸片上没有钩子!这个在生活中经常用到,比如我们的笔记本:
2,装饰模式第二版:
这样就用简单工厂封装了装饰者模式客户端分拣的过程,将变化进一步封装,优化了结构,使得变化更加灵活!
代码:
工厂
- <span style="font-size:18px">using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using ExamSystemV3.Web;
- using ExamSystemV3.Model;
- using BLL;
- using ExamSystemV3.Common;
- using System.Globalization;
- using System.Data;
- using System.Collections;
- using System.Web.SessionState;
- namespace ExamSystemV3.Web.web_class
- {
- public class CreatQuestion
- {
- /// <summary>
- /// 显示dataset里试题的页面
- /// </summary>
- /// <param name="ds">存放试题的dataset 要求:ds.DataSetName+"_"+ dt.TableName + "_Record" 能拼出答题记录表例如:ds.DataSetName="T_tongjixue" dt.TableName="xvanzeti" 则拼接出的答题记录表为"T_tongjixue_xvanzeti_Record" </param>
- /// <param name="isExaminghtml">页面中能够盛放试题的div的id</param>
- /// <param name="_FlagChooseQuestion">是否是二次登陆</param>
- /// <param name="_ExamId">考试id</param>
- /// <param name="_StudentId">学号</param>
- /// <returns>返回携带所有问题的QuestionsPage</returns>
- public QuestionsPage StuCreateQuestion(DataSet ds)
- {
- int i,j;
- DataTable dt;
- ArrayList arrAllQuestion=new ArrayList();
- ArrayList arrQuestion=new ArrayList();
- //创建所有的题型page类放到arrAllQuestion
- for (i = 0; i <= ds.Tables.Count - 1; i++)
- {
- dt=ds.Tables[i];
- arrQuestion = DataTableToArrylist(dt);
- strRecordTableName =ds.DataSetName+"_"+ dt.TableName + "_Record";
- qsPageLittle = CreatePage(dt, isExaminghtml, _FlagChooseQuestion, BigQuestionNum, arrQuestion, strRecordTableName, _ExamId, _StudentId);
- BigQuestionNum = BigQuestionNum + 1;
- arrAllQuestion.Add( qsPageLittle );
- }
- //将所有具体的页面封装在一个页面中
- for (j = arrAllQuestion.Count-1; j >= 1; j--)
- {
- qsPageLittle = (QuestionsPage)arrAllQuestion[j - 1];
- ((QuestionsPage)arrAllQuestion[j]).AddQuestionsPage(qsPageLittle);
- }
- //返回封装好的最后一个页面
- qsPageall = (QuestionsPage)arrAllQuestion[arrAllQuestion.Count - 1];
- return qsPageall;
- }
- //创建不同的页面
- private QuestionsPage CreatePage(DataTable dt, System.Web.UI.HtmlControls.HtmlGenericControl isExaminghtml, string _FlagChooseQuestion, int _BigQuestionNum, ArrayList _arrAllQuestion, string _strSingleSelectionRecordTableName, string _ExamId, string _StudentId)
- {
- QuestionsPage ChildQuestionPage;
- switch (dt.TableName)
- {
- //ChoiceQuestionPage
- //选择题
- case "xuanzeti":
- ChildQuestionPage = new ChoiceQuestionPage(isExaminghtml, _FlagChooseQuestion, _BigQuestionNum, _arrAllQuestion, _strSingleSelectionRecordTableName, _ExamId, _StudentId);
- break;
- //MultiSelectQestionPage
- //多选题
- case "duoxuanti":
- ChildQuestionPage = new MultiSelectQestionPage(isExaminghtml, _FlagChooseQuestion, _BigQuestionNum, _arrAllQuestion, _strSingleSelectionRecordTableName, _ExamId, _StudentId);
- break;
- // AnalysisQuestionPage
- //案例分析题
- case "anlifenxiti":
- ChildQuestionPage = new AnalysisQuestionPage(isExaminghtml, _FlagChooseQuestion, _BigQuestionNum, _arrAllQuestion, _strSingleSelectionRecordTableName, _ExamId, _StudentId);
- break;
- //剩下的略
- default:
- ChildQuestionPage=null;
- break;
- }
- return ChildQuestionPage;
- }
- }</span>
大家研究不难发现,其实就是case语句的功劳!
3,装饰模式,简单工厂模式总结:
我们写代码的时候,要充分考虑封装变化,将变化封装到模块中,增加模块内的内聚性,做到变化的改动尽量不重新生成,即使生成也是很小的改动,增加我们系统的灵活性和可靠性!要多思考,多总结!
注:为了照顾篇幅,本人已精简代码,只保留骨干部分,如有需要查看全部代码,请留言,共同交流!
0 0
- 论道——工厂模式与装饰模式的融合
- 论道——工厂模式与装饰模式的融合
- 设计模式-工厂融合
- 设计模式——单例模式、工厂模式、代理模式、观察者模式、装饰器模式
- 扩展系统功能——装饰模式(四):透明与半透明装饰模式,装饰模式注意事项,装饰模式总结
- 设计模式——抽象工厂模式及与工厂模式的区别
- Factory and Decorator (工厂模式与装饰者模式)
- 设计模式——装饰者模式与适配器模式
- 简单工厂模式/策略模式/装饰模式
- 装饰模式+工厂模式+模板模式
- 设计模式——代理模式介绍及与装饰者模式的区别
- 设计模式—装饰模式
- 设计模式—装饰模式
- 设计模式—装饰模式
- 设计模式—装饰模式
- 设计模式—装饰模式
- 代理模式与装饰模式的异同
- 代理模式与装饰模式的区别
- STM32资源
- easyui验证文件格式
- android的context
- LA 4287 Proving Equivalences / 强连通分量
- IBM将斥资12亿美元扩张云服务 建15个数据中心
- 论道——工厂模式与装饰模式的融合
- 《Unity4.x从入门到精通》随书光盘下载
- C# 系统应用之Cookie\Session基础知识及php读取Cookie\Session
- 大数据传统企业实施理性篇---请放慢你的步伐
- Learning to Rank入门小结 + 漫谈
- PCI DSS 3.0:确保云计算合规的三个关键要求
- 软件设计是怎样炼成的(3)——软件系统不是木桶型的
- Android Store Data
- TIMAC 开发随笔 一:CC2530的flash在线读写