软件框架设计的艺术----读书总结

总结

软件开发的艺术

理想主义,经验主义和无绪

文艺复兴时期,现代科学产生了两个重量级理论: 理性主义和经验主义。java

理性主义认为理智是信息的首要来源。给出一个假设,只要经过思考就能理解和描述这个世界,如著名的伽利略自由落体实验。mysql

经验主义则认为人类对世界认识的主要来源是经验。程序员

咱们开一辆车,没必要知道其内部实现细节。web

若是孤立地基于两种极端的方式来观察世界都是片面的。对大多数人来讲,懵懂无知是一种生活方式,也是理性主义和经验主义结合在一块儿的结果。今天的程序开发和软件工程方法也是如此。sql

软件的演变过程

  1. 上世纪40年度,用机器语言, 那时debug的时候可能还得带一个扳手
  2. 而后 FORTRAN ,他容许程序员只关心数学公式而不是内部机器内部实现 ---- 经验主义
  3. 而后COBOL来了, 他简化了数据库的操做 ---- 经验主义
  4. 固然同时期lisp出现了,他更强调纯粹的数学模型---理性主义
  5. 而后cpp, 而后java

咱们能够发如今软件演变的过程当中, 理性主义几乎已无存身之处。数据库

由于软件的趋势是: 程序员在能够不深刻了解不少内容的状况下就能够写出很是好的代码。编程

大型软件是如何开发的

现状: 开发团队每每直接复用现有的一些软件框架,彻底不重视这些重量级的框架是否超过咱们的须要的。现代软件都是基于大型组件的方式进行组装的。 我要一个web服务器就装一个tomocat, 要一个数据库就装个mysql。 这彻底是一种推土机式的开发方式,无论你的组件有多大, 总会找到合适的推土机把他推上去。 运行效率太差 就 加内存,搞服务器集群,windows

这种方法是好仍是坏呢?实际上绝大多数公司已经用这种方式了。api

由于推土机式的工做方式可使你在不关注内部细节的状况下,也能够获得不错的结果。 咱们能够在不了解汽车原理的状况下,能够把汽车开得很好。 在写win32程序时候,也没必要了解系统是怎么实现。 咱们只须要关注windows 系统API, 以及这些API的功能。缓存

理解一个系统有两个层面:

  1. 浅层理解: 紧限于了解使用方法
  2. 深层理解: 理解其原理

而在软件开发中, 通常只要作到浅层理解就能够了。

咱们说明软件开发实际上是一个经验的积累过程,而且能够是复用前人的经验积累的。

设计API的动力之源

好的API可使功能的使用者聚焦在使用层面而不是其内部细节

为何须要好的API:

  1. 分布式开发: 一般咱们一个程序部署由一我的能独立完成的
  2. 模块化应用程序 : 咱们的程序是分模块的,不一样模块的交互就是用API
  3. 交流互通才是一切: 模块之间相互依赖
  4. 开发第一个版本一般比较容易

设计API过程当中遇到的最大问题--- 不断变化的需求

一个软件开发的生命周期:

  1. 初版吧老是很是漂亮的
  2. 快乐老是短暂的
  3. 软件熵不断增长
  4. 天哪 千万不要动他
  5. 从新开发一个版本吧。

变化是万恶之源。

那么如何才能设计好的API

评价API好坏的标准

第一步先确认什么才叫好。

不少人认为所谓的API,不过是类和方法。可是这是比较片面的。

强调一点, 咱们为何须要开发好的API:咱们但愿可以将大块的构建模块,”无绪“地集合成应用程序。

那么如何评价一个API的质量: 漂亮? 可是评价漂亮的标准是很主观的。咱们应该设计易于使用、广为接受且富有成效的API。咱们能够有一下几个方面来衡量一个API的好坏。

  1. 可理解性: 每一个人的世界观都会限制本身d视野,因此对于一个优秀的API来讲,他涉及的概念都要在用户的可理解范围以内, 即便有新的概念也应该是渐进式的。
  2. 一致性: 向下维持兼容
  3. 可见性: 最好提供一个入口用来做为用户API的起点。 为何你们都喜欢开源,由于开源不少东西网上能够直接拷贝。
  4. 简单的任务应该有简单的方案: 因此API应该是分层的。
  5. 保护投资: 善待API的用户。 尽可能想办法让API漂亮点。如方法名,如结构等。 在发布初版以前这些都是很是合适的。可是发完初版之后咱们要保证我吗的代码改动不会影响正在运行的代码了。

实现API的步骤

第二步弄清楚写API的步骤

