基于java-design-patterns白话图解设计模式(个人理解)

Principle 设计原则

Generic

KISS

KISS (Keep It Simple Stupid)

YAGNI

You Ain’t Gonna Need It (翻译:你可能不需要他,即不要过度设计,为了迎合某些产生概率极低的需求而设计的成本是非常高的软件)

YAGNI stands for “you aren’t gonna need it”: don’t implement something until it is necessary.

DRY - Don’t Repeat Yourself

使其每一个部件都是职责明确的并且可重用的

Do The Simplest Thing That Could Possibly Work

Ask yourself: “What is the simplest thing that could possibly work?”

SoC

Separation of concerns

Break program functionality into separate modules that overlap as little as possible.

https://en.wikipedia.org/wiki/Separation_of_concerns

separation of concerns (SoC) is a design principle for separating a computer program into distinct sections such that each section addresses a separate concern. A concern is a set of information that affects the code of a computer program.

引用

Patterns 设计模式

Abstract Document (抽象文档模式)

白话:总分总分

故事:买车

我想买一辆车,首先要知道它的品牌型号如:300SL,价格 16W

但是我最近狗屎运特别好,厕所捡到了10W块,当然买高配版,轮胎型号15C,价格100¥,车门型号 Lambo 价格300¥,最终用抽象文档模式代码表示,我买到的车:

App.java

public App() {
    LOGGER.info("Constructing parts and car");

    var wheelProperties = Map.of(
        Property.TYPE.toString(), "wheel",
        Property.MODEL.toString(), "15C",
        Property.PRICE.toString(), 100L);

    var doorProperties = Map.of(
        Property.TYPE.toString(), "door",
        Property.MODEL.toString(), "Lambo",
        Property.PRICE.toString(), 300L);

    var carProperties = Map.of(
        Property.MODEL.toString(), "300SL",
        Property.PRICE.toString(), 160400L,
        Property.PARTS.toString(), List.of(wheelProperties, doorProperties));

    var car = new Car(carProperties);

    LOGGER.info("Here is our car:");
    LOGGER.info("-> model: {}", car.getModel().orElseThrow());
    LOGGER.info("-> price: {}", car.getPrice().orElseThrow());
    LOGGER.info("-> parts: ");
    car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}",
        p.getType().orElse(null),
        p.getModel().orElse(null),
        p.getPrice().orElse(null))
    );
  }

配一个网上找的类图

点评

主要的优点是找到总体和局部共有的属性,通过简单的几个属性能详细描绘复杂的总体和部分。

Abstract Factory (抽象工厂模式)

白话: switch 一个抽象类

故事:“从0到100万”——中国鞋都莆田口罩生产攻坚记

说实话我听到这个故事还是震惊的,:dizzy_face: 我印象中的“莆田”不是这个样子的呀?应该是莆田系博爱男科,或者是莆田系博士男科啥的。想不到竟然是鞋都,虽然是“Costplay”正版。

好进入正题,莆田通过抽象工厂模式 从鞋子->(转换)口罩工厂 就是典型的抽象工厂模式,代码上就是

莆田 class{

  public FactoryImp factory(String type){
    switch(type){
      case 鞋子:
            return 鞋子_factory;
      case 口罩:
            return 口罩_factory;
    }
  }
}

其实本质是由于生产鞋子和生产口罩的原料和工艺大体是类似的,通过相对简单的整合原料,机器和生产工艺就能得到生产不同产品的工厂。这种做法好处在于充分利用现有资源的情况下,最高效快速的生产出口罩,解决由于疫情爆发导致的口罩稀缺的情况;java-design-patterns 给的例子是一个城堡的例子不太喜欢,感兴趣的可以去看一下,地址如下:
abstract factory github App.java

点评

抽象工厂模式,通过的输入简单鞋子、口罩命令,并抽象规定这个工厂的产出,而具体复杂的资源整合及类的初始化调用的复杂逻辑流程等等都不需要使用者关心。

应用案例

Acyclic Visitor (非循环访问者模式)

白话: 一把钥匙开一个门(项目),可以有动态的数量的钥匙环

故事:从小我就有一个开游乐园的爸爸,当有同学来游乐园玩的时候,他会根据同学们的要求,兴趣和胆量分配给他们游乐项目的钥匙,当然有的同学拿到多有的拿到少,还有几个拿到了比较危险的项目;

App.java

  public static void main(String[] args) {
    /*分配到的玩项目的权限或钥匙集合*/
    var conUnix = new ConfigureForUnixVisitor()
    var conDos = new ConfigureForDosVisitor();

    //各种各样的游乐设施
    var zoom = new Zoom();
    var hayes = new Hayes();

    // 开玩
    hayes.accept(conDos); // Hayes modem with Dos configurator
    zoom.accept(conDos); // Zoom modem with Dos configurator
    hayes.accept(conUnix); // Hayes modem with Unix configurator
    zoom.accept(conUnix); // Zoom modem with Unix configurator   
  }

上一波项目类图

点评

非循环访问者模式,很近似于我们用不同的钥匙打开不同的门,而打开不同的门,里面会有不同的资源提供给我们使用。

  1. 钥匙和门的关系比较单一,具有固定属性。
  2. 子门子钥匙可以继承父钥匙和门,实现层级结构的划分。

使用场景

  1. 当你想动态的向现有层次结构添加功能(资源)时,不想做修改或影响整体的层次结构,即增加一个门和钥匙无需对整体修改;
  2. 当存在不同层级结构的资源(类比:门)访问操作时,不用修改层级结构,通过ConfigureXXX类进行管理控制;

参考:非循环访问者模式( Acyclic Visitor)

Adapter (适配器模式)

白话 USB转视频接口/USB转高清视频接口

点评

  • 安卓原生最常用类,常用于数据处理类,处理完数据定义好格式,返回给调用类使用,往往数据(事件)处理类格式一定,而返回的数据需要处理展示千变万化,定义一个adapter抽象类,给数据处理类调用,满足数据处理类最小功能和最少改动的设计原则。

Ambassador(大使模式)

为什么叫大使模式,无非二点

  • 大使是自己人
  • 大使负责处理非本国(远端)事务

白话

大使为我们(Client)处理外国(Service)的关系,记录交往信息,分析外国局势,使我们更好的应对外围环境的变化。

本地和远端共同实现一个接口,client调用本地大使,大使调用远端服务

点评

把维护service链接的功能放到大使类中处理,如

  1. 访问控制,维护…
  2. 访问日志记录
  3. 链接维护,短路重连,掉包测试…
  4. 卸载服务
  5. 安全管理

API-Gateway API 网关

白话 本地API统一交给API网关管理,对API进行整合及代理管理

附录

java-design-patterns

设计模式的分类