代码中的命名严禁使用拼音与英文混合的方式, 更不允许直接使用中文的方式. 正确的英文拼写和语法可以让阅读者易于理解, 避免歧义.
注意: 即使纯拼音命名方式也要避免采用. 但 alibaba,taobao,youku,hangzhou 等国际通用的名称, 可视同英文.
3.1 包名
包名全部小写, 连续的单词只是简单地连接起来, 不使用下划线, 采用反域名命名规则, 全部使用小写字母. 一级包名是顶级域名, 通常为 com,edu,gov,net,org 等, 二级包名为公司名, 三级包名根据应用进行命名, 后面就是对包名的划分了, 关于包名的划分, 推荐采用 PBF(按功能分包 Package By Feature), 一开始我们采用的也是 PBL(按层分包 Package By Layer), 很坑爹. PBF 可能不是很好区分在哪个功能中, 不过也比 PBL 要好找很多, 且 PBF 与 PBL 相比较有如下优势:
package 内高内聚, package 间低耦合
哪块要添新功能, 只改某一个 package 下的东西.
PBL 降低了代码耦合, 但带来了 package 耦合, 要添新功能, 需要改 model,dbHelper,view,service 等等, 需要改动好几个 package 下的代码, 改动的地方越多, 越容易产生新问题, 不是吗?
PBF 的话 featureA 相关的所有东西都在 featureA 包, feature 内高内聚, 高度模块化, 不同 feature 之间低耦合, 相关的东西都放在一起, 还好找.
package 有私有作用域(package-private scope)
你负责开发这块功能, 这个目录下所有东西都是你的.
PBL 的方式是把所有工具方法都放在 util 包下, 小张开发新功能时候发现需要一个 xxUtil, 但它又不是通用的, 那应该放在哪里? 没办法, 按照分层原则, 我们还得放在 util 包下, 好像不太合适, 但放在其它包更不合适, 功能越来越多, util 类也越定义越多. 后来小李负责开发一块功能时发现需要一个 xxUtil, 同样不通用, 去 util 包一看, 怎么已经有了, 而且还没法复用, 只好放弃 xx 这个名字, 改为 xxxUtil......, 因为 PBL 的 package 没有私有作用域, 每一个包都是 public(跨包方法调用是很平常的事情, 每一个包对其它包来说都是可访问的); 如果是 PBF, 小张的 xxUtil 自然放在 featureA 下, 小李的 xxUtil 在 featureB 下, 如果觉得 util 好像是通用的, 就去 util 包看看要不要把工具方法添进 xxUtil, class 命名冲突没有了.
PBF 的 package 有私有作用域, featureA 不应该访问 featureB 下的任何东西(如果非访问不可, 那就说明接口定义有问题).
很容易删除功能
统计发现新功能没人用, 这个版本那块功能得去掉.
如果是 PBL, 得从功能入口到整个业务流程把受到牵连的所有能删的代码和 class 都揪出来删掉, 一不小心就完蛋.
如果是 PBF, 好说, 先删掉对应包, 再删掉功能入口(删掉包后入口肯定报错了), 完事.
高度抽象
解决问题的一般方法是从抽象到具体, PBF 包名是对功能模块的抽象, 包内的 class 是实现细节, 符合从抽象到具体, 而 PBL 弄反了.
PBF 从确定 AppName 开始, 根据功能模块划分 package, 再考虑每块的具体实现细节, 而 PBL 从一开始就要考虑要不要 dao 层, 要不要 com 层等等.
只通过 class 来分离逻辑代码
PBL 既分离 class 又分离 package, 而 PBF 只通过 class 来分离逻辑代码.
没有必要通过 package 分离, 因为 PBL 中也可能出现尴尬的情况:
├── service
├── MainService.java
按照 PBL, service 包下的所有东西都是 Service, 应该不需要 Service 后缀, 但实际上通常为了方便, 直接 import service 包, Service 后缀是为了避免引入的 class 和当前包下的 class 命名冲突, 当然, 不用后缀也可以, 得写清楚包路径, 比如 new com.domain.service.MainService(), 麻烦; 而 PBF 就很方便, 无需 import, 直接 new MainService() 即可.
package 的大小有意义了
PBL 中包的大小无限增长是合理的, 因为功能越添越多, 而 PBF 中包太大 (包里 class 太多) 表示这块需要重构(划分子包).
如要知道更多好处, 可以查看这篇博文:
Package by features, not layers(https://link.jianshu.com/?t=https://medium.com/@cesarmcferreira/package-by-features-not-layers-2d076df1964d#.mp782izhh), 当然, 我们大谷歌也有相应的 Sample:todo-mvp(https://link.jianshu.com/?t=https://github.com/googlesamples/android-architecture/tree/todo-mvp/), 其结构如下所示, 很值得学习.
com
└── example
└── android
└── architecture
└── blueprints
└── todoapp
├── BasePresenter.java
├── BaseView.java
├── addedittask
│ ├── AddEditTaskActivity.java
│ ├── AddEditTaskContract.java
│ ├── AddEditTaskFragment.java
│ └── AddEditTaskPresenter.java
├── data
│ ├── Task.java
│ └── source
│ ├── TasksDataSource.java
│ ├── TasksRepository.java
│ ├── local
│ │ ├── TasksDbHelper.java
│ │ ├── TasksLocalDataSource.java
│ │ └── TasksPersistenceContract.java
│ └── remote
│ └── TasksRemoteDataSource.java
├── statistics
│ ├── StatisticsActivity.java
│ ├── StatisticsContract.java
│ ├── StatisticsFragment.java
│ └── StatisticsPresenter.java
├── taskdetail
│ ├── TaskDetailActivity.java
│ ├── TaskDetailContract.java
│ ├── TaskDetailFragment.java
│ └── TaskDetailPresenter.java
├── tasks
│ ├── ScrollChildSwipeRefreshLayout.java
│ ├── TasksActivity.java
│ ├── TasksContract.java
│ ├── TasksFilterType.java
│ ├── TasksFragment.java
│ └── TasksPresenter.java
└── util
├── ActivityUtils.java
├── EspressoIdlingResource.java
└── SimpleCountingIdlingResource.java
参考以上的代码结构, 按功能分包具体可以这样做:
com
└── domain
└── app
├── App.java 定义 Application 类
├── Config.java 定义配置数据(常量)
├── base 基础组件
├── custom_view 自定义视图
├── data 数据处理
│ ├── DataManager.java 数据管理器,
│ ├── local 来源于本地的数据, 比如 SP,Database,File
│ ├── model 定义 model(数据结构以及 getter/setter,compareTo,equals 等等, 不含复杂操作)
│ └── remote 来源于远端的数据
├── feature 功能
│ ├── feature0 功能 0
│ │ ├── feature0Activity.java
│ │ ├── feature0Fragment.java
│ │ ├── xxAdapter.java
│ │ └── ... 其他 class
│ └── ... 其他功能
├── injection 依赖注入
├── util 工具类
└── widget 小部件
3.2 类名
类名都以 UpperCamelCase 风格编写.
类名通常是名词或名词短语, 接口名称有时可能是形容词或形容词短语. 现在还没有特定的规则或行之有效的约定来命名注解类型.
名词, 采用大驼峰命名法, 尽量避免缩写, 除非该缩写是众所周知的, 比如 html,URL, 如果类名称中包含单词缩写, 则单词缩写的每个字母均应大写.
来源: https://mp.weixin.qq.com/s?__biz=MzIwMzYwMTk1NA==&mid=2247489519&idx=1&sn=e2130b149ec21f76898acfd88cb468a0