[JAVA] Méthode de codage et principe de refactoring

Chanyi a parlé des méthodes qui peuvent être utilisées pour le ** codage ** et l'état actuel du ** codage **, basé sur les problèmes du principe de refactoring.

Méthode 1: écrire le code à la main

La plupart des débutants JAVA Les programmeurs tapent le code suivant sur les outils de développement avec juste une mémoire musculaire Tu peux.

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

Oui, c'est la déclaration classique "Hello world" dont tout le monde se souvient quand ils entrent le code pour la première fois.

Bien entendu, la saisie manuelle du code est également une option. Et dans la pratique, la saisie manuelle du code est un bon moyen de tester vos capacités de programmeur. En fait, de nombreuses entreprises utilisent le codage manuel dans le cadre de leurs examens de programmation informatique pendant le processus d'entrevue. Pour de tels examens, l'intervieweur sélectionne un outil de programmation (tel que Eclipse) en fonction des exigences de l'examen et est spécifique. Vous devez écrire, déboguer et exécuter votre code à la main. Pendant tout le processus de codage, les intervieweurs ne pourront pas rechercher de réponses sur Internet ni consulter les documents d'aide en ligne. En général, il est nécessaire que l'enquêteur soit capable d'écrire le code entièrement de lui-même. Ces examens testent les capacités de codage de l'intervieweur, y compris la syntaxe, les fonctions, la logique, la pensée, les algorithmes et les capacités pratiques.

Le codage manuel est une compétence de base que tout bon programmeur devrait avoir et doit vraiment avoir. Le codage manuel est comme les compétences de base en écriture dont vous avez besoin pour écrire un article. La syntaxe est un moyen de créer des phrases dans votre code. Une fonction est un mot ou une phrase dans un article. Une bibliothèque de classes est une anecdote à citer et une architecture est un genre d'expression. Les fonctionnalités sont le principal objectif de la rédaction d'articles. Les algorithmes sont la logique de l'organisation des langues. Par conséquent, maîtrisez la syntaxe du langage de programmation, apprenez un tas de fonctionnalités de base de bibliothèque de classes, citez certaines des bibliothèques de classes tierces requises, choisissez une architecture mature et stable et clarifiez les fonctionnalités de vos exigences produit. Et vous devez choisir un algorithme qui implémente la logique. Et le codage manuel est aussi simple que d'écrire un article.

Méthode 2: copiez et collez le code

Il en va de même pour le codage, comme le dit le chinois: «Si vous étudiez bien 300 poèmes Tang, vous pourrez chanter même si vous ne pouvez pas les écrire». La première étape du codage est d'imiter. Autrement dit, copiez et collez le code. Copier et coller du code est un art. Si vous utilisez cette méthode correctement, vous pouvez terminer votre codage avec la moitié de l'effort. Lorsque vous avez le code dont vous avez besoin, vérifiez-le attentivement avant de le copier-coller. Un code qui convient à un scénario ne convient pas toujours à un autre. Les programmeurs qualifiés ne prennent pas et n'utilisent pas simplement le code sans le vérifier.

1. Pourquoi copier et coller le code

  1. Vous pouvez raccourcir le temps de développement en copiant et en collant le code existant.
  2. En copiant et en collant du code stable, vous pouvez réduire le risque de défaillance du système.
  3. En copiant et en collant le code du réseau, vous pouvez convertir les réalisations des autres en vos propres réalisations.

2. Problèmes de copie et de collage de code

  1. Comprenez-vous bien le code copié? La logique de mise en œuvre est-elle valide? Le code fonctionne-t-il régulièrement? Combien de bogues potentiels y a-t-il?
  2. Combien de fois avez-vous copié et collé le code dans votre projet? Si je fais la même chose une troisième fois, dois-je refactoriser le même code en fonction du principe de refactoring?
  3. Plus vous copiez et collez le code, plus les problèmes de maintenance du code se poseront. Les mêmes modifications doivent être apportées à chaque emplacement pour garder le code synchronisé après la mise à jour du code dans plusieurs versions. En conséquence, les coûts de maintenance et les risques augmentent.

