出了本练内功的书:《完美软件开发:方法与逻辑》

首先说下什么叫“完美软件开发”,想象一下,完美的圆在现实中是不存在的,现实中的圆只能是对完美的圆的回归,但完美的圆描述了圆的构成规则,完美软件开发意义与此相同,它试图描述软件开发的规则和铁律。但既然现实中不存在,探讨完美状态又有神马意思?好,那我们再来看一个完美状态:

牛顿第一定律说:任何一个物体在不受任何外力或受到的力平衡时,总保持匀速直线运动或静止状态,直到有作用在它上面的外力迫使它改变这种状态为止。

这显然也是一个完美状态或者说理想状态,现实中也是不存在的,那这东西又有神马意义?

个人感觉探讨软件开发的完美状态,就和探讨软件中的牛顿定律一样,虽然它现实中不存在,但对现实却有着极大的指导意义。单纯想做个高手,比如Android高手什么的是不太用的上这种探讨、这种书的,但要想把握下全局,这种探讨、这种书就有点意义了。

 

那怎么去探讨这种完美状态?

 

这类书,包括《人月神话》往往是用归纳法写出来的。但这样一来就会先天有种限制:一个人的眼界经历是有限制的,而软件世界其实无限宽广,编译器和信息管理系统的差别可能比人和猪的差别还大。所以一用归纳法,又说不清楚自己结论的边界,书就很容易偏颇。所以这本书用演绎法来写,用逻辑链来推导,看过三体的可能知道黑暗森林定律是咋整出来的,但把逻辑链用在这类书里,恐怕还很少人这么干。

 

看几条逻辑链。这书预设了几个前提,所有逻辑链都基于这几个前提。

  • 软件是一种固化的思维
  • 意识指导行动
  • 项目所能耗费的资源是有限的
  • 重复做同样的工作会降低效率

 下面列几条书里的逻辑链。

关于量化管理的:

软件是一种固化的思维 →思维的本质是概念和逻辑 → 概念和逻辑无法直接度量和精确度量 → 度量过程中需要很多的主观判断 → 以目标为导向的,以个人为中心的量化管理(相关的激励和惩罚)将崩溃 → 参照无歧义数据(函数复杂度等)的判断将成为程序员评价中的辅助手段 

 

关于流程尺度:

软件是一种固化的思维→思维固化本质上不可能是例行公事 → 现场的人需要较大的自主空间 →软件的流程粒度需要比较大,而不能规定工作细节,手册化。→ 可以把流程等价于一种打断,从这个尺度上可以度量当前流程的程度是否过于繁重。

 

关于开发模型的选择:

重复做同样的工作会降低效率→预先没有对既定问题的分析和准备,会导致同样的工作做多遍→ 纯粹的迭代会导致某些预先可以发现的问题得不到处理,进而导致不必要的重复,最终会降低组织总体生产效能

 

关于在何处终结需求开发:

项目所能耗费的资源是有限的  → 需求如果无限扩张,会造成以有限资源做无限工作的局面,最终导致忙中出错 →  在广度上,由于软件的应用环境处在变动之中,导致需求天生有越来越多的趋势。→ 在广度上,对不做那些需求要有清楚定义。→在深度上,需求的明确是一渐进的过程。 指望在初期某一截止时间点,澄清所有需求是不现实的。但能够澄清的,没有澄清却又导致效能降低。→ 在深度上,要使需求开发的细致程度有所定义

 

关于设计中的正交:

 

软件是一种固化的思维 → 思维的固化体现为概念和逻辑的固化 → 为保证简单性,逻辑要尽可能的少 →概念要尽可能正交

 

当然只有这些逻辑链是不够的,还需要补充例子,对逻辑链的具体含义进行阐释。

就拿最后一条逻辑链来说,你如果相信它是对的,再去看设计和代码,就会看出许多新问题,比如:Robert C.Martin在《敏捷软件开发:原则、方法与实践》里给出过一个关于门的例子。

 

Robert C.Martin的例子说:在安全系统中,有一些门,这些门可以被加载和解锁,并且知道自己是开着还是关着。

class Door

{

public: 

virtual void Lock() =0;

virtual void Unlock() =0;

virtual bool IsDoorOpen() =0;

};

接下来,一种更高级的门出现了,这种门如果开着的时间过长,就会发警报,这种门被称为TimedDoor

因为要定时出发某些事件,所以TimedDoor要用到定时器,而定时器的基本创建机制是:

class TimerClient

