设计模式 - kevinEeven/2025 GitHub Wiki

了解软件设计

了解一个软件的设计可以从三个部分着手:模型、接口和实现。这三者的关系就好比你去看代码,你会先去看有哪些类以及它们之间的关系,这就是看模型;然后你会打开一个具体的类,看它提供了哪些方法,这就相当于看接口;最后,你再来打开一个具体的方法,去看它的代码是怎么写的,这就是看实现。

函数式编程

函数式编程的两大优点:1.组合型(面向对象思维) 2.不变性(无副作用、无状态、引用透明)

Optional

让我们回到学生的例子上,如果想获取一个学生出生的国家,我们该怎么写这段代码呢?直觉上的写法是这样的:

public Country getBirthCountry() { 
  return this.getBirthPlace() // 获取出生地
              .getCity()      // 获取城市
              .getProvince()  // 获取省份
              .getCountry();  // 获取国家
}

然而,在真实项目中,代码并不能这么写,因为这样可能会出现空指针,所以,我们不得不把代码写成这样:

public Country getBirthCountry() {
  Place place = this.birthPlace;
  if (place != null) {
    City city = place.getCity();
    if (city != null) {
      Province province = city.getProvince();
      if (province != null) {
        return province.getCountry();
      }
    }
  }

  return null; 
}

Optional是一个对象容器,其中可能包含着一个非空的值,也可能不包含。这是什么意思呢?它和直接使用对象的场景是一一对应的,如果包含值,就对应着就是有值的场景;而不包含,则对应着值为空的场景。

那该如何去创建一个Optional对象呢?

如果有一个非空对象,可以用 of() 将它包装成一个 Optional 对象; 如果要表示空,可以返回一个 empty(); 如果有一个从别处传来的对象,你不知道它是不是空,可以用 ofNullable()。

Optional.of("Hello"); // 创建一个Optional对象,其中包含了"Hello"字符串
Optional.empty(); // 创建了一个表示空对象的Optional对象。
Optional.ofNullable(instance); // 创建了一个Optional对象,不知instance是否为空。

比如,获取学生的出生地,方法可以这么写:

Optional getBirthPlace() {
  return Optional.ofNullable(this.birthPlace);
}

好,回到我们前面的问题上。获取一个学生出生的国家,代码可以怎么写呢?如果相应的方法都改写成Optional,代码写出来会是这个样子:

public Optional getBirthCountry() {
  return Optional.ofNullable(this.birthPlace)
           .flatMap(Place::getCity)
           .flatMap(City::getProvince)
           .flatMap(Province::getCountry);
}

SOLID原则

那SOLID原则是什么呢?它实际上是五个设计原则首字母的缩写,它们分别是:

单一职责原则(Single responsibility principle,SRP)
开放封闭原则(Open–closed principle,OCP)
Liskov替换原则(Liskov substitution principle,LSP)
接口隔离原则(Interface segregation principle,ISP)
依赖倒置原则(Dependency inversion principle,DIP)

单一职责原则

含义:应用单一职责原则衡量模块,粒度越小越好,一个类只对一类行为负责

开放封闭原则

含义:软件实体(类、模块、函数)应该对扩展开放,对修改封闭。

里氏替换原则

含义:子类型必须能够替换其父类型

接口隔离原则