车子的个人博客

正确的事情通常都是优雅的

敏捷开发读书笔记六

18章

  • 数据库属于实现细节,应该尽可能的推迟考虑数据库.太多的应用程序跟数据库绑定在一起无法分离,就是因为一开始设计时就把数据库考虑在内了.

  • 用例:用例是一种捕获/分析系统行为的方法.用例和XP中的用户素材的概念非常相似,用例就像用稍多细节详细描述的用户素材.当前迭代中要实现用户素材的时候,这种详尽细节就是合适的.

  • 有的bug对程序员来说是很正常的,但是管理人员以及用户会对这些bug感到恐惧.并且程序会给管理人员和用户留下”危险且不稳定”的印象.

  • 过度信赖工具和过程以及低估智力和经验都是灾难的源泉.

  • 在一次迭代开始,开发人员通常会聚集在一个白版钱,一起思考这次迭代中要实现的用户素材设计.这次会话的目的是发起思考活动,并未开发人员提供一个公共的/可以依据其展开工作的智力模型,而不是为了确定设计.

19章

  • 推迟有关数据库的细节是一项不常见的/但是却很值得的实践.

  • 太多的UML图而没有验证他的代码是危险的.代码可以告诉你一些UML不能告诉你的设计的内容

  • 测试用例先于产品代码编写.

  • 多数情况下,测试以增量的方式创建,并和产品代码一同演化.

其他

目前为止还没有完成书中项目的编写,近三个周来比较痛苦.

第一周试图生读完满是代码的19张内容,然后熟悉之后在回头写代码,花了好几天只推进了一丢丢,太难了.不是第一次吃这个亏了,js权威指南和java编程思想两本书都吃过这种地方的亏,还是没长记性.第三次了,写下来,引以为戒.

纸上得来终觉浅,觉知此时要躬行.

净值

  • 主账户 :1.0732
  • 父母的养老金:1.0001
  • 我的养老及:1995
    截图;

本周操作

  • 主理财账户
    • 买入1500的货币三佳
  • 父母的养老钱
  • 买入2000稳稳地幸福

其他

没啥好些的,睡觉

投资实证2-2019-04-15

周末玩心血来潮玩了玩全面战争战锤2,结果什么也没有干,安安心心完了两天,罪过罪过.今天补上.并引以为戒.

净值

  • 主理财账户: 1.062
  • 父母养老金2019: 1.003
  • 自己的养老金: 0.9959

主理财账户

本周操作

  • 主理财账户

    • 定投买入100且慢”稳稳的幸福”策略

    • 买入100华宝油气

  • 我的要养老金

    • 买入200华宝油气

    • 买入1000货币三佳

  • 父母的养老金

    • 买入1000货币三佳

其他

  • 不跌不买,逢高减磅,不赚不出 —社保基金的策略

  • 想到什么立刻就买,是消费低效的原罪。—也谈钱

投资实证1-20190407

净值

  • 本周总净值:34863.67

  • 主理财账户净值:11538.01,1.0778

最新净值

操作

  • 买入二八轮动 1000

其他

  • E大微博

    • 记住,投资这件事千万不要用上次的经验推导下次。
      比如上次顶部没跑,就觉得要随时跑锁定利润。
      比如上次随时跑没赚钱,下次打死也不卖。
      比如上次胆子小买的少,下次疯狂加杠杆。
      如果这样做,你会非常惨。
      这条微博值500万,不信你十年后回来看

    • 各位用过去这几年的时间,能完整体会一次顶部坚决卖,下跌过程不着急买,底部区域坚定多买,上涨趋势不着急卖,这样一个完整赚大钱的过程。

  • 也谈钱

    • 开始跟投以前充分怀疑,开始跟投以后充分信任。

投资实证0-20190401

决定花点精力记录一下每周的资产情况,以及记录一些理财过程中的所想所感所学,以期能够在整理的过程中总结或者找到一些适合自己的理财脉络.
实证讲以周为周期,记录每周的投资情况和储蓄,每周末更新.此篇为0,给以后的文章打个底子.

净值

  • 上月总净值:35082.56
  • 主理财账户:10164
  • 父母养老金:2977
  • 自己养老金:995