En bref, copier et coller du code est comme toute autre méthode de codage, et personne n'est meilleur. C'est juste une méthode qui peut être utilisée correctement ou de manière inappropriée. Si vous copiez et collez le code, vous devez être responsable du résultat.

Méthode 3: génération de code par remplacement de texte

1. Exemple de code généré

Vous trouverez ci-dessous un morceau de code écrit pour implémenter une requête utilisateur.

/** Query user service function */
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);
}

/** Query user controller function */
@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);
}

Lors de l'écriture de code qui implémente une requête d'entreprise, le format du code est similaire à celui d'une requête utilisateur. La relation de substitution peut être organisée comme suit.

  1. Remplacez «Utilisateur» par «Entreprise».
  2. Remplacez "utilisateur" par "société". Bloc-notes et EditPlus Vous pouvez utiliser un éditeur de texte tel que .0.31d5474dAMXb9I) pour remplacer le texte courant en respectant la casse. Le résultat final ressemble à ceci:
/** Query company service function */
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);
}

/** Query 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);
}

Lors de la génération de code avec remplacement de texte, assurez-vous que le temps de génération du code ne dépasse pas 1 minute.

2. Avantages et inconvénients

mérite: 1, la vitesse de génération de code est rapide. Démérite:

  1. Vous devez compiler l'exemple de code.
  2. Cette méthode s'applique uniquement aux scénarios de remplacement de texte.

Méthode 4: générer du code à l'aide de formules Excel

Les formules Excel sont très puissantes et peuvent être utilisées pour compiler du code formalisé.

1. Générez une classe de modèle à l'aide de formules Excel

Copiez la définition du modèle d'interface de Wiki vers Excel. Les exemples de données sont les suivants.

image.png

Écrivez la formule Excel comme suit.

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

Générez du code à l'aide de formules comme suit:

/** User ID */ @NotNull private Long id;
/** Username */ @NotBlank private String name;
/** User gender (0:unknown;1:male;2:female) */ @NotNull private Integer sex;
/** User description */  private String description;

Créez une classe de modèle et organisez votre code comme suit:

/** User DO Class */
public class UserDO {
    /** 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;
    ......
}

2. Générez une classe d'énumération à l'aide d'une formule Excel

Copiez la définition d'énumération du Wiki vers Excel. Les exemples de données sont les suivants.

image.png

Écrivez la formule Excel comme suit.

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

Générez du code à l'aide de formules comme suit:

/** empty(0) */NONE(0, "Unknown"),
/** male(1) */MAN(1, "Male"),
/** female(2) */WOMAN(2, "Female"),

Créez une classe d'énumération et organisez votre code comme suit:

/** User gender enumeration class */
public enum UserSex {
    /** enumeration definition */
    /** empty(0) */
    NONE(0, "unknown"),
    /** male(1) */
    MAN(1, "male"),
    /** female(2) */
    WOMAN(2, "female");
    ......
}

3. Générez des instructions de base de données à l'aide de formules Excel

La liste des entreprises est triée dans Excel comme suit. Sur la base de cette liste, vous devez écrire une instruction SQL pour insérer l'enregistrement directement dans la base de données.

image.png

Écrivez la formule Excel comme suit.

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

Utilisez l'expression pour générer une instruction SQL similaire à la suivante:

('AutoNavi', 'First Tower', '(010)11111111', '[email protected]'),
('Alibaba Cloud', 'Green village', '(010)22222222', '[email protected]'),
('Cainiao', 'Alibaba offices', '(010)33333333', '[email protected]'),

Ajoutez un en-tête d'instruction into et triez les instructions SQL comme suit:

insert into t_company(name, address, phone, email) values
('AutoNavi', 'First Tower', '(010)11111111', '[email protected]'),
('Alibaba Cloud', 'Green village', '(010)22222222', '[email protected]'),
('Cainiao', 'Alibaba offices', '(010)33333333', '[email protected]');

4. Avantages et inconvénients

mérite:

