前文用C#代码实现了Facade模式、Adapter模式、Strategy模式、Bridge模式和Abstract Factory模式解决实际业务需求。本文将继续以C#代码为例,实现我在前面介绍的11个模式中剩下的6个模式:Decorator模式、Observer模式、Template Method模式、Singleton模式、Factory Method模式和Prototype模式。按照实现方法的不同,该11个模式可分成三类:创建型模式(Abstract Factory, Singleton, Factory Method, Prototype)、结构型模式(Adapter, Bridge, Decorator)和行为型模式(Strategy, Observer, Template Method)。

.Decorator模式

业务场景:在中国销售的一块手表,基本配置是显示北京时间,但也提供带有高级功能的配置。如:中端配置支持显示当前时区下的日期、高端配置支持第二时区(具体可以用户设置)。采用Decorator模式实现的代码如下:

  1. namespace PartternCase
  2. {
  3. public abstract class AbstractWatch
  4. {//Component in UML
  5. public abstract void StartWork();
  6. }
  7.  
  8. public class Watch : AbstractWatch
  9. {//ConcreteComponent in UML
  10. public override void StartWork()
  11. {
  12. //Show Beijing time
  13. }
  14. }
  15.  
  16. public abstract class WatchDecorator : AbstractWatch
  17. {//Decorator in UML
  18. protected AbstractWatch Watch { get; set; }
  19. protected WatchDecorator(AbstractWatch watch)
  20. {
  21. Watch = watch;
  22. }
  23. }
  24.  
  25. public class ShowDateDecorator : WatchDecorator
  26. {//ConcreteDecoratorA in UML
  27. public ShowDateDecorator(AbstractWatch watch)
  28. : base(watch)
  29. {
  30. }
  31.  
  32. public override void StartWork()
  33. {
  34. Watch.StartWork();
  35. //Show date of current time zone
  36. }
  37. }
  38.  
  39. public class ShowSecTimeZoneDecorator : WatchDecorator
  40. {//ConcreteDecoratorB in UML
  41. public ShowSecTimeZoneDecorator(AbstractWatch watch)
  42. : base(watch)
  43. {
  44. }
  45.  
  46. public override void StartWork()
  47. {
  48. Watch.StartWork();
  49. // Show time of sencond timezone
  50. }
  51. }
  52.  
  53. public class Client
  54. {//How to use decorator pattern
  55. public void ChooseWatch()
  56. {
  57. var watch = new Watch();//Basic function
  58. var middleWatch = new ShowDateDecorator(watch);//Middle: contain show date function
  59. var advanceWatch = new ShowSecTimeZoneDecorator(middleWatch);//Advance: contain show date and second time zone function
  60. }
  61. }
  62. }

.Observer模式

业务场景:盛天公司内部的报销有严格的审批流程,为提高审批效率,当员工提交报销单时,需要向具有审批权限的领导自动发送申请审批的邮件(当然,除报销单外,领导还会收到其他类型的审批邮件)。采用Observer模式实现的代码如下:

  1. namespace PartternCase
  2. {
  3. public abstract class Report
  4. {//Subject in UML
  5. public string Status { get; set; }
  6. protected IList<Employee> Employees { get; set; }
  7. public void Attach(Employee employee)
  8. {
  9. Employees = Employees ?? new List<Employee>();
  10. Employees.Add(employee);
  11. }
  12.  
  13. public void Detach(Employee employee)
  14. {
  15. if (Employees == null) { return; }
  16. Employees.Remove(employee);
  17. }
  18.  
  19. public void Notify(Report report)
  20. {
  21. if (Employees == null) { return; }
  22. foreach (var employee in Employees)
  23. {
  24. employee.HandleReportSubmit(report);
  25. }
  26. }
  27. }
  28.  
  29. public class ExpenseReport : Report
  30. {//ConcreteSubject in UML
  31. public void Submit()
  32. {
  33. Status = "Report Submited";
  34. Notify(this);
  35. }
  36. }
  37.  
  38. public abstract class Employee
  39. {//Observer in UML
  40. public abstract void HandleReportSubmit(Report report);
  41. }
  42.  
  43. public class Boss : Employee
  44. {//ConcreteObserver in UML
  45. public string Status { get; set; }
  46. public override void HandleReportSubmit(Report report)
  47. {
  48. // Send email to this boss by smtp server
  49. Status = report.Status;
  50. }
  51. }
  52.  
  53. public class Client
  54. {//How to use observer pattern
  55. public void Observer()
  56. {
  57. var boss1 = new Boss();
  58. var boss2 = new Boss();
  59. var expense = new ExpenseReport();
  60. expense.Attach(boss1);
  61. expense.Attach(boss2);
  62. expense.Submit();
  63. }
  64. }
  65. }

