【tmp】Java设计 - hippowc/hippowc.github.io GitHub Wiki

命名

  • 变量名:名词,拒绝魔数
    • 好处:描述业务含义,代码可搜索
  • 函数名:体现做什么,而不是怎么做
  • 类名:
    • 核心类要体现业务语义
    • 辅助类通过业务名+后缀表示
  • 通用
    • 限定词后置与业务描述词:total,sum,count等

规范

  • 命名规范:包名、类名、常量名,枚举以及异常等
  • 日志规范:
    • ERROR:不能自己恢复的错误;打印堆栈以及上下文关键信息
    • WARNING:可预知的业务问题
    • INFO:记录系统核心状态的变化
    • DEBUG:调试信息
  • 异常规范
    • 建议分为:业务异常和系统异常
    • 建议使用非检查异常,因为检查异常需要每一级都关心,成本高于收益
  • 错误码
    • 错误码规范没有统一的约定
    • 平台、底层系统或软件产品,可以采用编号式,譬如:ORA_00029,好处:风格固定,有正式感;缺点是需配合文档才能理解
    • 业务系统中建议使用显性化错误码,譬如:类型_场景_自定义标识,B_Customer_NameAlreadyExist,可维护性和可理解性大大提升
  • 埋点规范
    • 阿里超级位置模型(super position model, spm),格式:a.b.c.d,站点类型.外站ID.频道ID.页面ID

函数

  • 一个方法只做一件事情
  • 精简辅助代码:判空、日志、鉴权、缓存等
    • Optinal 判空
    • 使用注解优化缓存、降级等逻辑
  • 抽象层次一致:函数体的内容需要再同一个抽象层次

设计原则

  • SOLID
    • 其中 开闭原则和里氏替换原则 是设计目标
    • 单一职责、接口隔离和依赖倒置是设计方法
    • 介绍:
      • SRP 单一职责:任何一个模块中职责要单一
      • OCP 开闭原则:对扩展开放,对修改关闭
      • LSP 里氏替换:父类型能够正确被子类型替换
      • ISP 接口隔离:多个特定接口好于一个用途广泛接口
      • DIP 依赖倒置:模块之间依赖抽象,而不是实现
  • 关于是否要设计
    • DRY 不要重复你自己:避免重复代码
    • YANNI 你不会需要他:极限编程提出的原则,你自以为有用的功能,实际上用不到,因此不要提前设计
    • Rule of Three 三次原则:第一次用到某个功能,写一个特定解决方法,第二次用到,复制代码,第三次用到,才开始抽象;是对DRY和YANNI的折中,是代码冗余与开发成本的平衡点

设计模式

  • GOF模式简介
    • 创建型模式:关注怎样创建对象,特点是将对象创建与使用分离
      • 单例:类只能生成一个实例,类提供一个全局访问点,以便于外部获取该实例
      • 原型:将一个对象作为原型,通过对其复制操作而复制出多个和原型类似的新实例
      • 工厂方法:定义一个创建产品的接口,由子类决定生产什么产品
      • 抽象工厂:提供一个创建产品族的接口,其每个子类可以生产一系列相关产品
      • 建造者:将一个复杂对象分解成多个相对简单的部分,根据不同的需要分别创建他们,最终构建成复杂对象
    • 结构型模式:关注如何将类按某种布局组成更大更复杂的结构
      • 代理:为某丢下提供一个代理以控制对该对象的访问,使用者通过代理间接访问该对象,从而限制、增强或修改该对象的一些特性
      • 适配器:将一个类的接口转换成客户希望的另一个接口,使原本不兼容的类可以一起工作
      • 桥接:抽象与实现分离,使用组合关系代替继承关系,从而降低抽象和实现的耦合度
      • 装饰:动态的给对象增加一些职责
      • 外观:为多个复杂子系统提供一个一致接口,使子系统更容易被访问
      • 享元:使用共享技术有效支持大量细粒度对象的复用
      • 组合:将对象组合成树状层次结构,是用户对单个和组合对象具有一致的访问性
    • 行为型模式:关注对象之间怎么协作共同完成单个对象无法单独完成的任务
      • 模板:定义一个操作中的算法骨架,将一些步骤延迟到子类中,使子类可以在不改变算法结构的情况下,重新定义某些特定步骤
      • 策略:定义一系列算法,并将一些列算法封装起来,使他们可以互相替换,算法改变不会影响使用算法的客户
      • 命令:将请求封装成一个对象,使发送请求的责任和执行请求的责任分开
      • 职责链:把请求从链中的一个对象传到下一个对象,直到请求被响应,从而去除对象之间的耦合
      • 状态:允许对象在其内部状态发生改变时改变其行为能力
      • 观察者:对象间存在一对多关系,当一个对象改变时,通知其他多个对象
      • 中介者:定义一个中介对象简化原有对象间的交互关系,降低对象间耦合度
      • 迭代器:提供一种方法顺序访问聚合对象中的一系列数据,而不暴露对象的内部表示
      • 访问者:不改变集合元素的前提下,为集合中的每个元素提供多种访问方式
      • 备忘录:不破坏封装性的前提下,获取并保存一个对象内部状态,以便后续恢复
      • 解释器:提供语言定义的文法,以及对语言句子的解释方法
  • 其他应用广泛的设计模式
    • 拦截器或面向切面:提供一种通用的扩展机制,可以在业务操作前后提供切面操作,通常是业务无关的,如:日志记录、性能统计、安全控制等
    • 插件模式或SPI:与普通对象扩展方式不同点在于:普通扩展发生在软件内部,插件扩展发生在外部
    • 管道模式:和链式处理类似