  1. Cette méthode peut être appliquée à la génération de code de données basées sur des tables.
  2. Après avoir écrit la formule, vous pouvez générer le code par glisser-déposer. Par conséquent, la vitesse de génération de code est rapide. Démérite:
  3. Cette méthode ne peut pas être appliquée à la génération de code à l'aide de fonctions complexes.

Méthode 5: générer du code à l'aide d'outils

Autrement dit, utilisez vos outils existants pour générer le code. De nombreux outils de développement fournissent des outils pour générer du code. Par exemple, générer des constructeurs, recharger des classes de base et des fonctions d'interface, générer des fonctions getter / setter, générer des fonctions toString, etc. En utilisant ces outils, vous pouvez vous épargner la peine de coder manuellement. Vous pouvez également utiliser plusieurs plug-ins de génération de code pour générer du code qui répond à votre scénario d'application spécifique.

Ce qui suit décrit comment utiliser l'outil de génération de code, en utilisant le plug-in MyBatis-Generator comme exemple.

1. Installez et exécutez le plug-in

Pour plus d'informations, recherchez sur Internet des documents connexes.

2. Exemple de code généré

** 2.1. Générer le code de classe de modèle ** Le contenu du fichier User.java est le suivant.

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

** 2.2 Génération de code d'interface Mapper ** Le contenu du fichier UserMapper.java est le suivant.

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

** 2.3. Génération de code XML du mappeur ** Le contenu du fichier UserMapper.xml est le suivant.

......
<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>

3. Avantages et inconvénients

mérite:

  1. Générez du code à l'aide du plug-in de génération de code. Par conséquent, la vitesse de génération de code est rapide.
  2. Utilisez le fichier de configuration du plug-in pour contrôler la génération du code de fonction souhaité. Démérite:
  3. Il faut du temps pour apprendre à utiliser le plug-in de génération de code et à s'y habituer.
  4. Le code généré ne répond pas toujours aux spécifications du code. Un contrôle de conformité du code est requis à chaque fois qu'il est généré.
  5. Après avoir régénéré le code, le code personnalisé est susceptible d'être écrasé. Gérez donc une autre bibliothèque de codes, utilisez l'outil DIFF pour identifier les différences de code, attribuez des valeurs, puis différentes. Il est recommandé de coller le code.

Méthode 6: générer du code à l'aide du code

En d'autres termes, écrivez-le vous-même et générez votre propre code. Ce qui suit décrit cette méthode en utilisant le code d'accès à la base de données MyBatis comme exemple.

1. Demande d'informations sur les tables

Tout d'abord, obtenez les informations de table et de colonne nécessaires à la génération de code à partir de la base de données.

** 1.1. Demander des informations sur le tableau ** L'instruction pour interroger les informations de table est:

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

Le premier point d'interrogation indique la valeur attribuée au nom de la base de données et le deuxième point d'interrogation indique la valeur affectée au nom de la table.

Le résultat de la requête des informations de table est le suivant.

SN. Table name Table remarks
1 org_company Organization company table

** 1.2. Informations sur la colonne de requête ** L'instruction pour interroger les informations de colonne est:

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 'numeric precision'
, c.numeric_scale as 'numeric scale'
, c.column_default as ''
, c.is_nullable as 'optional?'
, 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;

Le premier point d'interrogation indique la valeur attribuée au nom de la base de données et le deuxième point d'interrogation indique la valeur affectée au nom de la table.

** Le résultat de la requête des informations de colonne est le suivant. ** **

image.png

2 Compilation et génération de code

** 2.1 Compilation et génération du code de classe de modèle **

/** Generate model class file function */
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 class */");
        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 Compilation et génération du code d'interface DAO **

/** Generate DAO interface file function */
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 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("}");
    }
}

