目录 start
目录 end
|2018-06-23| 码云 | CSDN | OSChina
开发思想
有关开发的理论性思想,编写,测试,部署等
抽象
稍微注意一下就会发现: 抽象层次越高,接口的语意就越模糊,适用的范围就越广,到最后就会变成数学模型或者概念。
但是抽象成数学模型和算法通常是可遇而不可求的, 这种情况下,我们需要退而求其次,试图抽象成若干个正交的概念,来降低复杂度。
你在处理x轴相关的事情时,不用考虑其他的y和z 相关的东西,因为你知道他们不会受到影响, 这样问题的复杂度就从3维一下子下降到1维!更容易把握了。
如果你说了,我的整个系统还没法抽象成正交的概念, 那只好再退一步,在局部使用接口。
其实 一组定义良好的接口一定是正交的,不然的话接口之间的依赖就会让实现非常麻烦。
在著名的《设计模式》一书中,其实在反复强调一点: 发现变化并且封装变化,针对接口编程而不是实现编程。 很多人看书是只关注具体的模式,而忽略了模式的本质目的。
抽象能力的高低,很大程度上反映了一个程序员的能力的高低
- 计算机科学中抽象的好处与问题—伪共享实例分析
计算机科学中的任何问题都可以通过加上一层间接层来解决,这是很正确的,但是也正是因为一层一层的抽象和包装,导致出了问题后很难定位,你都不知道问题究竟是出现在哪一层。所以要想提高技术水平不仅要知其然(看得见最顶层的包装)也要知其所以然(看得见底层的包装),每一层如果都懂或者说了解一些,那么出了问题很大程度上都可以凭直觉定位,即使不能凭直觉也可以通过各种手段debug,只会最顶层的抽象很多时候就只能望bug兴叹了。
命令式编程和响应式编程
响应式编程
ReactiveX
组合异步的序列 设计模式是 观察者模式的扩展, 数据结构是序列串流, 避免了并发, 是非阻塞的
数据流驱动
异步
- 非阻塞
- 不是 (同步非阻塞 : 当时不阻塞后续回调) 而是异步
多路复用
面向过程
只有数据和函数, 使用函数改变数据状态
面向对象
OO Object Oriented
参考博客: 再见面向对象编程?
OOP
维基 OOP | 中文版
面向过程和面向对象的对比
示例 把大象塞进冰箱:
面向过程, 冰箱开门(冰箱) 冰箱装进(冰箱, 大象) 冰箱关门(冰箱) 面向对象 冰箱.开门().装进(大象).关门()
- 面向过程
- 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
- 缺点:没有面向对象易维护、易复用、易扩展
- 面向对象
- 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
- 缺点:性能比面向过程低
DDD 领域驱动设计
领域驱动设计(DDD:Domain-Driven Design)入门贴
领域驱动设计 软件核心复杂性应对之道 Eric J. Evans 在线阅读 领域驱动设计精简版
参考博客 | 讨论 | 基础
参考博客: 危险的DDD聚合根 初步感受是DDD禁不起变化, 必须要在起初就设计好一个完备的体系 参考博客: DDD应用的思考提出了关于领域设计的困惑
聚合
聚合根的修改行为应该属于聚合根实体对象自己,用聚合根行为守护其内部状态的一致性是DDD设计核心,如果聚合根内部的状态直接暴露给外界(通过领域服务)任意修改,那么会导致状态变化混乱,难以调试和跟踪。
参考实践项目
enodeC#实现
数据的操作
CURD
CQRS
www.cqrs.nuCQRS Guides
event-sourcing| 中文版 微软关于azure的技术性文档
event-sourcing-in-practice 参考博客: CQRS & Event Sourcing
参考博客: 领域驱动设计的实践 – CQRS & Event Sourcing 图文并茂的讲解CQRS思想
eventapisJava实现的CQRS
CQRS journey 微软团队的项目
组件模型
SOA
参考博客: SOA面向服务架构
Spring Web 应用的最大败笔
- 传统意义上的SOA 内部封装的是数据表的DTO 也被称为 失血模型,贫血模型, 从而导致SOA服务内部腐烂堵塞,违背SOA自治和可用性等原则约束
- 我现在使用Java的SpringMVC进行开发的东西, MVC架构, 然后JavaBean, Dao层或者JPA的Repository, Service层, Controller层, 而且还使用了好几年了
- Web层负责处理用户输入,并返回正确的响应返回给用户。 web层与服务层通信。
- 服务层作为一个事务边界。它也负责授权和包含我们的应用程序的业务逻辑。服务层管理的域模型对象,并与其他服务和存储库层进行通信。
- 存储库/数据访问层负责与所使用的数据的存储进行通信。
- 正如这个毕业设计的项目 Graduate, 显然的都具有如上提到的各种缺陷,
- 每一个 DTO 只具有属性, 而没有方法, 一个DTO就要对应一个服务, 服务之间再相互注入, 就会有很有依赖, 甚至循环依赖
MSA
微服务
参考博客: SOA 与 MSA(微服务架构) 码农翻身:从SOA到微服务
微服务 MSA
Other
国际化的配置
- 将配置文件按语言分别配置
- 然后在加载时设定语言的配置, 然后加载对应文件夹下的配置文件
设计软件的方法
契约式设计
Design by Contract (Dbc)
百度百科解释
编程习惯
优先使用组合而不是继承, 继承破坏了封装性, 因为父类的很多细节对子类是可见的, 父类的变化可能极大的影响子类
面向接口编程, 而不是实现编程
接口定义
- 先有统一的接口定义规范,然后有AOP实现。先有思想再有技术。
- 现在知道为什么要返回统一的一个ResultBean了:
日志规范
异常处理
- 所以,我对开发人员的要求就是,绝大部分场景,不允许捕获异常,不要乱加空判断。只有明显不需要关心的异常,如关闭资源的时候的io异常,可以捕获然后什么都不干,其他时候,不允许捕获异常,都抛出去,到controller处理。空判断大部分时候不需要,你如果写了空判断,你就必须测试为空和不为空二种场景,要么就不要写空判断。
- 强调,有些空判断是要的,如:参数是用户输入的情况下。但是,大部分场景是不需要的(我们的IT系统里面,一半以上不需要),如参数是其它系统传过来,或者其他地方获取的传过来的,99.99%都不会为空,你判断来干嘛?就抛一个空指针到前台怎么啦?何况基本上不会出现。
- 总结:
- 开发组长定义好异常,异常继承RuntimeException。
- 不允许开发人员捕获异常。(异常上对开发人员就这点要求!异常都抛出到controller上用AOP处理)
- 后台(如队列等)异常一定要有通知机制,要第一时间知道异常。
- 少加空判断,加了空判断就要测试为空的场景!
代码质量分析
- 测试对代码的覆盖率
- 代码的格式是否清晰,有助于差异比较和可读性
- 是否很可能会出现NPE
- 是否忘记了域对象中的equals和hashCode方法
Checkstyle
FindBugs
阿里巴巴的代码检查
配置文件
千万业务代码里面不要和读取配置的代码耦合在一起。切记!