模型

软件工程两个高阶工作:架构和建模

  • 建模工具 UML
    • 类图
    • ER图:实体关系图,数据建模最重要模型
    • 时序图

DDD

DDD 领域驱动设计:其革命性在于它是基于面向对象分析的方法论,利用面向对象的特性化解复杂性

  • 数据驱动(贫血模型)
    • 目前主流的开发模式
    • 以数据库为中心,数据模型是最重要的设计,用数据库实现数据,使用服务实现行为
  • 领域驱动(充血模型)
    • 以领域模型为起点,更关注业务语义的显性表达,而不是数据存储和数据关系
    • 优势
      • 统一语言,业务与代码采用共同语言
      • 核心为领域模型,先找到业务中的领域模型,强调抽象和面向对象编程
      • 业务语义显性化,使得核心领域概念在代码中实现,代码尽量体现实体和实体关系原貌
      • 分离业务逻辑和技术细节,业务逻辑越复杂,好处越明显。
    • 核心概念
      • 领域实体:通过找名词可以得到不同的实体
      • 聚合根:更大范围的封装,把一组有相同生命周期,业务上不可分割的实体放在一起
      • 领域服务:有些领域中的动作是一些动词,看上去不属于任何对象,不能简单合并到某个实体中,可以声明为一个服务
      • 领域事件:在一个特定领域有一个用户触发的,发生在过去的行为产生的时间
      • 边界上下文:用于限定模型的应用范围
    • 领域建模方法
      • 用例分析
      • 四色建模
    • 领域模型架构
      • 接口层
      • 服务层,薄,负责协调与转发
      • 领域层:核心,所有业务逻辑在此处实现,包含:实体、值对象、领域事件、仓储
      • 基础设施层:具体平台及实现,常见的:持久化的具体实现

其他

  • 结构化思维:逻辑 + 套路
  • 逻辑:整体结构内在的逻辑关系、顺序,作者总结了四种
    • 演绎顺序:大前提 -》小前提 -》结论
    • 时间、步骤顺序
    • 空间顺序
    • 重要性顺序
  • 如何落地新团队
    • 对于企业,核心要素:业务、技术和人
    • 企业
      • 业务
        • 产品形态:使用测试账号使用下产品
        • 业务流程:
        • 走访客户
      • 技术
        • 系统架构:系统设计和架构思路
        • 领域模型:核心表结构和系统 api
        • 代码结构
        • 组织结构:key person
        • 人员角色:岗位和职责范围
        • 勤沟通
  • 技术leader素养
    • 技术氛围
      • codeReview
      • 技术分享
    • 目标管理
      • 目标管理是Leader管理事务中最重要的事情之一
      • OKR
      • SMART原则:目标制定,具体、可衡量、可能达成、相关性、时间节点
    • 技术规划
      • 当前问题:解决团队迫切紧急的问题
      • 技术领域:根据业务和团队情况,选择领域和命题去突破
      • 业务领域:需要技术做什么布局来应对业务发展
      • 团队特色
    • 与Manager区别:leader是引领和激发,非控制和权威
    • 动机:动机至善,如何兼顾自己和别人,是合作和权衡