技艺

命名

  1. 如果你无法给一个函数或者类精确的名字,可能你的方法或者类实现了太多功能,内聚性不够;

  2. 如果你的变量名还需要添加注释,说明这个变量名不够准确,变量名需要具有自表达能力;

  3. 代码要具有可搜索性,搜索PAGE_SIZE比搜索10更加可靠。

  4. proccessData 这样的函数名没有意义,因为所有函数都在处理数据。

  5. Hepler, Util这样的类名容易破环类的SRP(单一职责原则),使用CSVHelper, DOCHelper替换,另外的好处是,看类名就知道已经实现相关功能;

  6. 保持一致性,不同开发者间保持一致,选择了这个名字,就要一直用下去;

  7. get/fetch/query/find/request 都表示查询的意思,用一个就可以了。

  8. 使用对仗词add/remove, show/hide,get/set ….

规范

  1. 认知有成本,通过规范来降低成本。

  2. 混乱增加认知成本;

  3. 破窗效应:一旦有人写了不符合规范的混乱代码,后人就会效仿,甚至变本加厉。

  4. Code Review, 防止破窗。

函数

  1. 函数参数越少越好,如果多月三个,可以考虑封装参数,比如将四个坐标值,封装成两个Point(x,y);

  2. 函数的第一规则要短小,第二规则要更短小;

  3. 职责单一:一个方法只做一件事;

  4. 辅助代码和业务代码分离,精减业务代码中的辅助代码,提高代码的可读性,辅助代码如:判空,日志,鉴权等;

  5. 组合函数模式: 入口函数要像执行命令一样执行函数,具体实现细节要放在函数内部实现,入口函数就像一本书的目录一样清晰明了;

  6. SLAP(抽象层次一致性):要求函数体中的内容必须在同一抽象层次上。如(键盘输入,CPU计算,硬盘存储)属于统一抽象层次,但是(键盘输入,执行加法/减法,硬盘存储)中的执行加减法就不属于同一抽象层次。

  7. 函数式编程:没有”副作用”,函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

设计原则

  1. SOLID 模式: SRP,OCP, LSP, ISP, DIP;

  2. SRP:Single Responsibility Principle, 单一职责原则, 即一个类,方法,组件等只完成一件事,多了就烦了;

  3. OCP: Open Close Principle, 开闭原则,即对扩展开放,对修改关闭,新增功能的时候,不修改原有代码,而是新增扩展代码;

  4. LSP:Liskov Substitution Principle, 里氏替换原则,即父类实例出现的地方,可以使用子类实例替换,也就是说,子类重写父类的方法,干的应该同样的事情;

  5. ISP: Interface Segregation Principle, 接口隔离原则,即不能强迫用户去依赖他们不使用的接口,所以使用多个单一的接口替换总接口;

  6. DIP: Dependency Inversion Principle, 依赖倒置原则,即模块不依赖于具体的类,而是依赖于接口(标准)。

  7. DRY: Don’t Repeat Yourself, 不要复制你的代码,多次遇到同样的问题,将代码抽象成一个共同的解决方法;

  8. YAGNI: You Ain’t Gonna Need It, 不要过度设计,也许有些功能你并不需要他,除了核心功能外,其他功能不要提前设计,YAGNI和DRY原则有冲突,因为DRY提倡抽象。

  9. Rule of Three: 三次原则,即某个功能出现一次时,写代码解决;再次出现时,复制代码解决,再再次出现时,抽象化代码成通用解决方案。 三次原则是DRY和YAGNI的平衡;

  10. KISS:Keep it Simple and Stupid, Kiss是简单,而不是简陋,不是没有设计,而是让设计变得简单易用。要求设计时先发散,考虑所有情况,再收敛,将问题抽象化,去繁为简。

  11. POLA: Principle of least astonishment, 最小惊奇原则,不要让你的代码出现意想不到的“惊喜”,而是遵循原则,标准开发。