理财净值

目标净值500w,当前进度0.7%😂

操作

其他

  • 目测不会耗费太多精力,如果精力耗费太多,就切换为每月一次.
  • 储蓄确实太少,提升收入才是首要目标.提升技术和个人能力.准备跳槽.

敏捷开发读书笔记五

command模式

类图先行
类图

templete method(模板方法)模式和strategy(中介者)模式

  • 优先使用对象组合而不是类继承(老生常谈的问题)
  • 模板方法模式和策略模式体现了继承和委托之间的区别.他们要解决的问题类似,但是模板方法模式利用继承解决问题,策略模式利用委托来解决问题

模板方法模式

类图先行
类图

策略模式

类图先行
类图

  • 模板方法和策略模式都可以用来分离高层算法和低层具体实现细节.都允许高层的算法独立于它的具体实现细节重用.

facade(外观)模式和mediator(中介者)模式

  • 这两种模式都是把某种策略施加到另一组对象上,facade模式从上面施加策略,mediator模式从下面世家策略
  • 如果策略涉及范围广泛而且课件,可以使用facade模式从上面世家策略.如果策略隐藏并且具有针对性,mediator则是更好的选择.
  • facade通常是约定的关注点,每个人都去使用facade而不关心其下隐藏的对象.mediator则对用户是隐藏的.他的策略是既成事实而非一项约定事务.

facade模式

类图先行
类图

  • facade对用户隐藏了下层的复杂性,并且与用户约定必须通过facade来操作下层的操作而不能绕过.
  • facade模式是明显且受限的施加策略.

mediator模式

类图先行
类图

  • mediator模式以隐藏且不受限的方式来施加策略.

singleton模式(单例)和monostate模式

  • singleton和monostate都有单一的含义.singleton通过将构造函数私有化来维持单一实例,monostate通过将所有字段注册为静态字段(static)来保证所有实例都是统一状态.
  • 多数情况下,这两种模式的实施代价远低于它们的表达力带来的收益.
  • sigleton强调结构上的单一性,只能创建一个实例.monostate强调行为上的单一性,所有实例操作的都是同一字段.
  • 如果希望通过派生去约束一个现存类,并且不介意他的所有调用者都必须调用instance()方法来获取访问权,那么singleton最合适的.
  • 如果希望类的单一性本质对使用者透明,或者希望使用单一对象的多态派生对象,那么monostate最合适.

singleton模式

优点:

  • 跨平台
  • 适用于任何类(只需要将构造函数私有并添加相应的static函数和变量)
  • 可以通过派生创建(可以创建一个给定类的sigleton子类)
  • 延迟求值(sigleton未使用的时候就不需要创建)

缺点:

  • 摧毁方法未定义
  • 不能继承(singleton派生的子类不是sigleton)
  • 效率问题(instance方法中的if)
  • 不透明性(使用者知道操作的是sigleton对象)

monostate模式

优点:

  • 透明性(使用者不知道操作的是monostate对象)
  • 可派生性(monostate所有的派生类都是monostate)
  • 多态性(monostate的派生类可以overwrite父类的方法)

缺点:

  • 不可转换性(普通类不能转换成monostate)
  • 效率问题
  • 内存占用(static变量,即使没有使用,也会占用内存)
  • 平台局限性

null object模式

定义一个接口,实现接口时候分为null实现和implementation实现,当出现null情况的时候,返回null实现,从而避免琐碎的判空代码.

null object的实现代价要高于它的收益.好像陷入了复杂性的badsmell?

焦虑清单

2019年已经过去了马上三个月整,对已经在进行的几件事情还比较满意,主要包括:

  • 节食和减肥,年后回来体重已然减少了10kg左右.
  • 跟老刘的读书都按时完成,没有落下进度.
  • 水滴阅读的英语坑填上了,虽然不是完全消化,也算是可以以后会去看看.

然而因为17/18两年荒废了太多,总是经常陷进焦虑之中,莫名烦躁.所以想起来把这些焦虑列举一下,搞清楚自己究竟是在焦虑什么,然后再想办法对症下药,解决问题.

