软件设计模式 - STEMHA's Blog

软件设计模式

序言

为什么我们需要模式?直截了当的答案是我们不想重新发明轮子!

设计模式基本概念

什么是模式

  • 概念:在技术生活中经常发生的问题通常具有定义明确的解决方案,这些解决方案灵活,模块化且更易于理解。这些从战术细节上抽象出来的解决方案就成为了模式
  • 应用场景:假如你针对一个问题设计解决方案时遇到了似曾相识的感觉,换句话说,这个解决方案与之前你遇到的某个问题的解决方案极为相似,那么尽管问题在不同的领域,你可能在不知不觉中就使用了一种模式。

为什么要使用设计模式?

  • 为了重用代码
  • 让代码更容易被他人理解
  • 保证代码可靠性。

GOF(Gang of Four)

1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。
他们所提出的设计模式主要是基于以下的面向对象设计原则:

  • 对接口编程而不是对实现编程。
  • 优先使用对象组合而不是继承。

设计模式的使用

下面是一个示例,让我们更深刻地了解什么是设计模式以及如何应用它们。 接下来的文章中我们来做一下有意思的大工程吧,运用代码来创建一架飞机!

首先我们要创建飞机的类,名字为 Aircraft,然后要创建相应的构造函数。类构造函数是面向对象语言中的基本概念之一。构造函数帮助创建类的对象,并可以接受参数。

1
2
3
4
5
6
7
8
9
10
11
class Aircraft {

private:
string type;

public:
Aircraft(string type)
{
this->type = type;
}
}

在上面的示例中,我们为该类提供了默认构造函数,该构造函数接受飞机的单个参数type 。结果过了几天后,你意识到你还要向Aircraf类添加其他属性。我们就假设你要添加的新属性是飞机的颜色,但是你之前已经发布了一个版本的库,并且无法在库中修改原始构造函数。因为库已经发布给用户了,很多用户说不定都已经用上了,所以不能够改已经发布的库的函数接口。那么该怎么办呢?

解决方案是添加另一个具有两个参数的构造函数(也就是我们新加入一个拥有不同接口的构造函数),如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Aircraft {

private:
string type;
string color;

public:
Aircraft(string type)
{
this->type = type;
}

Aircraft(string type, string color)
{
this->type = type;
this->color = color;
}
}

假如又过了几天,你又有新的属性要添加到飞机这个类中。
如果继续上面这种方式,你将最终得到一堆构造函数,其中的函数参数越来越像折叠望远镜,我们就把这种办法称作为折叠构造函数模式(telescoping constructor pattern )吧:

1
2
3
4
Aircraft(string type)
Aircraft(string type, string color)
Aircraft(string type, string color, string prop3)
Aircraft(string type, string color, string prop3, string prop4)

The telescoping pattern is called an anti-pattern: how NOT to do things! //伸缩模式称为反模式:也就是如何对发布的库不做修改!

很明显,使用折叠构造函数模式来处理这种属性变量越来越多的类是极为不便的,那么,我们该采取何种方法呢?

实际上处理变量越来越多的类的方法是使用建造者模式(Builder Pattern),我们将在接下来的文章中深入讨论。

设计模式概要

  • 经验丰富的开发人员应精通设计模式,应用这些模式可使代码在将来可重用和可维护。
  • 设计模式不仅限于面向对象的语言,还存在于计算机科学的其他领域,例如分布式系统,大数据系统或用户界面。

急于要接受即将面试的课程的人们,建议您遍历所有的创建型模式,装饰器,代理,迭代器,观察者和访客模式。

设计模式的分类:

  • 创建型模式:新创建的对象听起来可能很琐碎,但在创建对象实例时随便乱扔代码绝对会让你日后头痛。创新的设计模式提供了有关如何最好地将对象创建过程封装到程序中的有力建议。、

    • 提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
  • 结构型模式:与类的组成有关,即类的构成或构造方式。

  • 行为设计模式:规定了类和对象之间的交互以及责任的委派。

    • 特别关注对象之间的通信

面向对象设计的建议

  • Separate out parts of code that vary or change from those that remain the same. //将保持不变的部分和经常变化的部分分开。
  • Always code to an interface and not against a concrete implementation. //针对接口编码,不要针对具体实现编码。
  • Encapsulate behaviors as much as possible. //尽可能对行为进行封装
  • Favor composition over inheritance. Inheritance can result in explosion of classes and also sometimes the base class is fitted with new functionality that isn’t applicable to some of its derived classes.//优先考虑组成而不是继承。继承会导致类的爆炸式增长,并且有时基类还配备了不适用于其某些派生类的新功能。
  • Interacting components within a system should be as loosely coupled as possible. //系统内的交互组件应尽可能松散地耦合。
  • Ideally, class design should inhibit modification and encourage extension. //理想情况下,类应该禁止修改并鼓励扩展。
  • Using patterns in your day to day work, allows exchanging entire implementation concepts with other developers via shared pattern vocabulary.//通过运用设计模式词汇和其他人交换设计思路

接下来我们说明的大多数设计模式,都是围绕着构建我们的飞机来的,不得不说是个大工程啊(从零开始造飞机!),开始我们的设计模式之旅吧!

参考资料

设计模式总结
Software Design Patterns: Best Practices for Software Developers /github educative

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×