C#项目中常用到的设计模式

C#项目中常用到的设计模式

1. 引言

一个项目的通常都是从Demo开始,不断为项目添加新的功能以及重构,也许刚开始的时候代码显得非常凌乱,毫无设计可言。但是随着项目的迭代,往往需要将很多相同功能的代码抽取出来,这也是设计模式的开始。熟练运用设计模式应该是每一个软件开发人员的必备技能。今天给大家介绍几个常用的设计模式。

 

2. 单例模式

单例模式恐怕是很多开发人员最先接触到的模式之一,可以认为就是一个全局变量。它的初始化过程无非就是一开始就new 一个instance,或者惰性初始化等需要用到的时候new 一个instance。这里需要注意的是在多线程情况下new一个instance。通常加上lock 可以解决问题。这里我们利用C# 的系统函数 Interlocked.CompareExchange

    internal class SingletonOne{private static SingletonOne _singleton;private SingletonOne(){}public static SingletonOne Instance{get{if (_singleton == null){Interlocked.CompareExchange(ref _singleton, new SingletonOne(), null);}return _singleton;}}}

 

3. 迭代器模式

迭代器模式也是用的比较多的一种,通常见于C#的内置容器数据结构 List,Stack等等,为了便于遍历容器内元素。这里给出一个简单版的Stack实现

    internal class Stack<T> : IEnumerable<T>, IEnumerable{private T[] _array;private int _index;private const int DefaultSize = 4;public Stack(int size){var sized = size > 0 ? size : DefaultSize;this._array = new T[sized];this._index = 0;}public int Count{get { return this._index; }}public Stack(IEnumerable<T> data) : this(0){var enumrator = data.GetEnumerator();while (enumrator.MoveNext()){var item = enumrator.Current;this.Push(item);}}public void Push(T item){if (this._index < this._array.Length){this._array[this._index++] = item;}else{var newLength = this._array.Length << 1;T[] newArray = new T[newLength];Array.Copy(this._array, newArray, this.Count);this._array = newArray;this.Push(item);}}public T Pop(){if (this.Count <= 0){throw new ArgumentOutOfRangeException("pop");}else{this._array[this._index] = default(T);return this._array[--this._index];}}public T Get(int index){if (this.Count <= index){throw new ArgumentOutOfRangeException("Get");}else{return this._array[index];}}IEnumerator IEnumerable.GetEnumerator(){return this.GetEnumerator();}public IEnumerator<T> GetEnumerator(){return new StackEnumerator<T>(this);}}

Stack 的 迭代器内部实现:

    internal class StackEnumerator<T> : IEnumerator<T> , IEnumerator{private Stack<T> _stack;private int _index;public StackEnumerator(Stack<T> stack){this._stack = stack;this._index = -1;}public bool MoveNext(){this._index++;return this._index < this._stack.Count;}public void Reset(){this._index = -1;}object  IEnumerator.Current {get { return this.Current; } }public T Current{get { return this._stack.Get(this._index); }}public void Dispose(){this._stack = null;}}

 

4 工厂模式

工厂模式细分的话有简单工厂模式、抽象工厂模式等。它最核心的就是如何通过 Factory new 一个 对象出来。在ASP.NET MVC 消息处理实现过程中工厂模式运用的非常多。比如

在MVC中处理一个Request,其实就是调用Controller下的一个Action,这就需要从Url 和Route 中反射出Controller对象,内部由ControllerFactory创建。

image

它的默认实现是:DefaultControllerFactory

image

另一个例子是ValueProviderFactory,它使得Controller 下的Action 能够接收到前端传回来的数据并实现模型绑定,是典型的抽象工厂实现。

image

 

5. 订阅模式

订阅模式在某些项目运用比较多,比如 Knockout 整个项目就是一个大的订阅模式的实现,但是它是用javascript编写的。还有像微博、微信公众号等等订阅模式通常少不了。

通常可以定义接口:

    internal interface ISubject{IEnumerable<IObserver> Observers { get; } void Notify();void AddObserver(IObserver observer);void RemoveObserver(IObserver observer);}internal interface IObserver{void ReceiveSubject(ISubject subject);}

实现:

    internal class AritcleObserver : IObserver{public void ReceiveSubject(ISubject subject){// receive the subject
        }}class WeChatArticle : ISubject{private ICollection<IObserver> _observers;private string _name;public WeChatArticle(string name){this._name = name;this._observers = new List<IObserver>();}public IEnumerable<IObserver> Observers{get { return this._observers; }}public void Notify(){foreach (IObserver observer in this._observers){observer.ReceiveSubject(this);}}public void AddObserver(IObserver observer){this._observers.Add(observer);}public void RemoveObserver(IObserver observer){this._observers.Remove(observer);}}

 

