前言:毫无疑问 ,学习一些设计模式,对我们的编程水平的提高帮助很大。写这个博客的时候自己刚开始学习设计模式,难免有错,欢迎评论指正。

我学设计模式的第一本书是“大话设计模式”。

1.为什么要学设计模式?

设计模式的存在就是为了抵御需求变更。学会了这些思想,开始一个项目的时候考虑的更多,当用户提出变更的时候项目改动更少。

2.怎么才能学会设计模式?

我不知道,不过轮子哥(vczh)文章中的一句话,我觉得对,就是:“设计模式就是因为情况复杂了所以才会出现的,所以我们只能通过复杂的程序来学习设计模式。你不管看别人的程序也好,自己写程序练习也好,那必须要复杂,复杂到你不用设计模式就做不下去,这才能起到学习设计模式的作用”。所以,我准备选择一些自己用到的设计模式,通过写代码的方式去熟悉它们。

一.简单工厂模式(Simple Factory Pattern)

场景描述:制作一个计算器。

1.实现加减乘除。

2.以后有其它算法的时候,容易维护。

工厂类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Author:cuishiyu
//2016.08.13
namespace OperationByFactory.Class
{
//运算工厂类
class OperationFactory
{
public static Operation createOperation(string operate)
{
Operation oper = null;
switch (operate)
{
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
}

运算类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Author:cuishiyu
//2016.08.13
namespace OperationByFactory.Class
{
//运算类
class Operation
{
private double _numberA = ;
private double _numberB = ; public double NumberA
{
get
{
return _numberA;
} set
{
_numberA = value;
}
} public double NumberB
{
get
{
return _numberB;
} set
{
_numberB = value;
}
} public virtual double GetResult()
{
double result = ;
return result;
}
}
}

加减乘除类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Author:cuishiyu
//2016.08.13
namespace OperationByFactory.Class
{
//加法类
class OperationAdd:Operation
{
public override double GetResult()
{
return NumberA + NumberB;
}
}
}
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Author:cuishiyu
//2016.08.13
namespace OperationByFactory.Class
{
//减法类
class OperationSub:Operation
{
public override double GetResult()
{
return NumberA - NumberB;
}
}
}
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Author:cuishiyu
//2016.08.13
namespace OperationByFactory.Class
{
//乘法类
class OperationMul:Operation
{
public override double GetResult()
{
return NumberA * NumberB;
}
}
}
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//Author:cuishiyu
//2016.08.13
namespace OperationByFactory.Class
{
//除法类
class OperationDiv:Operation
{
public override double GetResult()
{
if(NumberB== )
throw new Exception("除数不能为0");
return NumberA / NumberB;
}
}
}

总结:简单工厂模式很简单,重要的是。这个设计模式是怎么一步步形成的、和这样做的好处有哪些。

1.可移植性号,无论是控制台程序,Windows程序,Web程序,都可以用这段代码。

2.扩展性好,更安全,以后增加平方,立方,开根号等运算的时候,增加一个相应的类,然后再Switch里增加分支就好了。同时也不用担心程序员修改原先写好的加减乘除类,使得原先的代码不会被有意或者无意的修改,所以更安全。

3.(1)编程尽可能避免重复的代码。(2)对业务进行封装,尽可能的让业务逻辑和页面逻辑分开,让它们的耦合度下降,这样更容易维护和扩展。

4.大家可以熟悉一下UML类图,画出来之后理解更直观。

二.策略模式(strategy Pattern

场景描述:商场的收银软件,收银员根据客户所购买的商品单价和数量进行收费。

1.要考虑到打折的情况(比如过节打8折)。

2.要考虑满A返B的情况(比如满300返100)。

3.考虑以后发生其它情况是,尽量做到代码容易更改,安全的更改。

注:部分代码是伪代码

抽象策略类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace PromotionByStrategy
{
//抽象策略类
abstract class CashSuper
{
public abstract double acceptCatch(double money);
}
}

返利收费子类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace PromotionByStrategy
{
//返利收费子类
class CashReturn : CashSuper
{
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(string moneyCondition, string moneyReturn)
{
this.moneyCondition = double.Parse(moneyCondition);
this.moneyReturn = double.Parse(moneyReturn);
}
public override double acceptCatch(double money)
{
double result = money;
if (money >= moneyCondition)
{
result = money - Math.Floor(money / moneyCondition) * moneyReturn;
}
return result;
}
}
}

打折收费子类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace PromotionByStrategy
{
//打折收费子类
class CashRebate : CashSuper
{
private double moneyRebate = 1d; //构造函数传入打折信息
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
} public override double acceptCatch(double money)
{
return money * moneyRebate;
}
}
}

正常收费子类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace PromotionByStrategy
{
//正常收费子类
class CashNormal : CashSuper
{
public override double acceptCatch(double money)
{
return money;
}
}
}

策略和简单工厂的结合

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace PromotionByStrategy
{
//策略和简单工厂的结合
class CashContext
{
//收钱的父类
CashSuper cs = null; /// <summary>
/// 构造函数初始化收费类型对象
/// </summary>
/// <param name="type"></param>
public CashContext(string type)//传入一个收费的类型
{
switch (type)//根据不同的类型实例化不同的收款算法对象
{
case"正常收费":
cs = new CashNormal();
break;
case "满A减B":
cs = new CashReturn("A", "B");
break;
case "打X折":
cs = new CashRebate("0.X");
break;
}
} public double GetResult(double money)
{
return cs.acceptCatch(money);
}
}
}

客户端的主要程序

  double tatal = 0.0d;
//客户端的主要程序
//传入算法,和价格*数量,得到应收的钱
public void btnOK_Click()
{
CashContext csuper = new CashContext("传入收款的算法");
double totalPrices = 0.0d;
totalPrices = csuper.GetResult(Convert.ToDouble("价格*数量"));
}

总结:在分析一个项目中,遇到不同的时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。这个代码还可以优化,后面会用反射进行优化

三.单一职责原则(SRP)

注:三、四、五主要分享设计模式中用到的一些原则

就一个类而言,因该仅有一个引起它变化的原因。一个类只行使一个功能,后面维护的时候会方便许多。

四.开放-封闭原则(The Open-Closeed Principle)

对软件实体来说(类、模块。函数)都要求满足:

两大特征:对扩张是开放的(Open for extension),对更改是封闭的(Closed for modification)。

在具体的实现过程中,可按照下面做:

1.我们在最初编码的时候,假设变化不会发生。当发生变化的时候,我们就创建抽象来隔离以后发生的同类变化。

2.当面对需求的时候,对程序的改动,是通过增加代码而不是修改现有的代码实现。

3.拒绝不成熟的抽象,和抽象本身同样重要。

五.依赖倒转原则

1.依赖倒转原则:抽象不应该依赖细节,细节应该依赖抽象。

简单解释就是,针对接口编程而不是针对实现编程。

A.高模块不应该依赖低层模块。两个都应该依赖抽象。

B.抽象不应该依赖细节,细节应该依赖抽象。

2.里氏代换原则:子类型必须能够替换掉他们的父类型。

简单解释就是,一个软件实体如果使用的是一个父类的话,那么一定使用于其子类,而且它察觉不出父类对象和子类对象的区别。

也就是说,在软件里面,把父类都替换成它的子类,程序行为没有变化。

 六.装饰模式

场景描述:写一个给人搭配不同服饰的系统,类似QQ秀,或者游戏皮肤之类的。

Person类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DressByDecorator
{
//Person类
class Person
{
public Person()
{ } private string name; public Person(string name)
{
this.name = name;
} public virtual void Show()
{
Console.WriteLine("装扮的{0}",name);
}
}
}

服饰类,继承Person类

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DressByDecorator
{
//服饰类
class Finery : Person
{
protected Person componnet; //打扮
public void Decorate(Person component)
{
this.componnet = component;
} public override void Show()
{
if (componnet != null)
{
componnet.Show();
}
}
}
}

具体的服饰类,下面举两个例子。

鞋子类,继承服饰类。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DressByDecorator
{
//鞋子类
class Shose:Finery
{
public override void Show()
{
Console.WriteLine("鞋子");
base.Show();
}
}
}

T恤类,继承服饰类。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DressByDecorator
{
//T恤类
class TShirts:Finery
{
public override void Show()
{
Console.WriteLine("T恤");
base.Show();
}
}
}

下面是main函数里的实现

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DressByDecorator
{
//Person类
class Person
{
public Person()
{ } private string name; public Person(string name)
{
this.name = name;
} public virtual void Show()
{
Console.WriteLine("装扮的{0}",name);
}
}
}

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

总结:这个例子中,每一个类都形式自己的功能。他们公有的功能都写在了父类。可以实现动态的添加更多的衣服。

设计模式("大话设计模式"读书笔记 C#实现)的更多相关文章

  1. 《Android源代码设计模式解析》读书笔记——Android中你应该知道的设计模式

    断断续续的,<Android源代码设计模式解析>也看了一遍.书中提到了非常多的设计模式.可是有部分在开发中见到的几率非常小,所以掌握不了也没有太大影响. 我认为这本书的最大价值有两点,一个 ...

  2. java 的常用设计模式--大话设计模式

    设计模式:一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把 ...

  3. <大话设计模式>笔记

    读完了<大话设计模式>这本书,收获很多,对程序设计有了很多新的理解.将每章模式的大概要点做了些笔记以备查阅,一些设计模式书读完也对其了解得不是很透彻,需要以后在实践中来不断地加深理解吧.读 ...

  4. HeadFirst设计模式读书笔记--目录

    HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern) HeadFirst设计模式读书笔记(2)-观察者模式(Observer Pattern) HeadFirst设计 ...

  5. 《Head First 设计模式》读书笔记(1) - 策略模式

    <Head First 设计模式>(点击查看详情) 1.写在前面的话 之前在列书单的时候,看网友对于设计模式的推荐里说,设计模式的书类别都大同小异,于是自己就选择了Head First系列 ...

  6. 《松本行弘的程序世界》读书笔记(上)——面向对象、程序块、设计模式、ajax

    1. 前言 半个月之前买了这本书,还是经园子里的一位网友推荐的.到现在看了一半多,基础的都看完了,剩下的几章可做高级部分来看.这本书看到现在,可以说感触很深,必须做一次读书笔记! 关于这本书,不了解的 ...

  7. 《Head First 设计模式》读书笔记

    目录 <Head First 设计模式>读书笔记 创建模式 结构模式 行为模式 用思维导图记录的读书笔记. <Head First 设计模式>读书笔记 模式的分类遵循<设 ...

  8. 0.UML图入门——学习《大话设计模式》笔记

    <大话设计模式>中讲述了UML类图的基本用法,做此笔记加深理解. 注:上图来源于<大话设计模式> 上图中设计的关键术语为:继承.实现.聚合.组合.关联.依赖. 要想弄清楚UML ...

  9. JavaScript设计模式:读书笔记(未完)

    该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...

随机推荐

  1. Ubuntu 16.04安装unrar解压RAR文件

    除了7zip:http://www.cnblogs.com/EasonJim/p/7124306.html之外,还可以安装unrar进行解压RAR文件. 安装 sudo apt-get install ...

  2. Ubuntu 16.04安装JMeter测试工具

    JMeter是Java的测试工具,由Apache开发. 同样,JMeter是跨平台的. 下载: http://jmeter.apache.org/download_jmeter.cgi 安装: 7z ...

  3. JSP的文件上传

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/file-uploading.html: 一个JSP可以用一个HTML表单标签,它允许用户上传文件到服务器 ...

  4. Servlet中操作数据库

    以下内容引用自http://wiki.jikexueyuan.com/project/servlet/database-access.html: 前提先新建数据库及插入模拟数据: create tab ...

  5. 【SQL Server 学习系列】-- 随机生成日期时间的SQL脚本

    DECLARE @dt1 DATETIME,@dt2 DATETIME,@a BIGINT,@b BIGINT SET @dt1='2010-01-01'--开始日期 SET @dt2='2010-0 ...

  6. windows 7 忘記密碼,用“带命令行的安全模式”

    net user administrator /active:yes net user tester /add net localgroup administrators tester /add

  7. 获取路由事件的源Source和OriginalSource

    路由事件的消息包括在RoutedEventArgs实例中,该实例有两个属性Source和OriginalSource,都是表示路由事件传递的起点.即事件消息的源头.仅仅只是Source表示的是Logi ...

  8. Java中Comparator接口和Comparable接口的使用

    普通情况下在实现对对象元素的数组或集合进行排序的时候会用到Comparator和Comparable接口,通过在元素所在的类中实现这两个接口中的一个.然后对数组或集合调用Arrays.sort或者Co ...

  9. 常用Lunix命令

    计算机 1.硬件系统 输入单元.输出单元.算术逻辑单元.控制单元.记忆单元 中央处理单元:CPU(算术逻辑单元.控制单元) 电源.主板.CPU.内存(RAM).硬盘.(声卡.显卡.网卡)(集成在主板上 ...

  10. easyUI 对话框的关闭事件

    有一个easyUI的dialog: <div id="dlg_Add" class="easyui-dialog" style=" width: ...