.Template Method模式

业务场景:圣象饮料公司生产牛奶和矿泉水两种饮料。运营过程都分为生产和销售两个环节,但两种饮料的生产和销售方式不相同。如销售方式:牛奶每天通过送货员送货上门,矿泉水通过各大超市销售。采用Template Method模式实现的代码如下:

  1. namespace PartternCase
  2. {
  3. public abstract class DrinkOperation
  4. {//AbstractClass in UML
  5. public void Perform()
  6. {//Interface for client call
  7. Product();
  8. Sales();
  9. }
  10.  
  11. protected abstract void Product();
  12. protected abstract void Sales();
  13. }
  14.  
  15. public class MilkOperation : DrinkOperation
  16. {//ConcreteClass in UML
  17. protected override void Product()
  18. {
  19. //Get raw material from milk station then process
  20. }
  21.  
  22. protected override void Sales()
  23. {
  24. //Sell by deliveryman
  25. }
  26. }
  27.  
  28. public class WaterOperation : DrinkOperation
  29. {//ConcreteClass in UML
  30. protected override void Product()
  31. {
  32. //Get raw material from mountain then process
  33. }
  34.  
  35. protected override void Sales()
  36. {
  37. //Sell by supermarket
  38. }
  39. }
  40. }

. Singleton模式

业务场景:投资组合管理系统中经常会用到一些复杂的模型对投资组合的价值进行估值。这些计算模型往往都放在一个类中,互相之间没有依赖关系。采用Singleton模式实现的代码如下:

  1. namespace PartternCase
  2. {
  3. public class CalculationEngine
  4. {//Singleton in UML
  5. protected CalculationEngine() { }
  6.  
  7. private static readonly CalculationEngine instance = new CalculationEngine();
  8. public static CalculationEngine GetInstance { get { return instance; } }// Interface for client call
  9.  
  10. //Many calculation methods
  11. }
  12. }

. Factory Method模式

业务场景:圣天基金公司旗下的基金在向合伙人提款时,需根据合伙人类型不同(普通合伙人:GP、有限合伙人:LP)将提款数据存放在相应的合伙人类型中,然后保存。采用Factory Method模式实现的代码如下:

  1. namespace PartternCase
  2. {
  3. public abstract class CapitalCall
  4. {//Creator in UML
  5. public abstract Partner BuildPartner();
  6.  
  7. public void Perform()
  8. {
  9. var partner = BuildPartner();
  10. //Calculate amount of partner then save partner
  11. }
  12. }
  13.  
  14. public class GpCapitalCall : CapitalCall
  15. {//ConcreteCreator in UML
  16. public override Partner BuildPartner()
  17. {
  18. return new GP();
  19. }
  20. }
  21.  
  22. public class Partner
  23. {//Product in UML
  24. public decimal Amount { get; set; }
  25. }
  26.  
  27. public class GP : Partner
  28. {//ConcreteProduct in UML
  29. }
  30. }

. Prototype模式