关于工作/工资/技术/学习

  • 工作没有多少技术难度,技术提升空间和职位提升空间都没有,工资也低于平均水平,工作没有太多难度无法谈涨薪事宜。
  • 工作速度变慢,下班就走,担心在同事和领导的看法。
  • 按目前的状况职业生涯不明朗,不提升技术跳槽不到好公司。当前职业前景灰暗。
  • 可替代性太高,不能经受住失业。
  • 技术严重落后,17、18两年荒废,有太多的东西需要追赶。
  • 学习具有滞后性,过程中不免产生是否有用的焦虑。
  • 计划总是多于实际,完不成计划让自己产生挫败感
  • 工作/工资/技术这些东西,与同学比,与同事比,与微信群里的陌生人比,总是有种挫败感.

关于钱

  • 工资太少,相应的资产积累速度不够。
  • 17年跳槽耗光了精力,到现在存款相较同龄人太少。
  • 父母养老,自己保险,自己生活品质的花销堪堪够用,还有很多的欲望等待金钱实现。
  • 自己当前承担不起父母的老年生活。
  • 积蓄太少,经受不住失业。
  • 没有谈婚论嫁的经济能力。

体重

  • 还很胖。虽然已经从210->190.
  • 按照目前的习惯正在有条不紊的降低,明显不是一个短时间可以完成的目标,但是前途是光明的。

健康

  • 目前还顶着脂肪肝和高尿酸,身体亚健康。
  • 亚健康状况导致饮食有太多禁忌。
  • 不能熬夜。

恋爱和婚姻

  • 二百斤的胖子是没有对象的。
  • 没谈过恋爱,无限羡慕谈恋爱中的情侣。
  • 到了谈婚论嫁的年龄,自然而然的感受到各方面的压力。
  • 祝地铁上的每一对黏在一起的情侣都是失散多年的兄妹:)

人际关系

  • 交际圈变小,变小的交际圈明显会让你感到对少数朋友的依赖。
  • 保持着对同事的距离,不认同吧同事和朋友的相交叉。因为平时又两点一线的生活,所以导致交际圈不能发育。
  • 跟小雪吵过以后明显不愿意跟大学好友谈论事情。
  • 没人说话的心理状态很不爽.

敏捷开发读书笔记四

Liskov替换原则(LSP)

Liskov替换原则(LSP):子类型(subtype)必须能够替换掉它们的父类型(basetype)

  • IS-A(是一个)关系又是被认为是面向对象分析的基本技术之一.
  • 一个模型,如果孤立地看,并不具有真正意义上的有效性.模型的有效性只能通过它的客户程序来表现.
  • 像所有其他原则一样,通常最好的方法是只预测那些最明显的对于LSP的违反情况二推迟所有的其他的预测,直到出现相关的脆弱性的臭味时,采取处理他们.
  • IS-A是关于行为的.从行为方式的角度来看,Square不是Rectangle(关于正/长方形的例子),对象的行为方式才是软件真正所关注的问题.
  • 基于契约设计(Design By Contract,DBC):使用DBC,类的编写者显示的规定针对该类的契约.客户代码的编写者可以通过该契约获悉可以依赖的行为方式.契约是通过为每个方法生命的前置条件(preconditions)和后置条件(postconditions)来制定的.要使一个方法得以执行,前置条件必须要为真.执行完毕后,该方法要保证后置条件为真.
  • 大多数情况下,接受一个多态性为中的微妙错误都不会比试着修改设计使之完全符合LSP更为有利.接受缺陷而不是去追求完美这是一个工程中的权衡问题.好的工程师知道如何接受缺陷比追求完美更有利.
  • 提取公共部分是一个设计工具,最好在代码不是很多时应用.
  • 完成的功能少于基类的派生类通常是不能替换其基类的,一尺就违反了LSP
  • 在派生类中存在退化函数并不总是表示违反了LSP,但是当存在这种情况是,还是值得注意一下.
  • 另外一种LSP的违规形式是在派生类的方法中添加了其基类不会抛出的异常.
  • LSP是使OCP成为可能的主要原则之一

依赖倒置原则(DIP)

依赖倒置原则(DIP):

a.高层模块不应该依赖于低层模块,二者都应该依赖于抽象

