指尖世界

分享的乐趣

敏捷技能修炼

类别: 动态 更新时间: 2016-02-02

[摘要:豆瓣地点:http://book.douban.com/subject/11614307/ PDF:http://pan.百度.com/s/1c0L0sUW 第一局部 最症结的小舵板 第1章 企图导背编程 从上至下的一步步完成,]

豆瓣地址:http://book.douban.com/subject/11614307/
PDF:http://pan.baidu.com/s/1c0L0sUW

这里写图片描述


第一部分 最关键的小舵板

第1章 意图导向编程

从上至下的一步步实现,先声明好方法,一步步为了最重编译通过而实现。

优点:

  • 更加内聚(职责单一)
  • 更加可读和清晰
  • 更易于调试
  • 更易于重构和优化,所以只做最少设计,满足当前需要
  • 更易于单元测试
  • 模式更容易应用到代码中
  • 创建的方法可以容易地从一个类移动到另一个类
  • 代码更易于维护

第2章 分离构造和使用

创建类 和 引用类分离开来

旧的方式:

    public class BusinessObject {
        public void actionMethod() {
            // Other things
            Service myServiceObject = new Service();
            myServiceObject.doService();
            // Other things
        }
    }

如果创建Service对象的方式修改了,此时就需要修改BusinessObject

创建者:关心这个对象是什么
使用者:关心这个对象能做什么

方案1(通过依赖注入方式):

    public class BusinessObject {

        private Service myServiceObject;

        public BusinessObject(Service aService) {
            myServiceObject = aService;
        }
        public void actionMethod() {
            // Other things
            myServiceObject.doService();
            // Other things
        }
    }

方案2(通过工厂方式):

    public class BusinessObject {

        private Service myServiceObject;

        public BusinessObject() {
            myServiceObject = ServiceFactory.getService();
        }
        public void actionMethod() {
            // Other things
            myServiceObject.doService();
            // Other things
        }
    }
public class ServiceFactory {
        public static Service getService() {
            if (someCondition) {
                return new ServiceImpl1();
            } else {
                return new ServiceImpl2();    
            }

        }
    }
interface Service{
        void doService();
    }
class ServiceImpl1 implements Service {
        void doService(){}
    }
 class ServiceImpl2 implements Service {
        void doService(){}
    }

方案3(类似单例):
如果发生更复杂的变化,则可以变更为方案2

    public class BusinessObject {

        private Service myServiceObject;

        public BusinessObject() {
            myServiceObject = Service.getInstance();
        }
        public void actionMethod() {
            // Other things
            myServiceObject.doService();
            // Other things
        }
    }
class Service{
        private Service(){
            // any needed construction behavior
        }

        public static Service getInstance(){
            return new Service();
        }

        public void doService() {
            // implementation here
        }
    }

第3章 代码未动,测试先行

步骤如下:

  1. 设计测试
  2. 编写测试用例
  3. 编写代码
  4. 执行测试用例

第4章 Shalloway法则和Shalloway原则

冗余的种类:

  • 复制和粘贴
  • “魔法”数字
  • 其他类型
    • 保存到文件
    • 保存到数据库
    • 冗余信息
    • 冗余实现
    • 一个概念(数据,算法,带啊妈)

在修改代码的时候,如果对一处做了修改,那么你必须在其他地方也做出相应的改动,这就是冗余。

使用模式减少冗余:

  • 策略(Strategy)模式处理多种不同的算法
  • 桥接(Bridge)模式处理多种代码实现之间的衔接
  • 模版(Template Method)模式处理同一种流程下的不同代码实现方案
  • 装饰器(Decorator)模式时一个流程中可以加入不同的额外步骤

第5章 封装

通过get()封装,内部使用也通过get()

设计时要考虑可能产生的变化,并把可变的因素封装起来。

第6章 面向接口的设计

  • 一个对象可调用方法的集合
  • 一种协议,比如文件传输协议或者邮件传输协议
  • 一种程序接口,比如web服务

三大定律:

  • 接口的实现应当正确完成它的方法宣称的事情
  • 接口的实现不得损害系统
  • 实现不能正确完成它的职责,必须通知相关的调用者

避免过早采用继承体系

第7章 验收测试驱动开发

针对业务逻辑的测试可以通过多种方法来实现:

  • 通过用户界面创建一个调用业务员规则的事务
  • 开发一个用户界面,并通过这个界面直接调用业务规则
  • 通过某种语言的单元测试框架来实现测试
  • 通过自动化的测试用例直接与业务规则模块进行交互

第一部分 最关键的小舵板

第8章 避免过渡设计或设计不足

  • 避免过渡设计或设计不足
  • 把复杂度和返工最小化
  • 永远不要把代码变得更糟(编码的希波拉底誓言)
  • 仅在有目的的情况下降低代码质量
  • 使代码容易修改,足够健壮,适应变化并安全可靠

第9章 持续集成

  • 建立源代码分支
  • 将主干内容合并回分支
  • 测试驱动开发与合并的成本
  • 持续集成
  • 持续集成服务器

小结:

  • 减少合并代码到主干的时间消耗
  • 通过尽早地使团队成员所完成的工作被大家所知道来提高团队内部的沟通。这样做使大家有机会观察到刚刚完成的代码库改动并对其作出评价

第三部分 设计问题

第10章 共性和可变性分析

“分析矩阵”

方法:

  1. 选择一个将要描述的特定用例
  2. 列出完成这个用例所需要的步骤,把第一步放在最上面,后面的步骤依次排列
  3. 在每个步骤的左边创建一列
  4. 把每一个步骤的概念和意义卸载左边的列里

例子:
这里写图片描述

小结:
把不同的实现封装起来

第11章 以开放关闭原则为目标的重构

软件中的实体(类,模块,函数等)应当满足这样的要求:对开展使开发的,对修改是关闭的。

第12章 需求与功能接口

迪米特法则(最少知识原则)

例子:

    public class City {
        public String name();
        public City twinCity();
        public Street[] streets();
    }

    public class Street {
        public String name();
        public House[] houses();
    }

    public class House {
        public int number();
        public Color color();
    }

我们想知道在Main Street 1374号房屋的颜色,则接下来我们很有可能这样写:

    public Foo() {
        Color c = Seattle.streets()["Main"].houses()[1374].color();
    }

推荐做法:

    public Foo() {
        Color c = Seattle.ColorOfHouseInStreet("Main", 1374);
    }

小结:
接口通常是指由哪些服务可以提供,它表明服务提供者的能力。
直接反应客户端需要的接口,就这是外观模式 或者对简单点的情况采用适配器模式

第13章 何时以及如何使用继承

优先委托,策略模式
一个类必须只能因为一个原因发生改动。


第四部分 附录

附录A 统一建模语言概览

类图:
类之间的关系可能为以下几种类型:

  • 当一个类是另一个类的”一种”(kind of)时:是”is-a”关系
  • 当一个类与另一个类是写作关系时,
    • 当一个类”包含”(contains)另一个类时:是”has-a”关系
    • 当一个类”用到”(use)另一个类时:是”uses-a”关系
  • 一个类”创建”(creates)另一个类

聚合关系”has-a”:
这里写图片描述
不管有没有包含Aircraft类,Airport类都被称为Airport。

组合和使用的关系
这里写图片描述
car类如果没有Engine类就不是完整的。只要有汽车的地方,就必须包含发动机。

UML里的注释:
这里写图片描述

表明其他类所包含的信息:
这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述



感谢关注 V8指尖世界精品文库频道,v8en.com是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 V8指尖世界!