6.  责任链模式

责任链模式没有像工厂模式那样被人熟悉,在ASP.NET WebApi 中有一个非常典型的实现 就是WebApi的消息处理管道HttpMessageHandler

image

这里给一个简单的模拟

    class DataRequest{public string FileName { get; set; }}class DataResponse{public string Error { get; set; }public string Data { get; set; }}internal abstract class RequestHandler{public RequestHandler NextHandler { get; set; }public abstract DataResponse Process(DataRequest request);}class ReadRequestHandler : RequestHandler{public override DataResponse Process(DataRequest request){return new DataResponse(){Data = File.ReadAllText(request.FileName)};}}class ExistsRequestHandler : RequestHandler{public override DataResponse Process(DataRequest request){if (File.Exists(request.FileName)){return this.NextHandler.Process(request);}else{return new DataResponse(){Error = "no exists"};}}}

 

7. 组合模式

组合模式是使得单个对象和组合对象有一致的行为,一致的行为可以理解为拥有同一个接口,比如图形显示

    class ControlContext{}internal interface IControl{void Draw(ControlContext context);}class Line : IControl{public void Draw(ControlContext context){}}class Circle : IControl{public void Draw(ControlContext context){}}class CompositeControl : IControl{private List<IControl> controls;public CompositeControl(IList<IControl> cons){this.controls = new List<IControl>(cons);}public void Draw(ControlContext context){this.controls.ForEach(c => c.Draw(context));}public void Add(IControl control){this.controls.Add(control);}}

 

8. 总结

市场上有很多关于设计模式的书,但是基本的设计模式大概有20多种,本文给大家介绍了几种项目中常见的设计模式,其实有些设计模式在实际项目已经不知不觉用起来了。

以后再给大家介绍其他的几种设计模式。

 

欢迎访问我的个人主页 51zhang.net  网站还在不断开发中…..

posted on 2016-06-02 21:06 禅宗花园...迷失的佛 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/VectorZhang/p/5554388.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式数据库 HBase

原文地址&#xff1a;http://www.oschina.net/p/hbase/ HBase 概念 HBase – Hadoop Database&#xff0c;是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统&#xff0c;利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。 HBase是Google Bigtable的开源实…

学习笔记(15):Python网络编程并发编程-进程理论

立即学习:https://edu.csdn.net/course/play/24458/296423?utm_sourceblogtoedu 1.进程&#xff1a;正在运行的一个过程或者一个任务&#xff1b; 2.进程与程序的区别&#xff1a;程序是一堆代码&#xff0c;程序运行起来就是进程了&#xff0c;一个程序运行两次&#xff0c;算…

【翻译】Designing Websites for iPhone X

让网站适配 iphone X 英文原文地址&#xff1a;https://webkit.org/blog/7929/...本文原文地址&#xff1a;https://github.com/cnsnake11/... The section below about safe area insets was updated on Oct 31, 2017 to reflect changes in the iOS 11.2 beta. 以下关于safe …

使用 Log4Net 记录日志

第一步&#xff1a;下载Log4Net 下载地址&#xff1a;http://logging.apache.org/log4net/download_log4net.cgi 把下载的 log4net-1.2.11-bin-newkey解压后&#xff0c;如下图所示&#xff1a; 双击bin文件夹 双击net文件夹&#xff0c;选择针对.NET FramerWork的不同版本 找…

HDU 1757 A Simple Math Problem (矩阵快速幂)

题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1757 在吴神的帮助下才明白如何构造矩阵&#xff0c;还是好弱啊。 此处盗一张图 1 #include <iostream>2 #include <cstdio>3 #include <cstring>4 #include <cmath>5 #include <al…

用弦截法求一元三次方程的根x^3-5x^2+16x-80=0 ;带注释!

//用弦截法求一元三次方程的根x^3-5x^216x-800 #include<stdio.h>#include<math.h> float f(float x) //定义子函数f(x) x^3-5x^216x-80&#xff0c;当f(x) →0时&#xff0c;则x即为所求的实数根&#xff1b; { float y; y((x-5.0)*x16.0)*x-80.0; …

化零为整WCF(14) - 事务(Transaction)

[索引页][源码下载] 化零为整WCF(14) - 事务(Transaction)作者&#xff1a;webabcd介绍WCF(Windows Communication Foundation) - 事务(Transaction)&#xff1a; 对契约方法使用TransactionFlowAttribute声明&#xff08;设置TransactionFlowOption参数&#xff09;&#x…

iOS开发网络篇—NSURLConnection基本使用

