takeaway

A refactoring rule from Don Roberts:

Do something the first time; The second time you do something similar, you’ll feel bad, but you can do it anyway. The third time you do something like this, you should refactor.

The same goes for coding, and when writing similar code multiple times, we need to consider whether there is a way to speed up the coding. The author, who has worked on agile development for many years, has developed a coding methodology that helps programmers code “quickly, well, and efficiently”.

Method 1: Write the code by hand

Most programmers new to Java will type the following code word for word into a development tool with a sense of ritual reverence:

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


Yes, this is the classic “Hello World, “and it’s the first program that most people ever wrote by hand.

Writing code by hand can reflect the basic quality of a programmer. There are a lot of companies, the computer programming test as one of the important means of interview. According to the requirements of the topic, the candidates should choose a familiar programming tool (such as Eclipse), write the code by hand and debug it. During the whole process, no Internet search for answers, no online help documents, the interviewer is required to write code by hand, mainly to test the ability of the interviewer to write code by hand — grammar, function, logic, thinking, algorithm and practical ability.

Writing code by hand is the basic ability a good programmer must have. Writing code by hand is like writing an article, grammar is the method of choosing words and making sentences, function is the words and phrases of the article, class library is the story according to the classics, structure is the style of the expression, function is the main idea of writing an article, algorithm is the logic of organizing language… So, just master the syntax of a programming language, learn a bunch of basic library functions, reference a few needed third party libraries, choose a mature and stable architecture, identify product requirements, pick an algorithm to implement logic… Writing code by hand is as easy as writing articles.

Method 2: Copy and paste the code

As the saying goes, “if you have read three hundred Tang poems, you can sing them even if you can’t write them.” The same goes for coding. The first step in coding is imitation, which is simply “copying” — copying and pasting code. Copying and pasting code is an art form, and when you code well, you get more out of it. But, after all, you can’t trust everything that hasn’t been tested. When we see code we need to read it, think about it, and vet it before we copy and paste it… A lot of things, are different, different things, suitable for other scenes but not necessarily suitable for your scene. As a qualified programmer, must not blindly “take doctrine”.

1. Why copy and paste code

  1. Save development time by copying and pasting existing code;
  2. Copy and paste stable code to reduce the risk of system failure.
  3. Copy and paste network code, you can use other people’s work.

2. Copy and paste code causes problems

  1. How well do you understand the copied code? Is the implementation logic sound? Can it run stably? How many potential bugs are there?
  2. How many times has this code been copied and pasted in the project? Do you need to refactor the same code according to the “three refactorings” rule?
  3. The more times your code is copied and pasted, the more maintenance problems you create. Changes and fixes to multiple versions of code, and to keep them in sync, the same changes must be made everywhere, increasing maintenance costs and risks.

In short, copy-and-paste code, like any other coding method, is neither right nor wrong. It’s just a method that you can use or abuse. If we use copy and paste, we have to be responsible for the results.

Approach 3: Replace the generated code with text

1. Generate code samples

User query related code has been written:

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);
    }
    returnnew PageData<>(totalCount, userList); } /** Query user controller functions */ @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);
}Copy the code


If we want to write the code related to the company query, the code form is similar to the user query, and the substitution relationship is sorted out as follows:

  1. Replace “user” with “company “;
  2. Replace “User” with “Company”;
  3. Replace “user” with “company”.

Use Notepad, EditPlus and other text editors to select case-sensitive text replacement, and finally get the following results:

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);
    }
    returnnew PageData<>(totalCount, companyList); } /** Query the company controller function */ @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);
}Copy the code


Replace the generated code with text, and the entire code takes less than a minute to generate.

2. Main advantages and disadvantages

Main advantages:

  1. Generating code is fast.

Main disadvantages:

  1. You must write sample code;
  2. This applies only to text substitution scenarios.

Method 4: Generate code using Excel formulas

Excel’s formulas are powerful and can be used to write formulaic code.

1. Use Excel formula to generate model classes

Copy the interface model definition from WIKI to Excel.


A B C D E F
1 The serial number The field names The field type The field Could you empty Additional information
2 1 id Long The user id no
3 2 name String The user name no
4 3 sex Integer User’s gender no Zero: unknown; 1: male; 2: female
5 4 description String User stories is

Write Excel formula as follows:

