读书笔记之《设计模式解析》读后总结

      读完了《设计模式解析》一书,对于面向对象有了更深的理解。将该书关于模式理解的一些共性以及思考总结下来,具体的设计模式就不提了,因为笔者也是属于新手,就不班门弄斧了。


一、传统看法将对象看作有方法的数据,而设计模式将对象看作是具有责任的一个实体。面向对象原则总结:

  • 对象是具有明确定义的责任的事物。
  • 对象对自己负责
  • 封装指的是任何形式的隐藏:数据隐藏,实现隐藏,类隐藏(在抽象类或接口后),设计隐藏,实例化隐藏。
  • 使用共性和可变性分析抽象出行为和数据中的变化
  • 按接口设计
  • 将继承看成一种将变化概念化的方法,而不是创建已有对象的特殊情形
  • 将变化放入一个类中,并与该类中的其它变化解耦
  • 力求松耦合
  • 力求强内聚
  • 将使用一个对象的代码与创建该对象的代码奋力
  • 在应用”一次且仅一次“规则时要绝对小心
  • 通过”按意图编程“,使用反映意图的名字,确保代码的可读性
  • 在编码之前就考虑代码的可测试性


二、传统看法将封装看作是对数据封装,而设计模式将封装视为数据、方法、类型等所有变化的封装。

        对客户对象屏蔽了实现细节,隐藏实现的价值在于,模式使开发人员能够容易地添加新的实现,因为客户对象不知道当前实现的具体工作细节。


三、.模块化的原则,高内聚和松耦合。

        内聚性,指例程中操作之间联系的紧密程度。耦合性指两个例程之间联系的紧密程度。


四、设计模式方法经常被人叙述成需要“预先设计”

     它提倡从问题领域的一些主要概念着手,然后深入,逐步考虑更多的细节。

     关注最重要的问题对于敏捷开发至为关键。极限编程甚至为此创造了一句格言:YAGNI(ya ain‘t gonna need it,即”你不需要他“)。它反映了这样的理念:应该构建现在需要的东西,而忽略其它。应该尽早完成最重要的工作,何时能够解决这些最重要的问题,会产生最大的影响。这还说明,应该避免开发那些分散精力而且一般用不上的(因此构建它们是浪费资源的)东西。


五、敏捷编程的品质:

  (1)无冗余;

      “一个规则,一个地方”。也称为“一次且一次规则”-----系统必须能表达要表达的一切;系统必须不含重复代码。这通常会使代码中出现许多小的方法,所增加的代价很小,却消除了重复,而且经常可以预防将来可能出现的很多问题。重复的害处,不仅仅在于输入工作成倍增加,还因为将来有东西可能发生变化时,可能会忘记在所有需要的地方进行修改。遵循这一策略,有助于重构。复制粘贴然后修改代码会留下冗余,消除冗余的方式之一是去除重复。

 ( 2)可读;

    关注动机而非实现。“按意图编程”这一要求将可读性提升到了新的层次。简单而言,当你编写代码时,需要实现一些函数,只是假定它们已经存在,为它们指定“反映意图的名字”,编写对这些函数的方法调用,然后继续(以后再实现函数)。也就是说编程变成了一系列对函数的调用,这些函数的命名清晰地说明了它们的用途。Martin Flower对此更进一步:“每当我们感觉需要为什么东西加注释的时候,相反我们会编写一个方法。”其结果就是更简短、更清晰而且更紧凑的方法。

  (3)可测;

     可测试性:单元测试;测试驱动开发(TTD)。


六、面向对象设计中,设计人员应该了解问题域,找到其中的名词,然后创建对象来表示这些名词。接下来设计人员寻找与这些名词相关的动词(也就是它们的操作),并通过在对象中添加方法来实现这些动词。这种以名词和动词为中心的过程通常会生成超出我们意愿的庞大类层次。

      我认为,在创建对象时使用共性和可变性分析作为主要工具(即分析问题域中的共同的地方和发生变化的地方),要优于仅仅关注名词和动词。也就是先寻找共性,从这些共性创建对象;从共性的变化寻找派生,看共性之间的关系如何。通过先定义共性,消除了特殊情况之间的耦合,隔离变化和共性。

     在进行设计以应对变化的过程中,应遵循三条基本策略:(1)找出变化并封装之;(2)优先使用对象组合,而不是继承;(3)针对接口编程,而不是针对实现编程。其意图是能够在互相独立的类中包含变化,从而允许未来发生变化,而不影响原有代码。实现这一目的的一种方法是:将所有的变化都分别放在自己的抽象类中,然后观察这些抽象类之间的关系。


七、不要过度使用继承,学会用对象的职责而不是其结构来思考问题。有经验的面向对象分析师都已经了解到应该有选择地使用继承,才能发挥其优势。使用设计模式,将有助于加快这一学习进程。其中就包括从“为每种变化使用不同的特化”(继承)到“将变化转移到使用或拥有这种变化的对象中”(组合)的转变。

       按责任分解问题域。共性可变性分析可以辨识概念视角(共性)和实现视角(每个具体的变化)。如果只考虑共性和使用共性的对象,可以以另一种方式思考问题----分解责任。各种具体的设计模式有助于思考如何分解责任。


