×
Community Blog How Many of the Six Coding Methods Do You Know?

How Many of the Six Coding Methods Do You Know?

In this post, Changyi, a technical expert from Amap, discusses the six major methods of coding and talks about why you may want to know them all.

By Chen Changyi (Changyi) at Alibaba.

1

Some time ago, Don Roberts proposed an approach to refactoring: "The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor."

Similarly, when writing code multiple times, we need to think about whether there is a way to increase our coding speed. Today, Chen Changyi, an technical expert working with Alibaba's mobile map and navigation app AMAP, has been engaged in agile development for many years and would like to summarize some coding methods here to help programmers write code in a fast and efficient manner.

Method 1: Manually Write the Code

Most novice Java programmers will repeatedly type out the following code on their development tools as if it were a ritual:

public class Test {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

Yes, this is the classic "Hello world" code, which typically is the first program that most programmers will manually write.

Manual coding can in many ways reflect the competence of a programmer. Many companies use computer programming examinations as an important part of their interview processes. The interviewee needs to select a programming tool, such as Eclipse, based on the examination requirements and then manually write, debug and run the code. Naturally, when coding, the interviewee cannot search for answers on the Internet or view any online help documentation. The interviewee must write the code manually. Such examinations test the interviewee's ability to manually coding, and also specific aspects like the coder's syntax, functions, logic, conception, algorithms, and general hands-on knowhow.

Manual coding is a basic and essential skill that a good programmer must possess. Writing code manually is like writing an article. The syntax is the method for making sentences. Functions are the words and sentences that make up the article. The class libraries are anecdotes for quoting. The architecture is the genre for expressions. The functionality is the main purpose of writing the article. The algorithms are the logic for organizing the language. So, in other words, you need to master the syntax of a programming language, learn a bunch of functions of basic class libraries, quote some required third-party class libraries, select a mature and stable architecture, clarify the features involved in product requirements, and select an algorithm to implement the logic. Then, as you can see, once you've mastered all of this, manual coding can be as easy as writing an article.

Method 2: Copy and Paste Code

As one Chinese saying goes, "When you have learned to recite 300 poems of the Tang Dynasty by heart, you'll surely be able to write poems." The same is true for coding. The first step of coding is imitation, which is just a fancy way of saying copying and pasting code. In my opinion, copying and pasting code is something of an art. When properly done, this method allows you to write code with half the effort. However, code that is not tested cannot be trusted. When you see the code you need, carefully check it before copying and pasting it. And, it's also important to know that code suitable for one scenario may not be suitable for another scenario. Any qualified programmer knows that he cannot simply take and use the code without first checking it.

1. Reasons for Copying and Pasting Code

  • Copying and pasting existing code can save development time.
  • Copying and pasting stable code can reduce the risk of system failure.
  • Copying and pasting network code can more or less convert others' achievements into your own in a simple and easy way.

2. Problems Caused by Copying and Pasting Code

