0 设计模式基础
0.0 设计模式的定义
先来看一下设计模式常见的书面定义:
- 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
- 设计模式是指在软件开发中,经过验证的,用于解决在特定环境下,重复出现的、特定问题的解决方案。
设计模式更多的是一种实际应用中经验的基类和总结,并得到了多数人的认可和验证,经过更规范的整理和分类及命名,成为了一种众所周知的知识体系。
0.1 设计模式的分类
一般情况下说到的设计模式都是指Gof著作中所讲述的23中经典设计模式。
-
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
-
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
-
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
1 面向接口编程
上学的时候经常跟室友一起玩儿War3,我一直比较钟情于暗夜精灵族,暗夜精灵有4个灰常厉害的英雄,每个英雄都会有4个技能。刚开始学习面向对象思想的时候,我已经知道“英雄”可以定义成一个类,假设每个英雄出场时候都要秀一下自己华丽的四个技能,我们在构造函数中传递英雄名称,构造不同的英雄对象。
/// <summary>
/// 英雄类
/// </summary>
public class Hero
{
private readonly string _name; // 英雄名称
/// <summary>
/// 构造函数
/// </summary>
/// <param name="name">英雄名称</param>
public Hero(string name)
{
_name = name;
}
/// <summary>
/// 秀出自己的技能
/// </summary>
public void ShowSkills()
{
switch (_name)
{
case "DH":
Console.WriteLine("我是恶魔猎手,我会法力燃烧、献祭、闪避和变身。");
break;
case "WD":
Console.WriteLine("我是守望者,我会暗影突袭、刀阵、闪烁和复仇天神。");
break;
case "KOG":
Console.WriteLine("我是丛林守护者,我会缠绕根须、荆棘光环、自然之力和宁静。");
break;
case "POM":
Console.WriteLine("我是月亮女祭司,我会召唤猫头鹰,灼热之箭,强击光环和流星雨。");
break;
default:
break;
}
}
}
英雄轮流秀出的自己的技能(排名不分先后)
class Program
{
static void Main(string[] args)
{
Hero dh = new Hero("DH");
dh.ShowSkills();
Hero wd = new Hero("WD");
wd.ShowSkills();
Hero kog = new Hero("KOG");
kog.ShowSkills();
Hero pom = new Hero("POM");
pom.ShowSkills();
}
}
输出结果
上面的代码存在的问题主要有2个:
- 如果某天我不再玩儿暗夜精灵了,改玩儿别的种族,Hero类中的ShowSkills方法就要完全修改一遍。
- 秀出自己的技能只是一个最基本的行为,英雄还具有攻击、移动、释放技能等行为,每个英雄攻击力、移动速度、释放技能耗蓝却又都各不相同。
这里就涉及到了面向接口编程的重要原则。
通常接口用来定义实现类的外观,提取实现类共有的行为定义。接口类似于一种契约,根据外部应用的需要,约定了实现类应该实现的功能,而具体内部如何实现,应由具体的实现类控制,同时具体的实现类除了要实现接口规定的行为外,还可以根据需要实现自己独有的行为,也就是说实现类的功能应包含但不仅限于接口定义的功能。
由于外部调用和内部实现被接口隔离开了,外部调用只通过接口调用,也就是说只要接口不变,内部具体实现的变化就不会对外部调用产生任何影响。这样使用接口的好处就很明显了,当我们增加其他英雄的时候只需要增加一个实现英雄接口的具体实现类既可,对原有已实现的不分不会造成任何影响。提现了接口“封装隔离”的思想。
定义英雄接口:
/// <summary>
/// 英雄接口定义
/// </summary>
public interface IHero
{
/// <summary>
/// 秀技能
/// </summary>
void ShowSkills();
}
不同英雄的具体实现:
/// <summary>
/// 恶魔猎手
/// </summary>
public class DH : IHero
{
/// <summary>
/// 秀出自己的技能
/// </summary>
public void ShowSkills()
{
Console.WriteLine("我是恶魔猎手,我会法力燃烧、献祭、闪避和变身。");
}
}
/// <summary>
/// 守望者
/// </summary>
public class WD : IHero
{
/// <summary>
/// 秀出自己的技能
/// </summary>
public void ShowSkills()
{
Console.WriteLine("我是守望者,我会暗影突袭、刀阵、闪烁和复仇天神。");
}
}
/// <summary>
/// 丛林守护者
/// </summary>
public class KOG : IHero
{
/// <summary>
/// 秀出自己的技能
/// </summary>
public void ShowSkills()
{
Console.WriteLine("我是丛林守护者,我会缠绕根须、荆棘光环、自然之力和宁静。");
}
}
/// <summary>
/// 月亮女祭司
/// </summary>
public class POM : IHero
{
/// <summary>
/// 秀出自己的技能
/// </summary>
public void ShowSkills()
{
Console.WriteLine("我是月亮女祭司,我会召唤猫头鹰,