Logo
Section 1 / 2

简介

本课为理解设计模式奠定了基础。

导入

简介

本课为理解设计模式奠定了基础。

为何需要设计模式?

我们为什么需要设计模式?直白地说,因为我们不想重复造轮子! 在技术实践中频繁出现的问题,通常已有清晰、灵活、模块化且易于理解的解决方案。当这些解决方案从具体实现细节中抽象出来后,就形成了设计模式。如果你在设计某个问题的解决方案时,产生了一种似曾相识的感觉——尽管领域不同,但解决思路与之前遇到的问题非常相似——那么你很可能已经在无意中使用了某种设计模式。

下图展示了“四人组”在其开创性的设计模式著作中所阐述的各种设计模式之间的关系。

design-pattern-v2.png
design-pattern-v2.png

示例

我们通过一个例子来理解什么是设计模式以及它们如何被应用。类构造函数是面向对象语言中的基本概念之一。构造函数用于创建类的实例,并可以接收参数。以下面这个类为例:

1 2public class Aircraft { 3 4 private String type; 5 6 public Aircraft(String type) { 7 this.type = type; 8 } 9}

在上述例子中,我们为类定义了一个构造函数,它接受一个参数,即飞机的 type(类型)。假设几天后,你希望为 Aircraft 类添加更多属性,例如增加“颜色”属性。但此时你已经发布了一个库版本,无法修改原有的构造函数。一种解决方法是新增一个包含两个参数的构造函数:

1public class Aircraft { 2 3 private String type; 4 private String color; 5 6 public Aircraft(String type) { 7 this.type = type; 8 } 9 10 public Aircraft(String type, String color) { 11 this.type = type; 12 this.color = color; 13 } 14}

如果继续这样下去,你会得到一系列参数数量不断增加的构造函数,看起来就像望远镜一样层层延伸:

1 2Aircraft(String type) 3Aircraft(String type, String color) 4Aircraft(String type, String color, String prop3) 5Aircraft(String type, String color, String prop3, String prop4) 6

这种不断扩展参数的方式被称为反模式:即不应该采用的做法! 面对成员变量越来越多的类,正确的做法是使用建造者模式(Builder Pattern),我们将在后续章节中深入讨论这一模式。

经验丰富的开发者通常都熟悉设计模式,合理运用这些模式可使代码更易于复用和维护。设计模式不仅限于面向对象语言,也广泛存在于计算机科学的其他领域,如分布式系统、大数据系统或用户界面设计等。

面向对象设计建议

在编写面向对象语言代码时,遵循以下建议可以让代码更容易应对未来的变化,同时减少修改成本。

  • 将代码中可能变化的部分与不变的部分分离。

  • 尽量针对接口编程,而不是依赖具体实现。

  • 尽可能地封装行为。

  • 优先使用组合而非继承。继承可能导致类的数量急剧膨胀,有时基类新增的功能并不适用于所有子类。

  • 系统内部各组件之间的交互应尽可能松耦合。

  • 理想情况下,类的设计应禁止随意修改,但鼓励通过扩展来增强功能。

  • 在日常开发中使用设计模式,可以通过共通的模式术语与其他开发者高效交流整体设计思想。

上述部分建议将在接下来的课程中通过具体的设计模式体现出来。但需注意,提升设计的灵活性和可扩展性的同时,也会相应增加代码的复杂性和理解难度。在实际软件设计与开发过程中,必须在这两个目标之间把握好平衡。

设计模式的类型