  • How much do you really understand the copied code? Is the implementation logic reasonable? Can the code run stably? How many potential bugs exist?
  • How many times has the code been copied and pasted in the project? And, based on the principle of "refactoring the third time you do something similar," do you need to refactor similar code?
  • The more times the code is copied and pasted, the more code maintenance problems will arise. To keep the code synchronized after the code is updated in multiple versions, you must make the same changes in each and every place. And, this increases maintenance costs and risks.

So, in short, copying and pasting code is like other coding methods, and it is in no ways a method that is superior to any of the other methods. It is just a method that you can use or abuse. And, you need to remember that, if you copy and paste code, you are still responsible for the results, so copy and paste code carefully!

Method 3: Generate Code by Means of Text Replacement

1. An Example of Generated Code

Below is a piece of code that has been written to implement user queries:

/** 查询用户服务函数 */
public PageData<UserVO> queryUser(QueryUserParameterVO parameter) {
    Long totalCount = userDAO.countByParameter(parameter);
    List<UserVO> 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 Result<PageData<UserVO>> queryUser(@Valid @RequestBody QueryUserParameterVO parameter) {
    PageData<UserVO> pageData = userService.queryUser(parameter);
    return Result.success(pageData);
}

If you want to write code to implement company queries, then the code format you'll need is similar to the user query code. The replacement is as simple as this example: wherever "User" (with a captial "U") appears, replace it with "Company", and wherever "user" (with a lowercase "u") is, change it to be "company". The logic of it really is that simple. Of course, things can get complicated quick, so you'll still need to be careful.

You can use a text editor, such as Notepad or EditPlus, to replace the common text, but make sure to do so in a case-sensitive mode so to minimize mistakes. The final result should look something like this:

/** 查询公司服务函数 */
public PageData<CompanyVO> queryCompany(QueryCompanyParameterVO parameter) {
    Long totalCount = companyDAO.countByParameter(parameter);
    List<CompanyVO> 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 Result<PageData<CompanyVO>> queryCompany(@Valid @RequestBody QueryCompanyParameterVO parameter) {
    PageData<CompanyVO> pageData = companyService.queryCompany(parameter);
    return Result.success(pageData);
}

If you generate code by using the method of text replacement, the code generation time needed will typically not exceed more than one minute.

2. The Advantages and Disadvantages

Advantages

  • Your code generation speed can be quite fast.

Disadvantages

  • The sample code must be compiled.
  • This method is only applicable to text replacement scenarios.

Method 4: Use an Excel Formula to Generate Code

Excel formulas are very powerful and can be used to compile some formulaic code rather quickly.

1. Use an Excel Formula to Generate a Model Class

For this, first, you'll want to copy the interface model definition from Wiki to Excel. The sample data is shown below:

2

Now, you'll need to write an Excel formula like the one below:

= "/** "&D6&IF(ISBLANK(F6), "", "("&F6&")")&" */ "&IF(E6 = "否", IF(C6 = "String", "@NotBlank", "@NotNull"), "")&" private "&C6&" "&B6&";"

Use the formula to generate code like the one here:

/** 用户标识 */ @NotNull private Long id;
/** 用户名称 */ @NotBlank private String name;
/** 用户性别(0:未知;1:男;2:女) */ @NotNull private Integer sex;
/** 用户描述 */  private String description;

Then, create a model class and organize the code:

/** 用户DO类 */
public class UserDO {
    /** 用户标识 */
    @NotNull
    private Long id;
    /** 用户名称 */
    @NotBlank
    private String name;
    /** 用户性别(0:未知;1:男;2:女) */
    @NotNull
    private Integer sex;
    /** 用户描述 */
    private String description;
    ......
}

2. Use an Excel Formula to Generate an Enumeration Class

You'll want to copy the enumeration definition from Wiki to Excel. The sample data is as follows:

3

Next, you'll need to write an Excel formula like the one below:

="/** "&D2&"("&B2&") */"&C2&"("&B2&", """&D2&"""),"

And use the formula to generate the code:

/** 空(0) */NONE(0, "空"),
/** 男(1) */MAN(1, "男"),
/** 女(2) */WOMAN(2, "女"),

And then you'll want to create an enumeration class and organize the code:

/** 用户性别枚举 */
public enum UserSex {
    /** 枚举定义 */
    /** 空(0) */
    NONE(0, "空"),
    /** 男(1) */
    MAN(1, "男"),
    /** 女(2) */
    WOMAN(2, "女");
    ......
}

3. Use an Excel Formula to Generate SQL Statements

The company list should be sorted in the order shown in the example below. This is important to get right because you'll need to write SQL statements to insert the records directly into the database based on this list.

4

Then, you'll want to write an Excel formula like the one below:

= "('"&B2&"', '"&C2&"', '"&D2&"', '"&E2&"'),"

And use the formula to generate SQL statements:

('高德', '首开大厦', '(010)11111111', 'gaode@xxx.com'),
('阿里云', '绿地中心', '(010)22222222', 'aliyun@xxx.com'),
('菜鸟', '阿里中心', '(010)33333333', 'cainiao@xxx.com'),

Add the "into" statement header and sort the SQL statements should look something like this:

insert into t_company(name, address, phone, email) values
('高德', '首开大厦', '(010)11111111', 'gaode@xxx.com'),
('阿里云', '绿地中心', '(010)22222222', 'aliyun@xxx.com'),
('菜鸟', '阿里中心', '(010)33333333', 'cainiao@xxx.com');

4. The Advantages and Disadvantages

Advantages

  • This method can be used to generate code for table-based data.
  • After writing the formula, you can drag and drop the formula to generate code. So, the code generation is quite a quick process.

Disadvantages

  • This method cannot generate code for complex features.

Method 5: Generate Code by Using Tools

In this method, you'll use an existing tool to generate code. Many development toolkits provide tools to generate code, for example, to generate constructors, reload base classes or interface functions, generate Getter/Setter functions, and generate toString functions. These tools can save you the trouble of needing to manually coding, and many of them are free. You can also use some code generation plug-ins to generate code that suits certain application scenarios.

The example I'm sharing here uses MyBatis Generator to show just how you can use a tool to generate code.

1. Plug-in Installation and Running

Installing and running the plug-in isn't that hard, so I'll not going to go into too much detail here, but here's a list of plug-ins to get you started.

2. Examples of Generated Code

Now, assuming that you've installed and started to run MyBatis Generator, let's proceed to our example.

2.1. Generate Model Class Code

The content of the User.java file should look something like this:

......
public class User {
    private Long id;
    private String user;
    private String password;
    private Integer age;
    ......
}

2.2. Generate Mapper Interface Code

The content of the UserMapper.java file will look like this:

......
public interface UserMapper {
    User selectByPrimaryKey(Long id);
    ......
}

2.3. Generate Mapper XML Code

The content of the UserMapper.xml file:

......
<mapper namespace="com.test.dao.UserMapper" >
  <resultMap id="BaseResultMap" type="com.test.pojo.User" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="user" property="user" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="INTEGER" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, user, password, age
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
    select
    <include refid="Base_Column_List" />
    from test_user
    where id = #{id,jdbcType=BIGINT}
  </select>
  ......
</mapper>

4. The Advantages and Disadvantages

Advantages

  • Using code generation plug-ins leads to a much faster code generation process.
  • Plug-in configuration files are used to control the generation of the desired functional code.

Disadvantages

  • It can take some time to study and familiarize yourself with the use of code generation plug-ins.
  • The generated code may not necessarily match your corresponding code specifications. A code compliance check is required after each generation.
  • After the code is re-generated, custom code is often overwritten. So, it's generally recommended that you maintain a separate code library, use the DIFF tool to identify code differences, assign values, and then paste the different code.

Method 6: Use Code to Generate Code

For this method, you'll write the code by yourself and generate code in your own style. The following uses the MyBatis-based database access code as an example to explain this method.

1. Query Table Information

First, you'll need to obtain the table and column information required for code generation from the database.

1.1. Query Table Information

The statements for querying table information should look something like this:

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 = ?;

In this, the first question mark indicates the value assigned to the database name, and the second one indicates the value assigned to the table name.

The table information query result will look like this:

5

1.2. Query Column Information

The statements for querying column information should look something like this:

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;

For this code, like before, the first question mark indicates the value assigned to the database name, and the second one indicates the value assigned to the table name.

The column information query result will look like this:

6

2. Write Generation Code

2.1. Write Model Class Generation Code

/** 生成模型类文件函数 */
private void generateModelClassFile(File dir, Table table, List<Column> 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. Write DAO Interface Generation Code

/** 生成DAO接口文件函数 */
private void generateDaoInterfaceFile(File dir, Table table, List<Column> columnList, List<Column> 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. Write DAO Mapper Generation Code

/** 生成DAO映射文件函数 */
private void generateDaoMapperFile(File dir, Table table, List<Column> columnList, List<Column> 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("\t<sql 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("\t<select id=\"get\" resultType=\"" + groupName + "." + systemName + ".database." + className + "DO\">");
        writer.println("\t\tselect");
        writer.println("\t\t<include 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. Generate the Relevant Code

3.1. Generated Model Class Code

/** 组织公司DO类 */
@Getter
@Setter
@ToString
public class OrgCompanyDO {
    /** 公司标识 */
    private Long id;
    /** 公司名称 */
    private String name;
    /** 联系地址 */
    private String address;
    /** 公司描述 */
    private String description;
}

3.2. Generated DAO Interface Code

/** 组织公司DAO接口 */
public interface OrgCompanyDAO {
    /** 获取组织公司函数 */
    public OrgCompanyDO get(@Param("id") Long id);
}

3.3. Generated DAO Mapper Code

<!-- 组织公司映射 -->
<mapper namespace="xxx.database.OrgCompanyDAO">
    <!-- 所有字段语句 -->
    <sql id="fields">
        id
        , name
        , address
        , description
    </sql>
    <!-- 获取组织公司函数语句 -->
    <select id="get" resultType="xxx.database.OrgCompanyDO">
        select
        <include refid="fields"/>
        from org_company
        where id = #{id}
    </select>
</mapper>

4. The Advantages and Disadvantages

Advantages

  • You can customize the code format to ensure the compliance of the generated code.
  • You can customize the code features to generate only the code you want, and nothing else.
  • After preliminary code accumulation, the code can be used directly later.

Disadvantages

  • Your relevant data sources need to be studied to ensure that the data required for code generation can be obtained.
  • It can take quite a long time to create a data model and write the generation code.

The Ultimate Method: Don't Just Stick to One Method Only

In a dream world, of course, the ultimate method of coding would let you tell the computer what you need and have the computer automatically generate the code. Interestingly, this may become a reality as technology develops in the future. But today, this method is unrealistic. In reality, you cannot simply say what you want and receive the necessary code, unless you are a boss, product manager, or technical manager.

The best method of coding currently available is to use whatever methods that are appropriate, instead of sticking to only a single method. Of course, all the coding methods listed in this article have their own advantages and disadvantages and are applicable to different scenarios. So, again, in my opinion, flexibly using all of the various coding methods discussed in this article is the best coding method since we're not living in a dream world just quite yet.

Code Standardization

One last thing, many of the coding methods that I've discussed in this post require you to manually compile sample code. But, it's important to take note that, if your code does not comply with the specific code specifications needed for your work, it may be difficult to find commonalities between the relevant bits of code in the sample, and it also may be difficult to abstract the sample code to be used as the standard code. So, if the sample code that functions as a standard does not comply with any of your specific code specifications, then the generated code will of course also fail to comply with your code specifications. And, this noncompliance will only be magnified by tens, hundreds, or even thousands of times, as you continue to use it! So, above all else, I want to emphasize here that code standardization should also be your top priority when coding.

0 0 0
Share on

Changyi

5 posts | 0 followers

You may also like

Comments

Changyi

5 posts | 0 followers

Related Products