业务场景:圣象饮料公司在查询牛奶和矿泉水的季度销量时,会分别针对Milk和Water数据库表进行查询,查询条件除时间外从外部传入,内部只设置时间条件,但不能改变传入的查询条件。下面将采用Prototype模式实现该业务场景:

  1. namespace PartternCase
  2. {
  3. public abstract class DrinkCriteria
  4. {//Prototype in UML
  5. public abstract string QueryTable { get; }
  6. public DateTime StartDate { get; set; }
  7. public DateTime EndDate { get; set; }
  8. //Other query fields
  9.  
  10. public abstract DrinkCriteria Clone();
  11. }
  12.  
  13. public class MilkCriteria : DrinkCriteria
  14. {//Concrete Prototype1 in UML
  15. public override string QueryTable { get { return "Milk"; } }
  16.  
  17. public override DrinkCriteria Clone()
  18. {//This is shallow copy, in other case maybe need deep copy.
  19. return MemberwiseClone() as MilkCriteria;
  20. }
  21. }
  22.  
  23. public class WaterCriteria : DrinkCriteria
  24. {//Concrete Prototype2 in UML
  25. public override string QueryTable { get { return "Water"; } }
  26.  
  27. public override DrinkCriteria Clone()
  28. {
  29. return MemberwiseClone() as WaterCriteria;
  30. }
  31. }
  32.  
  33. public class Client
  34. {//Client in UML
  35. //Set relative criteria at runtime
  36. private DrinkCriteria Criteria { get; set; }
  37. public void HowToUse()
  38. {
  39. var newCritera = Criteria.Clone();
  40. //newCritera.StartDate = 2013-1-1;
  41. //newCritera.EndDate = 2013-3-31;
  42. //Start to query user new criteria
  43. }
  44. }
  45. }
【版权所有,转载请注明文章出处:Maxwell Zhou
 

SharePoint

 
摘要: 小菜Tip1: list创建和当前用户相关的view 此时,[me] = current user ...阅读全文
posted @ 2012-03-22 14:41 Q_L_H 阅读(72) | 评论 (0) 编辑
 
摘要: 一: 前言 上一回中,小菜学会CQWP的使用. 但是小菜深感对SharePoint整个系统体系的不熟悉而带来的事倍功半. 大师: 小菜, 又有新任务了. 你使用Event Handler 对用户上传文件和修改文件做下权限判断. 小菜: …… 二: Event Handler 1 目标 使用Event Handler 判断用户是否有权限上传和修改文件. 特定用户指定修改自己上传的文件. 2 过程 小菜昨天刚被上一回的CQWP折腾的死去活来, 又来个新的任务, 小菜有点感觉力不从心, 但是小菜有个自认为很伟大的方法, 就是默念”我行...阅读全文
posted @ 2012-03-18 15:11 Q_L_H 阅读(64) | 评论 (0) 编辑
 
