能够这么说,不懂设计模式,难以理解面向对象的思想。也能够反过来讲,不理解面向对象的思想,很难理解设计模式。不是吗?数据库
今天我要和你们说一说c#实现模板模式,这是一个很是经常使用,而且简单的模式,在众多的设计模式中,这是我用的最多,并且是天然而然地应用,没有担忧过什么。c#
曾几什么时候,模板模式悄悄地跑到个人代码里面了,也许是我看别人的代码时,不当心学到的。设计模式
有这么一个场景:我须要作“我的成果导出”和“管理后台的成果导出”,两个模块的实现的功能是同样的,都是在页面上展现成果列表,而后能够管理、查询、导出成果。至于具体如何展现,展现哪些数据,也就是具体的操做固然不同了。也有一部分代码是相同的,好比说我要删除一条成果,是否是实现一致呢?只要你给一个id,我操做数据库,便删除了。难道这样的代码,我还须要拷贝两份?有人说,你为何要弄两份呢,你写一个公共的方法,到时候调用便可。这貌似不错的解决办法。不过此解决方法遇到这种状况,怎么办呢?一个方法A的大部分代码都相同,就是有一些地方不一样,这时候,咱们还能提出来,做为公共的方法调用吗?有人说,你傻呀,你把大部分相同的代码提出来,做为公共的地方调用。那这样作,这个A方法,不是仍是拷贝了两份?ide
这种状况下,个人模板方法该是时候出场了,且看代码:工具
解释下代码,我首先定义了一个抽象的控制器,因为首页的显示,不论是后台的,仍是我的导出的,它们都是如此作法:设计
一、判断viewmodel是否为空3d
二、绑定页面下拉列表对象
三、填充viewmodelblog
四、返回视图排序
其中2和3两步,后台和我的导出的实现是不一样的。后台的下拉列表更丰富些,viewmodel展现的字段也多点。因此,咱们把2和3抽象出来,做为抽象方法。到具体运行时,决定到底调用后台导出的,仍是我的导出的方法实现。由于,在编译阶段,咱们也无法肯定它到底调用哪一个方法,由于它是抽象的。
且看管理后台的成果导出实现代码:
下面是我的成果导出的代码实现:
看代码,两个类名都起得同样,很差意思了,这两个类不在一个命名空间下。不过这样会给人形成阅读上的误会。那么有人会说,你上面的代码不是重复的吗?我说,不能看表面的,我是尽最大可能复用。不信,你看下面的代码:
管理后台的成果导出下拉列表绑定:
public override void BindSelect(ExportViewModel viewModel)
{
//学科类型绑定
ViewData["subjectTypes"] = SelectHelp.BindSelect<SubjectType>("学科系统");
//机构排名
ViewData["OrganizationOrders"] = new List<SelectListItem>()
{
new SelectListItem { Text = "本机构排名", Value = "-1"},
new SelectListItem { Text = "1", Value = "1"},
new SelectListItem { Text = ">1", Value = "2"},
new SelectListItem { Text = "2", Value = "3"},
new SelectListItem { Text = "<=2", Value = "4"},
new SelectListItem { Text = ">2", Value = "5"}
};
}
我的成果导出的下拉列表绑定:
public override void BindSelect(ExportViewModel viewModel)
{
//审核状态
ViewData["ReviewStates"] = new List<SelectListItem>()
{
new SelectListItem { Text = "审核状态", Value = "-1"},
new SelectListItem { Text = "待审核", Value = "1" },
new SelectListItem { Text = "审核经过", Value = "2"},
new SelectListItem { Text = "审核未经过", Value = "3"},
//new SelectListItem { Text = "自动审核中", Value = "4"},
new SelectListItem { Text = "撤回", Value = "5"},
new SelectListItem { Text = "禁止", Value = "6"}
};
//署名状况
ViewData["Bylines"] = new List<SelectListItem>()
{
new SelectListItem { Text = "署名状况", Value = "-1"},
new SelectListItem { Text = "第一做者", Value = "1" },
new SelectListItem { Text = "通讯做者", Value = "2"},
new SelectListItem { Text = "通讯做者或者第一做者", Value = "3"}
//new SelectListItem { Text = "非第一和通讯做者", Value = "4"}
};
//排序
ViewData["Orders"] = new List<SelectListItem>()
{
new SelectListItem { Text = "提交日期", Value = "1"},
new SelectListItem { Text = "年度", Value = "0"}
};
}
模板模式,体现了代码复用的思想,也体现了面向对象中的多态。有人说,你定义的抽象方法,子类要实现,这些不都重复吗?我说的是,模板方法还有一个特色,就是咱们的代码主干逻辑很是清晰,易于阅读,也好修改。若是说一味地提取公共方法,而后调用,最后也很差改,公共方法做为”公共服务“”,万一不能知足个别”客户端“,也就是调用端的需求,咱们怎么办呢?此时,抽象类的继承机制,能够解决问题。
固然不能说公共类做为公共服务就很差,就看什么场合了。好比说,我们常常用的工具类,处理字符串的,日期的,数据库操做的。这些工具类是很是有帮助的,也很是好的体现了代码复用原则。好了,模板模式就介绍到这里。