这两天面试被问到设计模式,发现自己大概从13年起也就不执着于根据设计模式来设计程序,虽然一直在用,但突兀问起有的记得,有的确也是记不太清了。趁此机会来回顾下,先推荐本书,个人感觉适合初学者,记忆会比较深刻《大话设计模式》,不过学会了还是看看经典吧~
还有篇博文,相当不错,对于每个设计模式都给出了示例之类的:
http://terrylee.cnblogs.com/archive/2006/06/01/334911.html
闲话少说,下面我就根据自己的理解来给你简单聊聊设计模式,时间有限,就不面面俱到,也就聊些常用的,如有不足还请批评指正。
1. 单例模式
这个因为太过不起眼,很容易令人遗忘,比如笔者就是想了半天还是觉得不会那么简单而放弃了,其实它真得很简单。
啥叫单例?顾名思义,就是指一个类或者对象有且仅有一个实例,有点类似于静态全局变量,用大白话来说,每个个体都是独一无二的,无法复制与克隆,就是这么简单。
2.简单工厂模式
个人认为这个模式实在太过普遍,乃是面向对象设计中的基础,何为简单工厂,举一个很简单的例子:
比如商场打折促销搞活动,不同的商家自然促销方式不同,假设有:
① 商品8折
② 特殊商品5折
③ 满99减45
……
诸如此类,我们可以将这些统称为打折策略。
如何灵活应用打折策略?那就是简单工厂的作用了。
我们定义一个抽象类叫做收费,随后对于不同的打折策略都以收费为基类,重写它们的具体方法,最为重要的是,我们仅在工厂中对它们进行有针对性的调用,以此来降低耦合度,使得复用性和维护性更好。
//抽象类
abstract class 收费
{
public abstract double 计算总价(double money);
}
//针对不同的打折方式的具体实现
class 打八折: 收费
{
public override double 计算总价(double money)
{
//具体计算流程
return money;
}
}
class 满99减45: 收费
{
public override double 计算总价(double money)
{
//具体计算流程
return money;
}
}
...
//工厂类
class 收费工厂
{
public static 收费 create(string str)
{
收费 oper = null;
switch (str)
{
case "打八折" : oper = new 打八折(xx);
break;
case "满99减45" : oper = new 满99减45(xx);
break;
……
}
return oper;
}
}
}
客户端调用就省略了,其实就是创建工厂类调用抽象类即可。
就和上面所说,我们用工厂封装了所有的打折策略,这就是简单工厂,注意:不是工厂模式哦~
3. 策略模式
还是依着上面的例子来说,打折是种策略,因而可以用策略模式(只是胡说八道罢了,莫当真O(∩_∩)O~)。
但其实,无论是商品打折,亦或是调度公交,它们都是针对同一件事的不同处理方法,或者说,算法不同,那么我们就可以用策略模式了。
先来一瞅代码,其中抽象类和具体实现不变,增加一个策略配置类。
//策略配置类
class 策略配置
{
收费 strategy;
public 策略配置 (收费 specific_strategy)
{
this.strategy = specific_strategy;
}
public double 策略配置接口()
{
return strategy.计算总价(xx);
}
}
这样子,整体的构建就完成了,最后看下客户端的调用,惊喜时刻来临:
//Main
int main()
{
策略配置 oper;
oper = new 策略配置(new 打八折(xx));
oper.策略配置接口();
oper = new 策略配置(new 满99减45(xx));
oper.策略配置接口();
return 0;
}
有没有很惊喜?是的,你没看错,它又回去了~第一反应就是:还不如简单工厂呢。。。
但它的优势在哪?直接在客户端根据需要调用即可,没有简单工厂那么的遮遮掩掩,当然喽,就封装性而言,简单工厂更胜一筹。
那么如何让它看起来更好?
很简单,更改策略配置类。
//策略配置类
class 策略配置
{
收费 strategy;
public 策略配置 (string str)
{
switch (str)
{
case "打八折" :
{
打八折 oper1 = new 打八折();
strategy = oper1;
}
break;
case "满99减45" :
{
满99减45 oper2 = new 满99减45();
strategy = oper2;
}
break;
……
}
}
public double 策略配置接口(double money)
{
return strategy.计算总价(money);
}
}
这时候再看客户端这时候就和简单工厂时类似了,其实我们只是把判断放回了封装类而已。
这便是策略模式与简单工厂的一个结合吧。
不过,笔者在这里要提醒各位的是:大部分情况下,择一即可,并不一定结合就是好,比如笔者,更偏爱纯粹的策略模式。其实两者区别不大,只是策略模式在封装时更复杂,增加了单一实例,通过构造函数和自带函数来传达一个更完整的处理流程罢了。
2014.4.30 小结
至此,最为基础的三个模式已经全部讲清楚了,也写了快一小时,休息下,以后继续。(我的目标是:签完工作的两周内,路漫漫o(╯□╰)o)
未完待续...
不过,还是先给出CSDN《大话设计模式》电子版的地址:http://download.csdn.net/detail/yousuosi/4364766
希望多多支持原作者,同样作为一个卖脑力劳动的我们,一定能明白是多么辛苦,尊重与分享,有点条件还是买本正版吧~
最后啰嗦句:这么好的书,不持有一本实在可惜。