美文网首页
《设计模式解析》笔记

《设计模式解析》笔记

作者: FreDdy_GY | 来源:发表于2019-02-16 16:35 被阅读0次

    最近阅读学习了《设计模式解析》一书,这本书主要解释了设计模式带来了什么好处、解决了什么问题,以及如何更好的使用它们。感觉其中有很多要点都非常的有道理,值得记录下来,在开发的时候时不时拿出来翻看,温故知新,做一个优雅的开发者。

    • 修改一处代码,不应该影响其他地方,如果影响了,说明它们应该放在一起来接受变化

    • 应当尝试预期所有可能发生的变化,并相应的构建代码

    • 对象应该自己负责自己,而且应该清楚的定义责任

    • 抽象类定义了一组类可以做什么,可以充当其他类的占位符

    • 多态:当我通过抽象引用概念性地要求对象做什么时,将得到不同的行为,具体行为取决于派生对象的具体类型。

    • 分析陷阱:避免过早过多的关注细节

    • 按接口编程:
      尽量用聚合代替继承,找出变化并封装之

    • Facade(外观) 模式简化了接口,而Adapter模式则将一个已有的接口转换成另一个接口。

    • 对象
      传统看法:具有方法的数据
      新看法:具有责任的实体

    • 封装
      传统看法:数据隐藏
      新看法:可以隐藏:实现细节、派生类、设计细节、实例化规则

    继承可能会带来的问题

    1. 弱内聚:五边形、六边形等都作为shape的子类,那么边线绘制的逻辑会存在于每一个类中

    2. 减少了复用的可能性:难道每次想要复用五边形的绘制代码,都要继承它?

    • 发现变化并将其封装:
      考虑你的设计中哪些地方可能发生变化,这种方式与关注会导致重新设计的原因相反。它不是考虑什么会迫使你的设计改变,而是考虑你怎样才能够在不重新设计的情况下进行改变。

    设计两步法

    1. 抽象类(共性) 需要用什么接口来处理这个类的所有责任
    2. 派生类(可变性) 对于这个给定的特定实现,应该怎么样根据给定的规约来实现它?
    • 规约视角和概念视角的关系在于:规约标识了用来处理此概念所有情况所需的接口
    • 规约视角和实现视角的关系在于:对于给定的规约,怎样实现这个特定情况
    • 每次当我们感觉需要为什么东西加注释的时候,相反我们会编写一个方法

    可测试的代码是优秀代码的主要品质

    敏捷编程中非常独具特色的实践之一,就是在编写代码之前就编写测试,这有几个目的:

    1. 最后能得到一组自动化测试。
    2. 必须按方法的接口而非实现来设计,这样能得到封装更好,耦合更松散的方法。
    3. 关注测试会使你注意将概念分成多个可测试的部分,这样能够获得强内聚和松耦合。
    • 灾难往往是由短期未甄最优的决策,长期累积而引起的。

    • 针对接口进行编程,而不要针对实现编程。

    • 优先使用对象组合,而不是类继承。

    对象应该只对自己负责

    设计者设计出的接口,没有必要考虑抽象类所有可能的派生类,这可能导致另一种分析瘫痪,只需要支持那些实际要构造的派生类即可。

    • 模式并不总能提供十全十美的解决方案。但是因为模式是众多设计人员多年的集体经验结晶,所以它通常优于你我自己在有限的时间所能提出的解决方案。
    • switch语句可能说明需要抽象

    • 每个部分都因其存在于更大的整体背景中而被赋予了特定的形式

    • 设计应该从问题的一个简单陈述开始,然后通过在这个陈述中加入信息,使它更加详细(也更加复杂),这种信息应该采取模式的形式。

    • 模式定义了问题域中实体之间的关系。

    一条规则(设计模式),实现一次

    模式应该按顺序每次只运用一个,首先应用那些要为其他模式创造背景的模式

    开发步骤
    • 找出模式:
      找到问题中存在的模式,用这些模式来思考问题。请记住,模式的用途是定义实体之间的关系
    • 从背景模式开始:
      找出为其他模式创造了背景的模式。这些模式应该作为设计的起点。然后从背景转向内部,观察其余的模式和任何其他可能已经发现的模式,从中选出为其余模式定义背景的模式,重复这一过程
    • 改进设计:
      改进过程中始终考虑模式所蕴含的背景
    • 实现:
      实现应该融入模式所要求的细节

    这是建筑学中的理论,在软件设计中一个模式可能无法成为另一个模式的背景,但我们能做到在已经出现的概念的背景中添加新概念进行设计。

    • 先考虑系统中需要什么,然后再去关注如何创建它们(先考虑需要什么对象再考虑如何创建(工厂))

    • 一个从基类创建的类应该支持基类的所有行为(主旨是让所有的派生类都可以彼此互换的,实现为一个空方法也是可以的)

    抽象类与接口

    • 抽象类允许有公共的状态或者行为
    • 在不需要的时候不要使用抽象类,因为只有从一个类派生的机会
    • 抽象类可以看成是一种聚集相关实体的方式,其关注点是如何设计这些具体的实体,从而可以以同样的方式使用它们。
    • 通过考虑服务对象,看如何抽象它们,使用对象才不会与任何特定于实现的细节相耦合。
    • 接口看上去更符合依赖倒置原则,看上去更简单,但并不代表其优于抽象类。
    • 当需要定义公开的状态、行为时,也可能定义一个接口,然后用抽象类实现该接口
    • 抽象类能够确定默认行为,使实现类更加简单
    • 现实世界中问题往往不会秩序井然或者循规蹈矩地出现。除了那些最简单的问题,似乎总会有一些没有什么规律的异常和变化。它们是一些异常的不良特性,会破坏我们精心设计的模型。

    Decorator(装饰者)模式

    动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator比生成子类更灵活。

    Decorator模式的约束因素
    • 考虑存在几种可选的功能
    • 这些装饰对象可能遵循也可能不遵循所有规则
    • 需要某种方式以所需的不同顺序调用这些装饰对象,但是又不能加重客户对象的负担
    • 不希望应用程序必须承担知道使用哪些装饰对象的职责

    Template Method模式

    定义一个操作中算法的骨架,而将一些步骤延迟到子类中,不改变算法的结构而重定义它的步骤。

    各种工厂模式

    开发分为以下两步方法:

    • 定义对象和它们的协作方式
    • 编写为相应情况实例化对象并在对象共享时管理已有对象的工厂
    • 对象要么构造其他对象,要么使用其他对象,绝不要两者兼顾

    • 工厂封装了在什么环境下创建什么对象的规则,这样当系统的其他部分使用对象时,就可以不考虑具体的实现。

    工厂方法模式

    定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到其子类。

    总结

    • 对象是具有明确定义的责任的事物。
    • 对象对自己负责。
    • 封装指的是任何形式的隐藏。其中包括:数据隐藏、实现隐藏、类隐藏、设计隐藏、实例化隐藏。
    • 使用共性和可变性分析抽象出行为和数据中的变化。
    • 按接口设计。
    • 将继承看成一种将变化概念化的方法,而不是创建已有对象的特殊情形。
    • 将变化放入一个类中,并与该类中的其他变化解耦。
    • 力求松耦合。
    • 力求强内聚。
    • 将使用一个对象的代码与创建该对象的代码分离。
    • 在应用“一次且仅一次”规则时要绝对小心。
    • 通过“按意图编程”,使用反映意图的名字,确保代码的可读性。
    • 在编程之前就考虑代码的可测试性。
    在模式的学习过程中,寻找以下约束因素和概念会有所帮助
    • 这个模式隐藏了什么实现?这样我们就可以修改它
    • 这个模式中有什么共性?这有助于你找到共性
    • 这个模式中对象的责任是什么?这可以更容易地按责任进行分解
    • 这些对象之间有什么关系?这将提供这些对象的约束因素的信息
    • 这个模式本身怎样成为从背景设计的微观示例?这使我们能够更好地理解为什么这个模式是优秀设计

    相关文章

      网友评论

          本文标题:《设计模式解析》笔记

          本文链接:https://www.haomeiwen.com/subject/xlcieqtx.html