• A Philosophy of Software Design读书笔记——不同的层需要不同的抽象


    软件系统中不同的层需要不同的抽象,比如:文件系统,网络模型等。如果不同的层实现类似的功能,这是有问题的,本章讨论这个问题如何发生、如何解决,如何重构这样的系统。

    透传方法

    相邻层有着类似的功能,通常表现为上层直接将方法参数透传下去,调用下层的函数,比如:

    1. class A{
    2. void GetValue() {
    3. return b.GetValue();
    4. }
    5. private:
    6. B b;
    7. };

    这种方式表明两个类或者模块功能划分不清晰。

    缺点:增加接口复杂度,但是并没有增加功能,同时也增加了模块间的耦合。

    如果遇到这样清空,需要考虑这两个类模块所负责的真正职责是什么,对于模块间的共同职责一定要关注。解决方式有两个:1、划分好每个类的职责;2、如果职责无法区分,就合并这两个类。

    什么时候接口重复是可以的

    上述方式并不是一直都是不好的,关键是模块有没有增加新的功能中,比如类似于工厂模式的设计实现,Dispatcher方法,根据不同的类型,调用下面实现类的Dispatcher方法。

    只有提供了不同的功能,提供相同的方法(包括方法名和方法参数)是可以的

    装饰器模式

    装饰器模式,对外提供一个接口,内部对这个接口有不同的实现。

    这个模式本质上是把一个专用模块扩展的更加通用,但是如果使用不同,很容易造成接口透传,造成模块耦合。

    在使用装饰器模式之前,考虑以下替代方式:

    1、是否可以直接使用底层实现类,而不是装饰器类

    2、如果新特性只对某些case生效,那么在使用时,扩展而不是创建一个新的类

    3、新的实现在老的类中扩展,而不是创建新的

    4、新特性只是一个很小的东西,没必要为了适配装饰器模式,而实现一个特别庞大的接口(组合是可选择的,但是继承是强耦合的)

    有时装饰器模式是好用的,但是大多数时候都不是一个好的选择

    接口与实现

    接口与实现在两个抽象层级,如果抽象层级一样,那么大多数实现的不深

    透传变量

    相邻层有着类似的功能另一个表现方式是透传变量。

    透传变量增加了模块间交互的复杂度,下层模块必须感知到上层模块的参数,而且中间模块必须接受这些参数,尽管这些模块并不需要这些参数(而且很容易造成方法参数很长)

    减少参数透传很困难,解决方式:1、创建共享参数类,把所有需要透传的变量封装到共享参数类中;2、使用全局变量(尽量不要使用,弊大于利);3、最常使用的是引入一个context类,在每个层级的构造函数中传入这个类,这样有新的透传参数需要添加时,只需要更改context类即可(没看出1与3的区别)

    作者推崇的是方法3,但是方法3远不是完美的解决方案

    总结

    每实现一个特性都要添加一些模块、类、方法、参数,这就为系统增加了复杂度,因为使用者必须了解这部分,一个完美的状态是,增加了很少复杂度(接口简单),但是实现了很多功能(实现要深)。

  • 相关阅读:
    Android jetpack room 数据库的升级
    修改history记录、定时校正服务器时间、停止IPv6网络服务、调整最大文件打开数、关闭写磁盘I/O功能、配置SSH服务
    黑马mysql教程笔记(mysql8教程)基础篇——数据库相关概念、mysql安装及卸载、数据模型、SQL通用语法及分类(DDL、DML、DQL、DCL)
    sql注入原理分析
    深入理解Java虚拟机-垃圾收集器与内存分配策略
    成为会带团队的技术人 做规划:除了交付和稳定性,还要规划什么?
    Java实现word转PDF
    node应用故障定位顶级技巧—动态追踪技术[Dynamic Trace]
    【NLP练习】调用Gensim库训练Word2Vec模型
    Redis 缓存穿透、缓存击穿、缓存雪崩分别是什么?
  • 原文地址:https://blog.csdn.net/yh88623131/article/details/127714707