写一个API有三个步骤:用例, 场景, 文档。

一个用例就是一种用法的描述,他指出用户可能要面临的问题,而这个问题不是一个具体的问题,而是不少问题的抽象。

举个例子

用例: 设计一个数据库管理器,他的功能是注册JDBC驱动。

场景:对用例的回答。咱们把API要描述的每个功能下列出来:

  1. 注册有一个JDBC能够写一个可以描述驱动的XML, 有格式
  2. 这个XML放置在DataBase/JDBCDrivers目录下
  3. 用URL来表示驱动地址

注意一些设计原则

第三步 学习一些设计原则和通用方法

  1. 只公开你要公开的内容
  2. 面向接口而非实现进行编程
  3. 模块化架构
  4. 声明式编程

只公开你要公开的内容

咱们所设计的API都会被可能误用。几乎全部的API设计者都会有这样的共识:一我的API设计的时间越长,他设计的API公开的内容会越少。

设计API的几种方法:

1. 方法优于字段

这个不用说了。 geter setter。 这样作会有不少改变的余地。 如计算、转换、校验、覆盖

2.工厂方法优于构造函数

工厂方法会带来很大的灵活性,三个好处:

  1. 返回不必定是声明的类型能够是子类
  2. 构造的对象能够被缓存
  3. 同步的控制。 能够都构造对象先后的代码进行控制。
3. 让全部的内容都不可改变

一般状况下, 在设计一个类的时候,若是不考虑让拥有子类,那就不该该让这个类被继承。 用final 来修饰。 还有些其余方案来: 不公开构造函数转而提供工厂方法。把大部分方法变为final或者private

4. 避免滥用setter方法

一个宝贵的教训: 如无必要,绝对不要再正式的API中声明setter方法。

5. 尽量经过友元的方式来公开功能

在java中,所谓的友元就是用默认的package方式访问,即容许同一个包内的代码进行访问。

有个实际的例子

6. 赋予对象建立者更多的权利
7. 避免暴露深层次继承

避免深层次的继承,定义程序的接口,并让用户来实现这些接口。 若是一个类继承了某个类或者接口,那么就能够做为响应的类或接口被使用。

如在swing中, frame间接继承了compoment,这样就表示全部使用compoment的地方,均可以使用frame. 实际上frame继承 compoment是为了复用compoment的代码。这是一种典型的面向对象的复用的误用。 因此若是发现继承提醒超过2层,必定要想清楚“我是在设计API仍是在复用代码”,若是是后者,则作好子类化准备。

面向接口而非实现进行编程

本质上讲,这个原则倡导的是,当咱们写一个函数或一个方法时,咱们应该引用相应的接口,而不是具体的实现类。接口提供了很是优秀的抽象概括,让咱们的开发工做变得容易不少。 让API的使用者和API的实现者解耦出来。

模块化架构

随着软件规模的增大以及功能的复杂性增长。只要代码开始访问其余无关模块的内容,那么架构的退化不可避免。模块化能有效变缓这种退化。

模块化的目的很是简单,就是要实现程序中各个组成部分的松耦合。若是两个模块是独立的,那两个模块就不须要知道对方的存在。若是两个模块要交互,那么他们应该经过具备良好定义的接口来进行交互。

声明式编程

声明式编程的基本思路, 不是让API用户一步一步告诉程序如何作,而只是须要告诉程序他们要的结果,而后交给API去完成。声明式编程的好处是能在较高的抽象层次来定义操做。

好比写一个资源管理API: API的使用者很容易找到一个方法去注册一个功能,运行一下成功了,而后再也不往下继续找注销的方法了。 声明式编程就是解决这个问题的一剂良药: 开发人员只须要声明注册什么,响应的注销和清理由系统完成。

极端的意见有害无益

最后提醒一点,任何极端的想法都是有害的,在软件框架设计中也同样, 有如下单不只限几个点:

  1. API必须是漂亮的
  2. API必须是正确的: 有时候易用性和正确性还重要。好比巨大文件
  3. API应该尽可能简单
  4. API必须是高性能
  5. API必须绝对兼容
  6. API必须是对称的

团队协做

现代的大型工程不多是有一我的单独开发完成的,因此团队协做很是重要。一下几个点能很好帮助在大型软件工做中完成好的API设:

  1. 在提交代码时候进行代码审核
  2. 为API提供文档
  3. 尽职尽责的监控者
  4. 接受API的补丁

以上很是简单,可是在外面日常工做中缺乏的就是执行。

相关文章
相关标签/搜索