北京建网站报价,网站建设军成,网站框架建设,平面设计公司赚钱吗阿里妹导读#xff1a;Don Roberts 提出的一条重构准则#xff1a;第一次做某件事时只管去做#xff1b;第二次做类似的事时会产生反感#xff0c;但无论如何还是可以去做#xff1b;第三次再做类似的事时#xff0c;你就应该重构。 
编码也是如此#xff0c;当多次编写… 
阿里妹导读Don Roberts 提出的一条重构准则第一次做某件事时只管去做第二次做类似的事时会产生反感但无论如何还是可以去做第三次再做类似的事时你就应该重构。 
编码也是如此当多次编写类似的代码时我们需要考虑是否有一种方法能够提高编码速度让编码速度“起飞”高德地图技术专家陈昌毅常意多年来致力于敏捷开发总结了一套编码的方法论有助于程序员快速、优质、高效地进行编码。 
方法1手工编写代码 
大多数刚学习 Java 的程序员都会怀着一种崇敬的仪式感一字一句地在开发工具上敲出以下代码 
public class Test {public static void main(String[] args) {System.out.println(Hello world!);}
} 
没错这就是经典的Hello world这也是大多数人手工编写的第一个程序。 
手工编写代码更能体现一个程序员的基本素质。有很多公司都把上机编程考试作为面试的重要手段之一。面试者需要根据题目的要求挑选一款熟悉的编程工具比如Eclipse手工编写代码并调试运行通过。在整个过程中不能通过网络搜索答案不能查看联机帮助文档要求面试者必须手工编写代码主要是考察面试者手工编写代码的能力——语法、函数、逻辑、思维、算法以及动手能力。 
手工编写代码是一个优秀程序员必须具备的基础能力。手工编写代码正如提笔写文章语法就是遣词造句的方法、函数就是组成文章的词句、类库就是据经引典的掌故、架构就是行文表述的体裁、功能就是写作文章的主旨、算法就是组织语言的逻辑……所以只要掌握一门程序语言的语法、学习一堆基础类库的函数、引用一些所需的第三方类库、选择一款成熟稳定的架构、明确一下产品需求的功能、挑选一种实现逻辑的算法……手工编写代码就会像写文章一样手到擒来。 
方法2复制粘贴代码 
常言道熟读唐诗三百首不会作诗也会吟。编码也是同样的道理编码的第一步就是模仿简单地说就是抄代码——复制粘贴代码。复制粘贴代码是一门艺术用好了编码会事半功倍。但是没有检验过的东西终究是不可全信的。当看到需要的代码时在复制粘贴前我们都需要仔细研读、认真思考、详细甄别……很多东西都是仁者见仁、智者见智的东西适合别的场景但不一定适合你的场景。作为一名合格的程序员切不可一味地拿来主义。 
1.为什么要复制粘贴代码 
复制粘贴现有代码可以节省开发时间复制粘贴稳定代码可以降低系统故障风险复制粘贴网络代码可以把别人的成果化为己用。
2.复制粘贴代码带来问题 
你对复制的代码理解程度是多少实现逻辑是否合理能不能稳定运行存在多少潜在的 Bug?这个代码在项目中已经复制粘贴了多少次根据“三则重构”原则你是否需要对这些相同代码进行重构代码被复制粘贴次数越多带来的代码维护问题越多。多个代码版本的更改和修正要保持这些代码的同步就必须需要在每一处进行同样的修改增加了维护的成本和风险。
总之复制粘贴代码跟其它编码方法一样没有优劣对错之分。它只是一种方法你可以善用也可以滥用。如果我们用到了复制粘贴我们就必须为结果负责。 
方法3用文本替换生成代码 
1.生成代码样例 
已经编写好的用户查询相关代码 
/** 查询用户服务函数 */
public PageDataUserVO queryUser(QueryUserParameterVO parameter) {Long totalCount  userDAO.countByParameter(parameter);ListUserVO userList  null;if (Objects.nonNull(totalCount)  totalCount.compareTo(0L)  0) {userList  userDAO.queryByParameter(parameter);}return new PageData(totalCount, userList);
}/** 查询用户控制器函数 */
RequestMapping(path  /queryUser, method  RequestMethod.POST)
public ResultPageDataUserVO queryUser(Valid RequestBody QueryUserParameterVO parameter) {PageDataUserVO pageData  userService.queryUser(parameter);return Result.success(pageData);
} 
如果我们要编写公司查询相关代码其代码形式与用户查询类似整理出替换关系如下 
把用户替换为公司;把User替换为Company;把user替换为company。
利用 Notepad、EditPlus 等文本编辑器选择区分大小写进行普通文本替换最终得到结果如下 
/** 查询公司服务函数 */
public PageDataCompanyVO queryCompany(QueryCompanyParameterVO parameter) {Long totalCount  companyDAO.countByParameter(parameter);ListCompanyVO companyList  null;if (Objects.nonNull(totalCount)  totalCount.compareTo(0L)  0) {companyList  companyDAO.queryByParameter(parameter);}return new PageData(totalCount, companyList);
}/** 查询公司控制器函数 */
RequestMapping(path  /queryCompany, method  RequestMethod.POST)
public ResultPageDataCompanyVO queryCompany(Valid RequestBody QueryCompanyParameterVO parameter) {PageDataCompanyVO pageData  companyService.queryCompany(parameter);return Result.success(pageData);
} 
利用文本替换生成代码整段代码生成时间不会超过1分钟。 
2.主要优缺点 
主要优点 
生成代码速度较快。
主要缺点 
必须编写样例代码只适用于文本替换的情景。
方法4用Excel公式生成代码 
Excel 的公式非常强悍可以用于编写一些公式化的代码。 
1.利用 Excel 公式生成模型类 
从 WIKI 上拷贝接口模型定义到 Excel 里样例数据内容如下 编写 Excel 公式如下 /** D6IF(ISBLANK(F6), , (F6)) */ IF(E6  否, IF(C6  String, NotBlank, NotNull), ) private C6 B6; 
利用公式生成代码如下 
/** 用户标识 */ NotNull private Long id;
/** 用户名称 */ NotBlank private String name;
/** 用户性别(0:未知;1:男;2:女) */ NotNull private Integer sex;
/** 用户描述 */  private String description; 
创建模型类整理代码如下 
/** 用户DO类 */
public class UserDO {/** 用户标识 */NotNullprivate Long id;/** 用户名称 */NotBlankprivate String name;/** 用户性别(0:未知;1:男;2:女) */NotNullprivate Integer sex;/** 用户描述 */private String description;......
} 
2.利用 Excel 公式生成枚举类 
从 WIKI 上拷贝枚举定义到 Excel 里样例数据内容如下 编写 Excel 公式如下 
/** D2(B2) */C2(B2, D2), 
利用公式生成代码如下 
/** 空(0) */NONE(0, 空),
/** 男(1) */MAN(1, 男),
/** 女(2) */WOMAN(2, 女), 
创建枚举类整理代码如下 
/** 用户性别枚举 */
public enum UserSex {/** 枚举定义 *//** 空(0) */NONE(0, 空),/** 男(1) */MAN(1, 男),/** 女(2) */WOMAN(2, 女);......
} 
3.利用 Excel 公式生成数据库语句 
用 Excel 整理的公司列表如下需要整理成 SQL 语句直接插入数据库 编写 Excel 公式如下 (B2, C2, D2, E2), 
利用公式生成 SQL 如下 
(高德, 首开大厦, (010)11111111, gaodexxx.com),
(阿里云, 绿地中心, (010)22222222, aliyunxxx.com),
(菜鸟, 阿里中心, (010)33333333, cainiaoxxx.com), 
添加 into 语句头整理 SQL 如下 
insert into t_company(name, address, phone, email) values
(高德, 首开大厦, (010)11111111, gaodexxx.com),
(阿里云, 绿地中心, (010)22222222, aliyunxxx.com),
(菜鸟, 阿里中心, (010)33333333, cainiaoxxx.com); 
4.主要优缺点 
主要优点 
适用于表格化数据的代码生成写好公式后拖拽生成代码生成速度较快。
主要缺点 
不适用于复杂功能的代码生成。
方法5用工具生成代码 
用工具生成代码顾名思义就是借用已有的工具生成代码。很多开发工具都提供一些工具生成代码比如生成构造函数重载基类/接口函数生成 Getter/Setter 函数生成 toString 函数……能够避免很多手敲代码。还有一些生成代码插件也可以生成满足某些应用场景的代码。 
这里以 mybatis-generator 插件生成代码为例介绍如何利用工具生成代码。 
1.安装运行插件 
具体方法这里不再累述自行上网搜索文档了解。 
2.生成代码样例 
| 2.1.生成模型类代码 
文件 User.java 内容 
......
public class User {private Long id;private String user;private String password;private Integer age;......
} 
| 2.2.生成映射接口代码 
文件 UserMapper.java 内容 
......
public interface UserMapper {User selectByPrimaryKey(Long id);......
} 
| 2.3.生成映射XML代码 
文件 UserMapper.xml 内容 
......
mapper namespacecom.test.dao.UserMapper resultMap idBaseResultMap typecom.test.pojo.User id columnid propertyid jdbcTypeBIGINT /result columnuser propertyuser jdbcTypeVARCHAR /result columnpassword propertypassword jdbcTypeVARCHAR /result columnage propertyage jdbcTypeINTEGER //resultMapsql idBase_Column_List id, user, password, age/sqlselect idselectByPrimaryKey resultMapBaseResultMap parameterTypejava.lang.Long selectinclude refidBase_Column_List /from test_userwhere id  #{id,jdbcTypeBIGINT}/select......
/mapper 
3.主要优缺点 
主要优点 
利用生成代码插件生成代码速度较快利用插件配置文件控制生成想要的功能代码。
主要缺点 
需要时间研究和熟悉生成代码插件的使用生成的代码不一定满足代码规范每次生成后需进行代码合规重新生成代码后容易覆盖自定义代码建议维护单独的生成代码库通过DIFF 工具比较代码差异然后再赋值粘贴差异代码。
方法6用代码生成代码 
用代码生成代码就是自己编写代码按照自己的格式生成代码。下面以生成基于 MyBatis 的数据库访问代码为例说明。 
1.查询表格信息 
首先我们要从数据库中拿到我们生成代码所需要的表和列相关信息。 
| 1.1.查询表信息 
查询表信息语句 
select t.table_name as 表名称
, t.table_comment as 表备注
from information_schema.tables t
where t.table_schema  ?
and t.table_type  BASE TABLE
and t.table_name  ?; 
其中第1个问号赋值数据库名称第2个问号赋值表名称。 
查询表信息结果 | 1.2.查询列信息 
查询列信息语句 
select c.column_name as 列名称
, c.column_comment as 列备注
, c.data_type as 数据类型
, c.character_maximum_length as 字符长度
, c.numeric_precision as 数字精度
, c.numeric_scale as 数字范围
, c.column_default as 
, c.is_nullable as 是否可空
, c.column_key as 列键名
from information_schema.columns c
where c.table_schema  ?
and c.table_name  ?
order by c.ordinal_position; 
其中第1个问号赋值数据库名称第2个问号赋值表名称。 
查询列信息结果 2.编写生成代码 
| 2.1.编写生成模型类代码 
/** 生成模型类文件函数 */
private void generateModelClassFile(File dir, Table table, ListColumn columnList) throws Exception {try (PrintWriter writer  new PrintWriter(new File(dir, className  DO.java))) {String className  getClassName(table.getTableName());String classComments  getClassComment(table.getTableComment());writer.println(package   groupName  .  systemName  .database;);......writer.println(/**   classComments  DO类 */);writer.println(Getter);writer.println(Setter);writer.println(ToString);writer.println(public class   className  DO {);for (Column column : columnList) {String fieldType  getFieldType(column);String fieldName  getFieldName(column.getColumnName());String fieldComment  getFieldComment(column);writer.println(\t/**   fieldComment   */);writer.println(\tprivate   fieldType     fieldName  ;);}writer.println(});}
} 
| 2.2.编写生成 DAO 接口代码 
/** 生成DAO接口文件函数 */
private void generateDaoInterfaceFile(File dir, Table table, ListColumn columnList, ListColumn pkColumnList) throws Exception {try (PrintWriter writer  new PrintWriter(new File(dir, className  DAO.java))) {String className  getClassName(table.getTableName());String classComments  getClassComment(table.getTableComment());writer.println(package   groupName  .  systemName  .database;);......writer.println(/**   classComments  DAO接口 */);writer.println(public interface   className  DAO {);writer.println(\t/** 获取  classComments  函数 */);writer.print(\tpublic   className  DO get();boolean isFirst  true;for (Column pkColumn : pkColumnList) {if (!isFirst) {writer.print(, );} else {isFirst  false;}String fieldType  getFieldType(pkColumn);String fieldName  getFieldName(pkColumn.getColumnName());writer.print(Param(\  fieldName  \)   fieldType     fieldName);}writer.println(););......writer.println(});}
} 
| 2.3.编写生成 DAO 映射代码 
/** 生成DAO映射文件函数 */
private void generateDaoMapperFile(File dir, Table table, ListColumn columnList, ListColumn pkColumnList) throws Exception {try (PrintWriter writer  new PrintWriter(new File(dir, className  DAO.xml))) {String className  getClassName(table.getTableName());String classComments  getClassComment(table.getTableComment());writer.println(?xml version\1.0\ encoding\UTF-8\?);......writer.println(!--   classComments  映射 --);writer.println(mapper namespace\  groupName  .  systemName  .database.  className  DAO\);writer.println(\t!-- 所有字段语句 --);writer.println(\tsql id\fields\);if (CollectionUtils.isNotEmpty(columnList)) {boolean isFirst  true;String columnName  getColumnName(pkColumn.getColumnName());for (Column column : columnList) {if (isFirst) {isFirst  false;writer.println(\t\t  columnName);} else {writer.println(\t\t,   columnName);}}}writer.println(\t/sql);writer.println(\t!-- 获取  classComments  函数语句 --);writer.println(\tselect id\get\ resultType\  groupName  .  systemName  .database.  className  DO\);writer.println(\t\tselect);writer.println(\t\tinclude refid\fields\/);writer.println(\t\tfrom   table.getTableName());boolean isFirst  true;for (Column pkColumn : pkColumnList) {String columnName  getColumnName(pkColumn.getColumnName());String fieldName  getFieldName(pkColumn.getColumnName());writer.print(\t\t);if (isFirst) {writer.print(where);isFirst  false;} else {writer.print(and);}writer.println(   columnName    #{  fieldName  });}writer.println(\t/select);writer.println(/mapper);}
} 
3.生成相关代码 
| 3.1.生成的模型类代码 
/** 组织公司DO类 */
Getter
Setter
ToString
public class OrgCompanyDO {/** 公司标识 */private Long id;/** 公司名称 */private String name;/** 联系地址 */private String address;/** 公司描述 */private String description;
} 
| 3.2.生成的 DAO 接口代码 
/** 组织公司DAO接口 */
public interface OrgCompanyDAO {/** 获取组织公司函数 */public OrgCompanyDO get(Param(id) Long id);
} 
| 3.3.生成的 DAO 映射代码 
!-- 组织公司映射 --
mapper namespacexxx.database.OrgCompanyDAO!-- 所有字段语句 --sql idfieldsid, name, address, description/sql!-- 获取组织公司函数语句 --select idget resultTypexxx.database.OrgCompanyDOselectinclude refidfields/from org_companywhere id  #{id}/select
/mapper 
3.主要优缺点 
主要优点 
代码格式可以定制保证生成代码合规代码功能可以定制只生成需要的代码经过前期代码沉淀后后期能够直接使用。
主要缺点 
需要研究数据来源保证能获取到生成代码所需的数据需要建立数据模型、编写生成代码耗费时间比较长。
终极方法无招胜有招 
编码的终极方法是不是直接对着电脑说需求然后电脑就自动生成代码了未来科技发展到一定水平后这种情况或许会变成现实。但是目前这种情况是不现实的。现实中想要做到大口一张、代码就来除非你是老板、产品经理或者技术管理者。 
编码的终极方法是“无招胜有招”无招并不是不讲究招式而是不拘泥于某一招式信手拈来合适的招式为宜。本文中列举的各种编码方法没有高低优劣之分只有合不合适之说。所以灵活地运用各种编码方法就是编码的终极方法。 
代码规范化 
在上面的各种编码方法中很多方法都需要手工编写样例代码。如果你的代码不遵循代码规范就很难发现代码之间的共性并抽象出能够作为标准的样例代码如果作为标准的样例代码不满足代码规范必然导致生成的代码也不满足代码规范于是把这些不规范放大了十倍、百倍甚至千倍。所以代码规范化是编码的重中之重。 
原文链接 本文为云栖社区原创内容未经允许不得转载。