八、switch语句可能说明需要抽象。

       swich语句本身常常说明:(1)需要多态行为;(2)存在职责错放。应该考虑用一种更通用的解决方案,比如抽象代替switch语句,或者将职责赋予其他对象。


九、使用设计模式进行思考的方法:

  (1)从对整体的概念性理解开始,以理解需要实现的目标;

  (2)找到在整体中出现的模式;

  (3)从为其他模式创造背景的那些模式开始; 

  (4)从背景向内:应用这些模式,找到新模式,并重复;

  (5)最后,通过每次应用一个模式,改进设计,并在所创建的背景中予以实现。

    更加精确的用模式思考的过程:

  (1)找出模式。在问题域中找出模式。

  (2)分析和应用模式。对于要进行分析的模式集合,执行步骤a~d。

           a .按背景的创造顺序将模式排序。根据为其他模式创造背景的情况将模式排序。其原理是,一个模式将为另一个模式创造背景,不会出现两个模式互为彼此创建背景的情况。考虑背景时使用的一条规则:优先考虑系统中需要什么,然后再去关注如何创建它们。

          b.选择模式并扩展设计。根据排序,选择列表中的下一个模式,用它得到高层的概念设计。

          c.找到其它模式。找到在分析中可能出现的其他模式,将它们添加到要分析的模式集合中。

          d.重复。对还没融入概念设计的模式重复以上步骤。

  (3)添加细节。根据设计的需要添加细节。扩展方法和类的定义。


十、设计模式的原则:

   (1)开闭原则,可以这样理解:模块、方法和类应该对外开放,对修改封闭。也就是说应该将软件设计得不对其修改就能扩展功能。

   (2)依赖倒置原则,高层模块不应该依赖低层模块。高层模块和低层模块都应该依赖抽象。抽象不应该依赖于细节。细节应该依赖于抽象。这一原则隐含着使用对象与被使用对象之间只能在概念层次存在耦合,而非实现层次。这与”按接口编程“可以说是英雄所见略同。

    (3)替换原则,一个从基类派生的类应该支持基类的所有行为。让使用者甚至无法知道是否存在派生类。因为所有这样的派生类都是彼此可以互换的,从而对类型进行了很好的封装。

    (4)封装变化原则,在类中封装变化。

        抽象类和接口两种获得多态性的机制之间的区别   :(1)抽象类允许有公共的状态和行为。(2)抽象类可以看成一种聚集相关实体的方式。其关注点是如何设计这些具体的实体(派生类),从而可以以同样的方式使用它们。也就是说,如何保存这些实现并封装起来。而为了使用接口,设计时应问的是:”这些东西如果要以相同的方式使用,必须都有什么样的公共接口?“接口的关注点是要使用这些派生、实现的对象。也就是说,服务对象应该有什么样的接口,才能最好地服务于背景、控制对象?如果使用对象要求许多不同类型的对象(即多个抽象),可以为每种类型设置一个接口。而结果将是比抽象更加简洁的接口。

    (5)理性怀疑原则。小心过分依赖模式。


十一、.共性与可变性分析:

         考察软件开发中最大的问题之一:处理问题域中的变化。运用分析矩阵来分析考察问题的主要变化的部分 ,它是决策表的一个简单变形,对于理解和协调概念中的变化很有帮助。矩阵分析的方法步骤如下:

      (1)找到某种特定情况中最重要的特性,并用矩阵将它们组织起来。用特性所表示的概念为每个特性标记。

      (2)继续处理其他情况,按需要扩展这个矩阵。处理每一情况时应该独立于其它情况,按需要扩展这个矩阵。处理每一情况时应该独立于其它情况。

      (3)用新的概念扩展该分析矩阵,

      (4)用行发现规则。

      (5)用列发现特定情况。

      (6)从这种分析中确定模式。

      (7)得到高层设计。

     例子:

扩展分析矩阵
  美国销售 加拿大销售 德国销售
计算运费 按照UPS费率 按照联邦快递费率 按照德国货运公司费率
验证地址 使用美国邮政规则 使用加拿大邮政规则 使用德国邮政规则
计算税额 使用美国和当地税收规则 使用GST和PST 使用德国增值税
金额 美元 加拿大元 欧元
日期 mm/dd/yyyy mm/dd/yyyy mm/dd/yyyyy
最大重量     30千克
       


十二、学习模式的过程中,寻找以下约束因素和概念会有所帮助

  • 这个模式隐藏了什么实现?这样我们就可以修改它
  • 这个模式如何使用共性和可变性分析?这有助于你找到共性。
  • 这个模式中如何将问题域分解为多个责任?这可以更容易地按责任进行分解。
  • 这个模式如何指定对象之间的关系?这将提供这些对象的约束因素的信息。
  • 这个模式本身怎样成为从背景设计的微观实例?这使我们能够更好地理解为什么这个模式是优秀设计。

     










   

猜你喜欢

转载自blog.csdn.net/eric_XJJ/article/details/8654400