b.抽象不应该依赖于细节,细节应该依赖于抽象.

  • DIP是框架设计的核心原则.
  • 倒置不仅仅是依赖关系的倒置,也是接口所有权的倒置.应用DIP的时,往往是客户拥有抽象接口,而服务者则从这些抽象接口派生.
  • 低层模块实现了在高层模块中声明并被高层模块调用的接口.
  • 程序中所有的依赖关系都应该终止于抽象类或者接口
  • 我们在应用程序中所编写的大多数具体类都是不稳定的,我们不想直接依赖于这些不稳定的具体类.通过把它们隐藏在抽象接口的后面,可以隔离它们的不稳定性.
  • 面向对象的程序设计倒置了依赖关系结构,使得细节和策略都依赖于抽象,并且常常是客户拥有服务接口.这种依赖关系的倒置正式好的面向对象设计的标志所在.
  • 如果程序的依赖关系是倒置的,它就是面向对象的设计.如果程序的依赖关系不是倒置的,它就是过程化设计.
  • DIP的正确应用对于创建可重用框架来说是必须的.

接口隔离原则(ISP)

接口隔离原则:不应该强迫客户依赖于它们不用的方法.

  • ISP用来处理”胖(fat)”接口所具有的缺点.如果类的接口不是内聚的(conhesive),就表示该类具有”胖”的接口.换句话说,类的”胖”接口可以分解成多组方法.每一组方法都服务于一组不同的客户程序.
  • 多参数形式通常都应该优先于单参数形式使用.
  • 每个原则在应用时都必须小心,不能过度使用它们.
  • 客户程序应该仅仅依赖与它们的实际调用方法.通过把胖类的接口分解成多个特定于客户程序的接口,实现这个目标.

第七章 什么是敏捷设计

  • 软件项目的设计是一个抽象的概念.它和程序的概括形状/结构以及每一个模块/类和方法的详细形状和结构有关.可以用不同的媒介去描述他,但是他最终体现为源代码.源代码就是设计.

  • 敏捷设计是一个过程,而不是一个事件.它是一个持续的应用原则/模式以及实践来改进软件的结构和可读性的过程.它致力于保持系统设计在任何时间都能尽可能得简单/干净和富有表现力.

  • 实际上满足工程设计标准的唯一软件文档,就是源代码清单.–Jack Reeves

  • UML图只描绘了设计的一些部分,但是它并不是设计.

  • 敏捷开发人员对待软件设计的态度要像外科医生对待消毒过程的态度是一样的.

  • 设计需要保持干净/简单,并且由于源代码是设计最重要的展示,所以它同样需要保持干净.职业特性要求我们,作为软件开发人员,不能忍受代码腐化.

软件腐化的坏味道

  1. 僵化性(Rigidity):很难对系统进行改动,每个改动都会迫使许多对系统其它部分的其它改动.

  2. 脆弱性(Fragility):对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题.

  3. 牢固性(Immobility):很难解开系统的纠结,使之成为一些可在其它系统中重用的组件.

  4. 粘滞性(Visosity):做正确的事情比做错误的事情要困难.

    • 粘滞性有两种形式:软件的粘滞性和环境的粘滞性
  5. 不必要的复杂性(Needless Complexity):设计中含有不具有任何直接好处的基础结构.

  6. 不必要的重复(NeedLess Repetition):设计中包含有重复结构,而该重复的结构本可以使用单一的抽象进行统一.

  7. 晦涩性(Opacity):很难阅读/理解.没有很好的表现意图.

    • 开发人员必须站在代码阅读者的位置.

软件腐化的原因

  • 变化而又改动急迫的需求/修改人员对原设计思路不熟悉/以上变化的日积月累
  • 我们需要意识到,需求是项目中最不稳定的要素.大多数软件项目中最不稳定的东西就是需求.需求处在一个持续变动的状态之中.
  • 如果设计因为持续/大量的需求变化而失败,就表明设计和实践本身是有缺陷的.

敏捷团队不允许代码腐坏

敏捷团队依靠变化来获取活力.团队几乎不进行预先设计,不需要一个成熟的初始设计.团队更愿意保持系统设计尽可能的干净/简单,并使用许多的单元测试和验收测试作为支援.