= "/ * *"&D6&IF(ISBLANK(F6), ""."("&F6&")") &"* /"&IF(E6 = "No." ", IF(C6 = "String"."@NotBlank"."@NotNull"), "") &" private "&C6&""&B6&";"Copy the code


The code generated using the formula is as follows:

/** user id */ @notnull private Long ID; /** user name */ @notblank private String name; /** User gender (0: unknown; 1: male; 2: female) */ @notnull private Integer sex; /** User description */ private String description;Copy the code


Create a model class with the following code:

Public class UserDO {/** userid */ @notnull private Long ID; /** user name */ @notblank private String name; /** User gender (0: unknown; 1: male; 2: female) */ @notnull private Integer sex; /** User description */ private String description; . }Copy the code


2. Use Excel formula to generate enumeration classes

Copy enumeration definitions from WIKI to Excel with the following sample data:


A B C D
1 The serial number Field values The field names The field
2 1 0 NONE empty
3 2 1 MAN male
4 3 2 WOMAN female

Write Excel formula as follows:

="/ * *"&D2&"("&B2&") * /"&C2&"("&B2&","""&D2&"""),"Copy the code


The code generated using the formula is as follows:

Empty (0) / * * * / NONE (0,"Empty"), /** male (1) */MAN(1,"Male"), /** female (2) */ female (2,"Female"),Copy the code


Create an enumeration class with the following code:

Public enum UserSex {public enum UserSex {public enum UserSex {public enum UserSex {public enum UserSex {public enum UserSex */"Empty"), /** male (1) */ MAN(1,"Male"), /** female (2) */ female (2,"Female"); . }Copy the code


3. Use Excel formula to generate database statements

The company list sorted by Excel is as follows, which needs to be sorted into SQL statements and directly inserted into the database:


A B C D E
1 The serial number The name of the company The company address The phone company Company email
2 1 Scott The first building (010)11111111 [email protected]
3 2 Ali cloud Green space center (010)22222222 [email protected]
4 3 rookie Ali center (010)33333333 [email protected]

Write Excel formula as follows:

= "("&B2&"', '"&C2&"', '"&D2&"', '"&E2&"'),"Copy the code


Use the formula to generate SQL as follows:

('gold'.'Opening House'.'(010)11111111'.'[email protected]'),
(Ali Cloud.'Green Centre'.'(010)22222222'.'[email protected]'),
('new'.Ali Center.'(010)33333333'.'[email protected]'),Copy the code


Add into statement header, collate SQL as follows:

insert into t_company(name, address, phone, email) values
('gold'.'Opening House'.'(010)11111111'.'[email protected]'),
(Ali Cloud.'Green Centre'.'(010)22222222'.'[email protected]'),
('new'.Ali Center.'(010)33333333'.'[email protected]');Copy the code


4. Main advantages and disadvantages

Main advantages:

  1. Code generation for tabular data;
  2. After writing the formula, drag and drop to generate the code, the generation speed is faster.

Main disadvantages:

  1. Not suitable for code generation of complex functions.

Approach 5: Tool generation code

Using tools to generate code, as the name implies, is to borrow existing tools to generate code. Many development tools provide utility generation code, such as generating constructors, overloading base classes/interface functions, generating getters/setters, generating toString functions… Can avoid a lot of manual code. There are also generated code plug-ins that can generate code for certain application scenarios.

This section uses mybatis- Generator plug-in as an example to introduce how to use tools to generate code.

1. Install and run the plug-in

Specific methods are no longer described here, their own Internet search documents to understand.

2. Generate code samples

2.1. Generate model class code

The contents of the user.java file:

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


2.2. Generate mapping interface code

The contents of the usermapper. Java file:

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


2.3. Generate the mapping XML code

The contents 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>Copy the code


3. Main advantages and disadvantages

Main advantages:

  1. Using generated code plug-in, generate code faster;
  2. Control the generation of the desired function code using the plug-in configuration file.

Main disadvantages:

  1. Need time to research and become familiar with the use of generated code plug-ins;
  2. The generated code may not meet the code specifications, and code compliance is required after each generation.
  3. After regenerating code, it is easy to overwrite custom code (it is recommended to maintain a separate generated code base, compare code differences through the DIFF tool, and then assign and paste the differences).

Approach 6: Generate code from code

To generate code from code is to write code and generate code in your own format. The following is an example of generating database access code based on MyBatis.

1. Query table information

First, we need to get the table and column information from the database that we need to generate the code.

1.1. Query table information

Query table information statement:

select t.table_name as 'Table name'
, t.table_comment as 'Table remarks'
from information_schema.tables t
where t.table_schema = ?
and t.table_type = 'BASE TABLE'and t.table_name = ? ;Copy the code


The first question mark assigns the database name and the second question mark assigns the table name.

Query table information:

The serial number The name of the table Table note
1 org_company Organization company form

1.2. Query column information

Query column information statement:

select c.column_name as 'Column name'
, c.column_comment as 'Column remarks'
, c.data_type as 'Data type'
, c.character_maximum_length as 'Character length'
, c.numeric_precision as 'Digital accuracy'
, c.numeric_scale as 'Number range'
, c.column_default as ' '
, c.is_nullable as 'Empty or not empty'
, c.column_key as Column key name
from information_schema.columns c
where c.table_schema = ?
and c.table_name = ?
order by c.ordinal_position;Copy the code


The first question mark assigns the database name and the second question mark assigns the table name.

Query column information.

The serial number Column name The column note The data type Characters in length Digital precision Digital range Could you empty The column keys
1 id Company logo bigint
19 0 NO PRI
2 name The name of the company varchar 50

NO
3 address Contact address varchar 200

YES
4 description Company description text 65535

YES

2. Write generated code

2.1. Write generation model class 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("}"); }}Copy the code


2.2. Write code to generate DAO interface

*/ 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 + "The DAO interface * /");
        writer.println("public interface " + className + "DAO {");
        writer.println("\ t / * * get" + classComments + "Function * /");
        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("}"); }}Copy the code


2.3. Write code to generate DAO mapping

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("
       "); . writer.println("<! -" + classComments + "Mapping -- -- >");
        writer.println("<mapper namespace=\"" + groupName + "." + systemName + ".database." + className + "DAO\">");
        writer.println("\t<! -- all field statements -->");
        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<! - to get" + classComments + "Function statement -->");
        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>"); }}Copy the code


3. Generate relevant code

3.1. Generated model class code

/** OrgCompanyDO class */ @get@setter@toString public class OrgCompanyDO {/** companyId */ private Long ID; /** private String name; /** private String address; /** private String description; }Copy the code


3.2. Generated DAO interface code

Public OrgCompanyDAO {/** OrgCompanyDAO {/** OrgCompanyDO get(@param ("id") Long id);
}Copy the code


3.3. Generated DAO mapping code

<! -- Organize company mapping --> < namespace="xxx.database.OrgCompanyDAO"> <! -- all field statements --> < SQL id="fields"> id , name , address , description </sql> <! Select select id="get" resultType="xxx.database.OrgCompanyDO">
        select
        <include refid="fields"/>
        from org_company
        where id = #{id}
    </select>
</mapper>Copy the code


3. Main advantages and disadvantages

Main advantages:

  1. The code format can be customized to ensure the generated code compliance;
  2. The code functions can be customized, generating only the required code;
  3. After the early code precipitation, the later can be used directly.

Main disadvantages:

  1. Data sources need to be researched to ensure that the data needed to generate the code is available;
  2. It takes a long time to build the data model and write the generated code.

The ultimate solution: Nothing wins

The ultimate way to code, isn’t it just a matter of talking to a computer and the computer automatically generates the code? This may become a reality in the future as technology advances. However, this situation is not realistic at present. In reality, you have to be a boss, product manager, or technical manager to get code in one big gulp.

The ultimate method of coding is “no trick wins”, “no trick” is not not pay attention to the “move”, but not adhere to a certain “move”, the appropriate “move”. The various coding methods listed in this paper, there is no superior or inferior points, only suitable to say. Therefore, flexible use of various coding methods, coding is the ultimate method.

Code normalization

Of the various coding methods above, many require manual writing of sample code. If your code doesn’t follow the code specification, it’s hard to find commonalities and abstract out sample code that can serve as a standard. If the standard sample code does not meet the code specification, the resulting code does not meet the code specification, and the irregularities are magnified by a factor of ten, a hundredfold, or even a thousandfold. Therefore, code normalization is the most important coding.

Please refer to the development regulations of Alibaba Group:

Ali Economic Development Regulations

Some of my code normalization suggestions:

The Elegant Way of Java Functions

The Java Server Mess we’ve Seen over the Years

Afterword.

When I was thinking of this article, I saw such a meme on the Internet: a netizen satirized the resume of an Ali person, which was full of “precipitation of a set of XX methodology, enabling XX business.” “Using the buzzword” empowerment “makes it look” posh “. Regardless of his resume, there are lessons to be learned from someone who can approach methodology. Here, I’ll rub off on the meme and give it a fancy title: Coding Methodology, Empowering You and Me.

Author: Chen Changyi, Hua Ming Changyi, technical expert of Autonavi Map, joined Alibaba in 2018 and has been engaged in map data collection.


The original link

This article is the original content of the cloud habitat community, shall not be reproduced without permission.