{

public:

virtual void TimeOut()=0;

};

class Timer

{

public:

void Register(int timeout, TimerClient* client);

};

任何TimerClient都可以向Timer注册自己,而Timer则会按照指定的时间间隔来调用TimerClientTimeOut()

 

到现在为止,TimerTimeClientDoor在概念上是正交的,没什么问题。

 

接下来,为了使TimedDoor具有定时发警报的功能,这三个概念要产生交互了。

 

处理方法可以有很多,第一种方法DoorTimeClient继承,这种方法的正交程度最不好,接触面过大,像Robert C.Martin在书里说的,很多Door根本和定时不定时没有关系,但一旦让DoorTimerClient继承,那就不管什么门都有了定时的特征,这种关联毫无道理。

第二种方法是让TimedDoor分别继承TimerClientDoor(多重继承)。Robert C.Martin认为自己会优选这个方式。

从正交的角度看,在这种方式下,TimedDoor只和与自己有关的部分产生关联,正交性已经非常好了。

如果仔细想想,就会发现Robert C.Martin的第二种方法其实还是有问题。

门是否计时报警是一个功能,是否能录像也是一个功能,是否能自动发消息也是一个功能。

这些功能甚至可能是动态配置的,如果都用多重继承来解决,那会衍生出各种各样的对象,如:VideoDoorTimeVideoDoorMessageDoorTimeVideoMessageDoor等等。这好像并不是什么好事。

这意味着正交的程度也许还是可以提升。

如果不让自己的思维局限于所有东西必须都是对象,那么就可以找到其他解法。我们可以认为定时报警功能是门的可组合部分,是使用关系而不是继承关系。也就是说,并不认为应该独立存在着TimerClient这样的类,而认为这是一种偶然的组合。否则的话,XXClient这样的类会漫天飞。想象一下,门、马桶等都可以是TimerClient,也可以是MotorClient

 

上面就是书中部分对正交的讨论和分析,这类讨论和分析会针对几乎所有主要软件开发的领域展开。好处是似乎可以多想到,多看到一些别人没看到的东西,坏处是这样一来很多地方会有点抽象。所以总的来看,这书适合愿意琢磨事,愿意思考本质问题的人,不适合喜欢做事,不喜欢思考的人。

 

除了用演绎法来重新解构软件开发之外,这书还做了的一件事情是:探讨软件开发各个领域间的关系。做软件的都知道,管理好≠项目结果好,流程好≠项目结果好,开发模型≠好项目结果好,设计编码好≠项目结果好。但一实际操作起来,负责不同事情的人,总是会起冲突,做流程的和做现场编码的总是捏不到一起去,因为不同部分间一方面是配合协作,一方面则是共同竞争有限资源。而为了配合好,显然任何一部分都要停在某个程度上,这个也比较抽象,是这个书另一个探讨的地方。

再写下去就太长了,书的说明就此打住。

最后说两句其他的。

看过我别的文章的人,应该大致知道,我比较喜欢写本质的东西,喜欢用一种哲学思辨的方法来看待东西。从立刻有用的角度看,其实这类文章和书挺差的。但我有时候想《人月神话》也不是立刻有用,也还许多人看,所以可能这种对本质的思考还是有用的吧,所以就还是坚持把书写出来了。

接下来会写点怎么把书写出来的东西,算是给想写书的做点分享。

--------------------------------------------------------------

 

理想流 + 软件 = 《完美软件开发:方法与逻辑》
理想流 + 人生 = ??
理想流 + 管理 = ??
理想流 = 以概念和逻辑推演本质,追求真理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot后台接收前端Date类型

From: https://my.oschina.net/zicheng/blog/2963117 这个问题不是专门针对Springboot的,Springmvc也同样适用于这一个问题。 昨的是Springboot前后端分离的项目,今天和前端对接口发现前端的请求走不到后台,检查了请求什么的都没有问题&…

关于jTopo的引用

jTopo是一款 2 D和3D模型展示的插件,不过目前文档不是很齐全,刚开始看的时候就有点懵了,因为你在网上很难找到jTopo的资料。下面我就介绍一下jTopo 的引用吧。 1、首先在官网上下载到jTopo的包,地址:http://www.jtopo.…

mysql重置root密码方法

2019独角兽企业重金招聘Python工程师标准>>> 1. 先关闭mysqld 2. 运行: mysqld_safe --skip-grant-tables 3. 另开一个窗口,用 mysql -uroot 登录mysql,执行 UPDATE mysql.user SET PasswordPASSWORD(你的密码) WHERE User…