iOS开发网络篇—NSURLConnection基本使用 一、NSURLConnection的常用类 &#xff08;1&#xff09;NSURL&#xff1a;请求地址 &#xff08;2&#xff09;NSURLRequest&#xff1a;封装一个请求&#xff0c;保存发给服务器的全部数据&#xff0c;包括一个NSURL对象&#xff0c;…

使用HTML5+CSS3制作圆角内发光按钮----示例

<!doctype html> <html> <head> <meta charset"utf-8" /> <title>制作漂亮的圆角按钮<title> <style type"text/css"> .loginBtnDiv { float:right; padding-right:50px; padding-top:10px; } .loginBtn, .Resg…

ccBPM典型的树形表单和多表头表单的流程示例

ccBPM典型的树形表单和多表头表单的流程 关键字&#xff1a;树形表单。ccBPM支持树形表单&#xff0c;也可以称之为树结构的多表单或者多表头表单。 应用场景&#xff1a;比如项目招标类流程&#xff0c;在填写项目申请的环节&#xff0c;需要填写公司简介、公司业绩、项目实施…

H5+JS实现《Just Do 8》游戏源码分享

【界面效果图】 【代码结构】 【代码结构解释】 1、使用html语言实现数据 2、使用css3语言实现样式 3、使用JS语言实现路基控制 【注意是想】 1、如需查看效果&#xff0c;请使用手机浏览器&#xff0c;或者使用appcan打包查看 2、如果使用浏览器&#xff0c;请选择google的Chr…

python数据结构_大O符号_学习笔记(1)

1.概念 &#xff1a;大O符号是用来表达一个算法的复杂程度的&#xff0c;是一个数量级 2.代码 a 1 b 2 c 3 for i in range(n):for j in range(n):x i*iy j*jz i*jfor k in range(n):m a*k 5v k*kd 100*c e c*d3.分析 在上述代码中&#xff0c;分配操作数分为四…

.NET简谈组件程序设计之(上下文与同步域)

我们继续学习.NET多线程技术&#xff0c;这篇文章的内容可能有点复杂。在打破常理之后&#xff0c;换一种新的思考模型最为头疼。这篇文章里面会涉及到一些不太常见的概念&#xff0c;比如&#xff1a;上下文、同步域等等。我也是最近才接触这些关于组件编程方面的高深技术&…

调用图片按钮的img图片

今天是我学前端的第12天。早上起床后活动筋骨时看了《JS的基本属性操作》&#xff0c;作业是模拟手机发送短信。文字都能传输到<div>上&#xff0c;就是图片不知道怎么传。折腾了好久才弄清楚&#xff0c;多亏了某群的小伙伴们。 这一节课&#xff0c;我学会了如何调用图…

python数据结构_(列表)大O性能_学习笔记(2)

1.列表 1&#xff09;一般列表操作命令的复杂度&#xff08;准确来说是函数的复杂度&#xff09; 2&#xff09;时间计算&#xff08;timeit模块和Timer对象&#xff09; 要捕获我们的每个函数执行所需的时间&#xff0c;我们将使用 Python 的 timeit 模块。timeit 模块旨在 …

找到你的位置(JS在页面中的位置)最常用的方式是在页面中head部分放置script元素,浏览器解析head部分就会执行这个代码,然后才解析页面的其余部分...

找到你的位置&#xff08;JS在页面中的位置&#xff09; 我们可以将JavaScript代码放在html文件中任何位置&#xff0c;但是我们一般放在网页的head或者body部分。放在<head>部分 最常用的方式是在页面中head部分放置<script>元素&#xff0c;浏览器解析head部分就…

3.cocos2dx它Menu,由menu为了实现场景切换

&#xfeff;&#xfeff;1 头文件 TMenu.h #ifndef __TMENU_H__ #define __TMENU_H__ #include "cocos2d.h" USING_NS_CC; class TMenu :public CCLayer { public: static CCScene * scene(); CREATE_FUNC(TMenu); bool init(); CCMenu * menu; void menuCallback(C…

人工智能数学基础知识

方差的概念与计算公式&#xff0c;例1 两人的5次测验成绩如下&#xff1a;X&#xff1a; 50&#xff0c;100&#xff0c;100&#xff0c;60&#xff0c;50 E(X)72&#xff1b;Y&#xff1a; 73&#xff0c; 70&#xff0c; 75&#xff0c;72&#xff0c;70 E(Y)72。平均成绩相同…

认真分析mmap:是什么 为什么 怎么用

mmap基础概念 mmap是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff0c;进程就可以采用指针的方式读写操作这一段内存&#xff…