设计模式

创建型模式
  1. 单例模式: 全局唯一,外部不可修改属性和行为
  2. 工厂方法模式:暴露对外暴露方法,创建一类对象。 如:Rx.Observale.create()
  3. 抽象工厂方法模式:
  4. 原型模式:将一个对象作为模板,创建同类对象。
  5. 创建者模式:复杂的类由简单的类通过聚合/组合的方式构成。
结构型模式
  1. 适配器模式:已有类无法与现有系统对接,使用适配器类进行对接,如:电脑无法直接读取SD,但是把SD卡放在USB读卡器里就能被读取了
  2. 桥接模式:从不同维度定义物体的不同属性的接口,单独实现各个维度的属性的类,然后从不同维度取出各个属性对象来聚合成复杂对象。而不是直接继承多个维度的属性而创建固定的类,这样会导致类爆炸。
  3. 组合模式:将单个对象和对象组合组织为树状结构,要求访问对象和对象组的方法一致。如:文件系统
  4. 装饰者模式:动态给对象增加额外的功能,装饰器返回的对象和原始对象应该实现相同接口。
  5. 外观模式:类对外暴露一个简单的方法,类内部处理复杂的逻辑。比如基金经理处理复杂的炒股,债券等复杂行为,投资者只要在支付宝上买入一只基金即可;
  6. 享元模式
  7. 代理模式:隐藏原始对象,暴露代理对象,目的是保护原始对象;
行为型模式
  1. 责任链模式:系统中不同角色构成一个权限链,前面的角色无法处理的任务,直接丢给下一个角色,如:多级审批制度。
  2. 命令模式:对象之间不会互相直接引用,而是创建一个命令对象传递信息;
  3. 解释器模式:
  4. 迭代器模式:提供一个方法来访问聚合对象内的所有元素,隐藏聚合对象的内部细节。
  5. 中介者模式:系统中多个角色之间交叉传递信息,耦合图很大,设置一个中介对象,所有同事类只能和中介交流,降低耦合度;
  6. 备忘录模式
  7. 状态模式:将状态定义为一个类,不同状态类内实现其修改状态的方法;
  8. 策略模式:Array.prototype.sort(策略方法)
  9. 模板方法模式:父类定义完成一件事的步骤执行顺序,以及已知步骤的实现细节,未知的差异步骤由子类实现;
  10. 观察者模式:Rx.Observable Observer 一对多
  11. 访问者模式

模型

  1. 模型是现实世界的抽象化;
  2. 建模工具UML;
  3. 领域模型:领域即特定范围内的问题的集合,针对这一特定问题集合建立模型,在不同用户之间建立统一认知。
  4. 敏捷建模:核心是:模型是用来沟通和理解的;简单的工具进行简单的建模;需求在变化,建模要拥抱变化

DDD领域驱动设计

领域驱动设计

思想

抽象

我理解的抽象和归类差不多,抽象的过程就是将问题域中的研究对象,根据他们是否具有相似或相同的属性和行为归类的过程。

抽象或者说归类的好处是,不必为每一个研究对象提供各自的解决方案,而是给每一个分类提供一套通用的解决方案,降低解决方案域的复杂度,未来如果问题域中产生了新的问题,如果改问题可以划分到现有的分类中,那么可以直接使用现有分类的解决方案,不必为其提供解决方案,减少了工作量;

如果抽象呢? 书中提道:自下而上地思考,总结概括;自上而下地表达,结论先行。也就是说抽象是层层向上地,越往上,抽象程度越大,就像构建金字塔一样。

如何提升抽象能力?要多读书,因为文字本身就是抽象地,而视频图片是具象的,具象限制了人的想象力,抽象的文字能够让人的思维发散,开拓想象力,但是思维不能只发散不收敛,只有将思维收敛,才能提炼,总结,形成抽象。

分治

化整为零,分而治之,各个击破,再合而为一,形成系统;