插入排序之C++实现

描述 插入排序是一种简单直观的排序算法。它的基本思想是将一个待排序的数据序列分为已排序和未排序两部分,每次从未排序序列中取出一个元素,然后将它插入到已排序序列的适当位置,直到所有元素都插入完毕,即完成排序。 实现思路…

spring boot使用logback实现多环境日志配置

From: https://blog.csdn.net/vitech/article/details/53812137 软件生存周期中,涉及代码运行的环节有编码、测试和维护阶段,而一套成熟的代码,在此三个阶段,数据库、日志路径、日志级别、线程池大小等配置一般会不一样。作为开发…

IOT(Index Organized Table)

我们知道一般的表都以堆(heap)的形式来组织的,这是无序的组织方式。Oracle还提供了一种有序的表,它就是索引组织表,简称IOT表。IOT表上必须要有主键,而IOT表本身不对应segment,表里所有的数据都存放在主键所在的索引的…

C++中的 :: 用法

::是运算符中等级最高的,它分为三种:1)global scope(全局作用域符),用法(::name)2)class scope(类作用域符),用法(class::name)3)namespace scope(命名空间作用域符),用法(namespace…

Spring Boot SLF4J日志实例

From: https://blog.csdn.net/lxh18682851338/article/details/78560295 默认情况下,SLF4j日志记录包含在Spring Boot Web应用程序中,只需要启用它就可以了。 注意:查看此Spring Boot Logback XML模板以了解默认的日志记录模式和配置。 SLF4…

java 反取字符串

public class demo2 {/*** 2 : 将字符串反取出来 新中国好 好国中新*/public static void main(String[] args) {String s "新中国好";s reverse1(s);System.out.println("方法一:" s);s reverse2(s);System.out.println("方法二…

测试使用wiz来发布blog

晚上尝试了下用wiz写随笔并发布,貌似成功了,虽然操作体验和方便性上不如word,但起码它集成了这个简单的功能可以让我用:如果能让我自动新建blog文章并自动定时更新发布就完美了。2013年7月5日19:31:04发现最近开始慢慢重度使用wiz…

Spring在Java Filter注入Bean为Null的问题解决

From: https://www.cnblogs.com/EasonJim/p/7666009.html 在Spring的自动注入中普通的POJO类都可以使用Autowired进行自动注入,但是除了两类:Filter和Servlet无法使用自动注入属性。(因为这两个归Web容器管理)可以用init&#xf…

关于工作的选择之软件开发还是软件维护的建议

今天是周六休息,好可爱的双休日啊。下周一出差去四平,要和我们单位另外2名工程师一起去给四平的一个公司安装调试一个机房的设备,大概需要三天的时间吧。昨天晚上去个朋友家做客,朋友他侄子大学是学计算机软件的,今年刚…

Mybatis:resultMap的使用总结

From: https://www.cnblogs.com/kenhome/p/7764398.html Mybatis的介绍以及使用:http://www.mybatis.org/mybatis-3/zh/index.html resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个…

NSOperation, NSOperationQueue 原理探析

通过GNUstep的Foundation来尝试探索下NSOperation,NSOperationQueue 示例程序 写一个简单的程序 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self configurationQueue]; LDNSOperatio…

MyBatis总结六:resultMap详解(包含多表查询)

From: https://www.cnblogs.com/Alex-zqzy/p/9296039.html 简介:   MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性&a…

object c 快速构建对象

__block NSNumber *capacity (0);

mysql语句添加索引

1.PRIMARY KEY(主键索引) mysql>ALTER TABLE table_name ADD PRIMARY KEY ( column ) 2.UNIQUE(唯一索引) mysql>ALTER TABLE table_name ADD UNIQUE (column ) 3.INDEX(普通索引) mysql>ALTER TABLE table…

基于beego一键创建RESTFul应用

2019独角兽企业重金招聘Python工程师标准>>> API应用开发入门 Go是非常适合用来开发API应用的,而且我认为也是Go相对于其他动态语言的最大优势应用。beego在开发API应用方面提供了非常强大和快速的工具,方便用户快速的建立API应用原型&#…

MyBatis中in的使用

From: https://www.cnblogs.com/w-bb/articles/6378031.html foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。 foreach元素的属性主要有 item,index,collection,open,separator,close…

JS 限制input框的输入字数,并提示可输入字数

<!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title>限制文件字数字</title> </head> <body> <span class"span">备注信息</br><span id"stay" sty…