摘要: 一: 前言 上一回中,小菜学会了修改和部署一个WebPart. 大师: 小菜,有几个很常用的WebPart你需要熟悉下. 先用那个Content Query Web Part做一个图片滚动的任务.示例已经发你了. 小菜: 得令. 二: Content Query Web Part的使用 1 目标 使用CQWP实现一个图片走马灯的效果.(这个玩意...阅读全文
posted @ 2012-03-18 11:59 Q_L_H 阅读(67) | 评论 (3) 编辑
 
摘要: 一: 前言 接上文,小菜完成了WebPart的修改,不知道如何将更改部署到服务器中.祭出万能的Google利器,小菜很快找到了部署方法. 二: 部署WebPart! 1 目标 将WebPart部署到服务器端.(小菜当然只能部署到测试服务器,客户的服务器是小菜够不着的.) ...阅读全文
posted @ 2012-03-18 09:15 Q_L_H 阅读(89) | 评论 (0) 编辑
 
摘要: 一: 前言 先来点背景介绍吧, 小菜从事.Net 相关的开发工作2年, 算是跨过了新手的那道门槛. 某日, 小菜手上的项目接近收尾, 没啥明确的任务便在电脑前打打酱油. 这时候, 大师突然过来找小菜. 大师: 小菜啊, 现在有个SharePoint项目, 你先练练手吧, 具体的任务我都已经给你列好了. 小菜: 好的. 小菜从来也没有接触过SharePoint, 心里一阵嘀咕, 为什么让我做这个啊? 但是大师的...阅读全文
posted @ 2012-03-16 20:08 Q_L_H 阅读(59) | 评论 (0) 编辑

小菜的SharePoint Tips的更多相关文章

  1. Office 365 - SharePoint Tips & Tricks

    1. Recycle Bin 地址: //管理员 /_layouts/15/AdminRecycleBin.aspx //普通用户 /_layouts/15/RecycleBin.aspx 2.

  2. 【转】必需知道的 SharePoint 权限 Tips

    SharePoint Tips about Permissions: What you need to know         I have been writing tips about Shar ...

  3. SharePoint “File not found” 错误

    Troubleshooting the SharePoint "File not found" Error Have you ever come across a "Fi ...

  4. 修改SharePoint 2013中Search Topology时遇到的一些问题以及一些Tips

    这次操作在笔者的场中涉及到5台服务器, CA, APP2, APP3, APP4, APP5. 原本只有CA运行着Search Service Applicaiton, 现在想让APP2-5运行这项服 ...

  5. SharePoint 2010自定义母版页小技巧——JavaScript和CSS引用

    通常在我们的项目中,都会涉及到母版页的定制.并且必不可少的,需要配合以一套自己的JavaScript框架和CSS样式.你有没有遇到过这样的情况呢,在开发环境和UAT时都还算顺利,但是当最终部署到生产服 ...

  6. SharePoint配置搜索服务和指定搜索范围

    转载:http://constforce.blog.163.com/blog/static/163881235201201211843334/ 一.配置SharePoint Foundation搜索 ...

  7. How to Get SharePoint Client Context in SharePoint Apps (Provider Hosted / SharePoint Access ) in CSOM (Client Side Object Model)

    http://www.codeproject.com/Articles/581060/HowplustoplusGetplusSharePointplusClientplusContex Downlo ...

  8. Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010

    from:http://blog.tallan.com/2012/07/18/creating-a-sharepoint-bcs-net-assembly-connector-to-crawl-rss ...

  9. SharePoint 开发小结

    目标:将sharepoint网站对接Office 365 最直接的API:How to: Add Office 365 APIs to a Visual Studio project http://m ...

随机推荐

  1. mysql_常用命令

    1: 以指定编码创建数据库 CREATE DATABASE `search_data` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

  2. java学习笔记2——Eclipse的安装及汉化图解

    Eclipse的安装 有了JDK,你可以编译Java源码,运行Java程序,但是还没有代码编辑器,没有版本管理工具,也不能方便的管理工程文件,不能与团队协作.安装Eclipse,你才能完成这些工作. ...

  3. Hadoop2.2.0--Hadoop Federation、Automatic HA、Yarn完全分布式集群结构

    Hadoop有很多的上场时间,与系统上线.手头的事情略少.So,抓紧时间去通过一遍Hadoop2在下面Hadoop联盟(Federation).Hadoop2可用性(HA)及Yarn的全然分布式配置. ...

  4. 使用JFinal框架中Validator

    Validator是JFinal框架中的校验组件,在Validator类中提供了我们经常使用的校验方法,而Validator本身实现了Interceptor接口,所以Validator也相当于一个拦截 ...

  5. 基于Cocos2dx + box2d 愤怒的小鸟的实现Demo

    1. Demo初始界面 2. 游戏界面 3. 精确碰撞检測 4. 下载  压缩文件文件夹 AngryBird source    愤慨的小鸟Demo源码,基于Cocos2dx C++,以及box2d技 ...

  6. 异常处理 Access to the path is denied

    在需要进行读写操作的目录下添加Network Service这个帐号, 由于在iis 6.0中,默认的应用程序池中的标示用的是Network Service, 所以在进程中是使用Network Ser ...

  7. NET 2015

    .NET 2015 英文原文:Understanding .NET 2015 Understanding 翻译为了解或理解,对于 .NET 来说,2015 年注定会更加精彩,所以标题就用了“精彩”这个 ...

  8. animation渐进实现点点点等待效果实例页面

    CSS代码: .ani_dot { font-family: simsun; } :root .ani_dot { display: inline-block; width: 1.5em; verti ...

  9. 第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例(原创)

    天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...

  10. php生成签名及验证签名

    <?php /** * 根据原文生成签名内容 * * @param string $data 原文内容 * * @return string * @author confu */ functio ...