** 2.3 Compilation et génération de code mappeur DAO **

/** Generate DAO mapping file function */
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 + "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<!-- 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>");
    }
}

3 Générer du code associé

** 3.1 Code de classe de modèle généré **

/** Organize company DO class */
@Getter
@Setter
@ToString
public class OrgCompanyDO {
    /** company logo */
    private Long id;
    /** company name */
    private String name;
    /** contact address */
    private String address;
    /** company description */
    private String description;
}

** 3.2 Code d'interface DAO généré **

/** Organize company DAO interface */
public interface OrgCompanyDAO {
    /** Get organization company function */
    public OrgCompanyDO get(@Param("id") Long id);
}

** 3.3 Code mappeur DAO généré **

<!—Organize company mapping -->
<mapper namespace="xxx.database.OrgCompanyDAO">
    <!—All field statement -->
    <sql id="fields">
        id
        , name
        , address
        , description
    </sql>
    <!—Get organization company function statement -->
    <select id="get" resultType="xxx.database.OrgCompanyDO">
        select
        <include refid="fields"/>
        from org_company
        where id = #{id}
    </select>
</mapper>

4. Avantages et inconvénients

mérite:

  1. Vous pouvez personnaliser le format du code pour garantir la conformité du code généré.
  2. Vous pouvez personnaliser la fonction de code pour générer uniquement le code souhaité. 3, après la précipitation pré-cordon, le code peut être utilisé directement plus tard. Démérite:
  3. Il est nécessaire de considérer la source de données pour s'assurer que les données nécessaires à la génération de code sont obtenues.
  4. Il faut du temps pour créer et compiler un modèle de données et générer du code.

Méthode ultime: ne vous contentez pas de la méthode

Est-ce la méthode de codage ultime où vous pouvez dire à l'ordinateur ce dont vous avez besoin et l'ordinateur générera automatiquement le code pour vous? Cela pourrait devenir une réalité après un certain développement technologique dans le futur. Cependant, cette méthode est désormais peu pratique. En réalité, à moins d'être un patron, un chef de produit ou un directeur technique, vous ne pouvez pas «générer du code dès que vous ouvrez la bouche».

Le moyen ultime de coder n'est pas seulement de s'en tenir à la méthode, mais d'utiliser la méthode qui vous convient. Toutes les méthodes de codage répertoriées dans cet article ont leurs avantages et leurs inconvénients et peuvent être appliquées à divers scénarios. Par conséquent, on peut dire que la véritable méthode de codage ultime consiste à utiliser de manière flexible diverses méthodes de codage.

Standardisation du code

La plupart des méthodes de codage précédentes nécessitent que vous compiliez manuellement l'exemple de code. Si votre code n'est pas conforme aux spécifications du code, il sera difficile de trouver un terrain d'entente entre les codes et de résumer l'exemple de code qui agit comme une norme. Si l'exemple de code qui fonctionne comme une norme n'est pas conforme aux spécifications du code, le code généré ne sera pas non plus conforme aux spécifications du code et la non-conformité augmentera des dizaines, des centaines et des milliers de fois. .. Par conséquent, la normalisation du code est une priorité de codage.

Recommended Posts

Méthode de codage et principe de refactoring
Fonctions et méthodes
[Java] Classe générique et méthode générique
chemins de rails et méthodes d'URL
À propos de la méthode Pluck et de la méthode ID
Méthodes Java et surcharges de méthodes
[Ruby] Méthodes singulières et classes singulières
Méthodes et classes Ruby (basiques)
Méthodes et classes abstraites Java
À propos des méthodes Java statiques et non statiques
À propos des méthodes equals () et hashcode ()
Entrée standard Ruby et diverses méthodes
Comment appeler des classes et des méthodes
Etudier Java 8 (méthode StaticIF et Default)
Java Generics (définit les classes et les méthodes)
TCP: principes de base et architecture d'application
Application des méthodes downcase et slice