团队在开始设计的时候以最简单的方法编写.直到需求最终明确变化时,他们才修改模块的设计,是之对该变化保持弹性.

敏捷开发人员如何知道做什么.

  • 遵循敏捷实践去发现问题(一二章内容)
  • 应用设计原则去诊断问题(单一职责/里式替换/依赖倒转/开闭/接口隔离)
  • 应用适当的设计模式去解决问题.

第八章 单一职责原则(SRP)

单一职责原则:就一个类而言,应该仅有一个引起它变化的原因.

  • 如果一个类承担过多的职责,那么引起它变化的原因就会有多个.多个职责在一个类中后合在一起会导致脆弱(fragile)的设计.在发生变化的时候可能会遭受意想不到的破坏.
  • 什么是职责?在SRP中,我们把职责定义为”变化的原因”.如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.
  • 每一个职责都是一个变化的轴线. 该变化会反应为类的职责的变化.变化的轴线仅当变化实际发生时才具有真正的意义.如果没有征兆,那么去应用SRP或者其他原则都是不明智的.
  • SRP是所有原则中最简单的之一,也是最难正确运用的之一.我们会自然地把职责结合在一起.软件设计真正要做的许多内容,就是发现职责并把这些职责相互分离.

第九章 开放-关闭原则(OCP)

开放-关闭原则:软件实体(类,模块,函数等等)应该是可以扩展的,但是不可以修改.

  • 如果程序中因为一处修改就发生连锁反应,那么它的设计就有僵化性的坏味道.OCP建议在发生变化的时候,对系统的设计进行重构,确保以后在进行同样的改动的时候能够只增加新的代码,而不需要做更多的修改.

  • STARTEGY(策略)模式和TEMPLATE METHOD(模板方法)模式是实现OCP常用的方法.

  • 无论模块多么封闭,都存在一些无法对之封闭的变化.设计人员必须对于他设计的模块应该对那种变化封闭做出选择.

  • 封闭建立在抽象的基础上.

  • OCP的应用应该限定在可能发生的变化上(原因:OCP的代价是昂贵的,正确的抽象需要花费开发时间和精力,抽象也会增加系统的复杂性,开发人员有能力处理的抽象是有限的)

  • 什么时候考虑/适合应用OCP

    变化真正发生的时候.

    • 只受一次愚弄.最初编写代码的时候,假设变化是不发生的.当变化发生的时候,重构系统,创建抽象隔离以后的同类变化.
    • 刺激变化.通过编写测试/短迭代周期/首先开发重要特性/尽早的经常的发布软件.
  • 遵循OCP原则可以带来面向对象技术所生成的巨大好处(灵活性,可重用性和可维护性)

  • 抽象应该针对程序中频繁变化的那部分.

  • 拒绝不成熟的抽象和抽象本身一样重要.

第六章读书笔记

纸上得来终觉浅,绝知此事要躬行

  • 自己的代码确实low,应该多接触一些大佬的代码.
  • 断言的简单引用(以后写单元测试可以用)
  • 单元测试代码也应该重构.同一类的单元测试代码可以整体重构优化.
  • @before来初始化可以让单元测试的代码更优雅一些.
  • 在+1和-1的过程中胡乱调整,直到可以正常工作.//基于巧合的编程???
  • 完整的测试集合可以为程序的修改提供保障
  • 编码前的设计要适当,避免复杂的过度设计.在编码的过程中完善设计.”想清楚来再写代码”这一点要更重要一些.具体的工作过程中要合理掌握度量.

看书碰到代码内容过多的地方,应该动手码一下这些代码.看似是比较麻烦的事情,其实恰恰相反,相比于靠脑袋去运行一遍书上的代码,手敲下来让电脑去运行反而是相对容易的一件事情.
而且在敲代码的过程中,自然而然的会带入到作者的思路里,这样远比一边思考代码思路,一边在脑子里想代码如何运行要简单的多.
而且敲代码所需要的注意力集中程度要更小一点.至少在现阶段自己的段位不足以长时间维持读代码的注意力集中,所以碰见类似的尽量自己敲一下.

0%