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

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

透传方法

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

class A{
    void GetValue() {
        return b.GetValue();
    }

  private:
     B b;
};

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

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

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

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

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

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

装饰器模式

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

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

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

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

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

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

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

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

接口与实现

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

透传变量

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

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

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

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

总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值