最近在看"Head First 设计模式"这本书,便想将自己所学的记录下来以加深理解,文中肯定有许多不足之处,请各位前辈们指出.
设计模式并不是某种开发语言中的工具,而是我们处理问题时的一种体现,平时在工作我们也总是会使用设计模式,在工作时我们会碰到各种问题,然后我们通过思考,总结.得到出自己的一套处理问题的经验,或许我们并不知道什么是设计模式,但是对于某种问题我们已经有了一套解决方案,然后通过观看它人的代码会发现别人处理这类问题与自己总结的相同,其实设计模式就是如此,它是前辈们通过大量的经验总结了出了一套程序设计思想,然后通过记录和分享,于是出现了现在编程中的圣经-----23种设计模式.也就是说设计模式其实并不神秘,但是它却如此的重要
注:此处所说的问题是代码中设计的问题,并不是功能需求问题,例如代码的紧耦合
下面来说一下第一个设计模式:策略模式,策略模式是一个极其简单的模式,但也是一个极其常用的模式,下面以一个极其简单的例子介绍策略模式 现在要为一家商场设计一个促销功能,不过现在并不知道具体的促销需求,我们只需将促销需求设计出来,然后在后期进行添加具体的促销策略,于是我们快速的完成了这个类的第一版
// 商品类
class Goods
{
// 商品名称
public string GoodsName { get; set; }
// 商品价格
public decimal GoodsPrice { get; set; }
// 促销方法
public void Discount()
{
Console.WriteLine("这是促销方法,目前无促销");
}
}
注:这是一个简单例子,只为阐述策略模式.
这一个简单的类型便是第一版的商品类的促销功能,但是在这里有一个巨大的问题,就是促销策略的改变使得我们就必须更改其代码.这并符合我们的设计理念,我们观察代码可以得知在这个功能中促销是一个可变的部分,而我们可以将可变的部分进行分离,现在我们来更改一下代码
// 商品类
class Goods
{
//促销类引用
public DiscountStrategyClass DiscountStrategyClass { get; set; }
// 商品名称
public string GoodsName { get; set; }
// 商品价格
public decimal GoodsPrice { get; set; }
// 促销方法
public void Discount()
{
//调用促销类的促销方法
DiscountStrategyClass.Discount();
//Console.WriteLine("这是促销方法,目前无促销");
}
}
// 促销类
class DiscountStrategyClass
{
// 促销方法
public void Discount()
{
Console.WriteLine("这是促销方法,目前无促销");
}
}
上面就是我们将促销方法分离后的代码,我创建了一个促销类,然后在商品类内部创建一个促销类的引用并在促销方法调用促销类的促销方法,然后我们其实很自然的就能想到下一步了,也就是创建抽象促销类,然后子类进行实现,并约定好自己的促销策略,而商品类只需声明并调用抽象促销类促销方法就可以,
// 商品类
class Goods
{
//促销接口引用
public IDiscountStrategy DiscountStrategy { get; set; }
// 商品名称
public string GoodsName { get; set; }
// 商品价格
public decimal GoodsPrice { get; set; }
// 促销方法
public void Discount()
{
//调用促销类的促销方法
DiscountStrategy.Discount();
//Console.WriteLine("这是促销方法,目前无促销");
}
}
// 促销类
interface IDiscountStrategy
{
// 定义促销方法
void Discount();
}
//八折折扣
class EightyPercentDS : IDiscountStrategy
{
public void Discount()
{
Console.WriteLine("这是促销方法,我打八折");
}
}
//七折折扣
class SevenPercentDS : IDiscountStrategy
{
public void Discount()
{
Console.WriteLine("这是促销方法,我打八折");
}
}
这个小的促销功能就完成了,并且我们可以感觉到在写代码时总是这样使用 从这里可以看到策略模式的两个好处
策略模式体现了两个原则:
其中策略模式强调的是组合,也就是有一个(HAS-A),只是这里并没有很好的体现,在装饰者模式更能很好的体现 我们在设计编写代码时也要遵守这样的规则,让系统变得更有弹性.
下面是这个简单的策略模式的UML图
但在项目中有时候却会再抽象一层,将环境角色类(当前Goods)抽象成抽象类也就是这样的UML图
这样的UML可以想象成将Goods类变成抽象类,然后再声明它的子类,例如ComputerGoods(电视),BookGoods(书籍),然后利用继承的特性来解放实现,也就是我们常说的面对接口编程
注: 面对接口编程并不是面对Interface编程,而是面对超类编程
定义一个算法家族,分别封装起来,让它们可以互相替换,此模式让算法的变化独立于使用算法的客户