[JAVA] Trop d'arguments de fonction - je veux vous donner une chance d'écrire du bon code. 8 [Exemple de refactoring C #]

Problème avec trop d'arguments de fonction

Je vois du code avec de nombreux arguments de fonction dans divers projets. Il y a une histoire que les humains peuvent comprendre au plus sept, alors pensez à la réduire. Le point le plus important est que si vous pensez correctement à la division du traitement, le nombre d'arguments augmentera rarement. J'ai écrit un exemple de manteau basé sur un exemple réel.

Exemple de code

Envisagez d'obtenir des données de huit tableaux à l'écran et de les afficher à l'écran.

        void Main(int id)
        {
            //Traitement d'affichage initial de l'écran
            var table1Rows = GetTable1Rows(id);
            var table2Rows = GetTable2Rows(id);
            var table3Rows = GetTable3Rows(id);
            var table4Rows = GetTable4Rows(id);
            var table5Rows = GetTable5Rows(id);
            var table6Rows = GetTable6Rows(id);
            var table7Rows = GetTable7Rows(id);
            var table8Rows = GetTable8Rows(id);

            InitializeView(
                table1Rows,
                table2Rows,
                table3Rows,
                table4Rows,
                table5Rows,
                table6Rows,
                table7Rows,
                table8Rows);
        }

        /**Traitement d'affichage initial**/
        private void InitializeView(
            List<Table1Row> table1Rows,
            List<Table2Row> table2Rows,
            List<Table3Row> table3Rows,
            List<Table4Row> table4Rows,
            List<Table5Row> table5Rows,
            List<Table6Row> table6Rows,
            List<Table7Row> table7Rows,
            List<Table8Row> table8Rows)
        {
            //Réglez sur l'écran.
            SetView(
                table1Rows,
                table2Rows,
                table3Rows,
                table4Rows,
                table5Rows,
                table6Rows,
                table7Rows,
                table8Rows);

        }

        /**Processus de remplacement mystérieux appelé lors du processus d'affichage initial**/
        private void SetView(
            List<Table1Row> table1Rows,
            List<Table2Row> table2Rows,
            List<Table3Row> table3Rows,
            List<Table4Row> table4Rows,
            List<Table5Row> table5Rows,
            List<Table6Row> table6Rows,
            List<Table7Row> table7Rows,
            List<Table8Row> table8Rows)
        {
            SetTable1(table1Rows);
            SetTable2(table2Rows);
            SetTable3(table3Rows);
            SetTable4(table4Rows);
            SetTable5(table5Rows);
            SetTable6(table6Rows);
            SetTable7(table7Rows);
            SetTable8(table8Rows);
        }

        /**Le processus de réglage de chaque DTO à l'écran. Le code lui-même à définir est omis.**/
        private void SetTable1(List<Table1Row> table1Rows)
        {
        }

        private void SetTable2(List<Table2Row> table2Rows)
        {
        }

        private void SetTable3(List<Table3Row> table2Rows)
        {
        }

        private void SetTable4(List<Table4Row> table2Rows)
        {
        }

        private void SetTable5(List<Table5Row> table2Rows)
        {
        }

        private void SetTable6(List<Table6Row> table2Rows)
        {
        }

        private void SetTable7(List<Table7Row> table2Rows)
        {
        }

        private void SetTable8(List<Table8Row> table2Rows)
        {
        }

        /**Renvoyer une instance vide pour l'échantillon,
         *En fait, tableau 1,...,Dao existe jusqu'au tableau 8 et est acquis auprès de DB.
         **/
        private List<Table1Row> GetTable1Rows(int id)
        {
            return new List<Table1Row>();
        }

        private List<Table2Row> GetTable2Rows(int id)
        {
            return new List<Table2Row>();
        }
        private List<Table3Row> GetTable3Rows(int id)
        {
            return new List<Table3Row>();
        }
        private List<Table4Row> GetTable4Rows(int id)
        {
            return new List<Table4Row>();
        }
        private List<Table5Row> GetTable5Rows(int id)
        {
            return new List<Table5Row>();
        }

        private List<Table6Row> GetTable6Rows(int id)
        {
            return new List<Table6Row>();
        }

        private List<Table7Row> GetTable7Rows(int id)
        {
            return new List<Table7Row>();
        }

        private List<Table8Row> GetTable8Rows(int id)
        {
            return new List<Table8Row>();
        }

        /** 
         *Simplifié pour un échantillon, mais en fait un ensemble de tables plus complexe.
         *Je ne pense pas à la mauvaise conception de la table ici.
         **/
        public class Table1Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table2Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table3Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table4Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table5Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table6Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table7Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

        public class Table8Row
        {
            int Id { get; set; }
            string Value { get; set; }
        }

La première chose à dessiner est qu'il y a deux fonctions avec huit arguments, dont l'un a une raison d'existence inconnue. Je suppose que je voulais probablement un nom de fonction plus descriptif. Non seulement il y a beaucoup d'arguments, mais il est également difficile de savoir comment obtenir les arguments de la fonction SetTable en raison de la portée de la variable inutilement longue. En passant, dans le code actuel, cette fonction n'est pas appelée ailleurs.

Raccourcissez simplement la portée de la variable et ce sera rafraîchissant.

Code après refactoring

        void Main(int id)
        {
            //Traitement d'affichage initial de l'écran

            InitializeView(id);
        }

        /**Traitement d'affichage initial**/
        private void InitializeView(int id)
        {
            var table1Rows = GetTable1Rows(id);
            SetTable1(table1Rows);

            var table2Rows = GetTable2Rows(id);
            SetTable2(table2Rows);

            var table3Rows = GetTable3Rows(id);
            SetTable3(table3Rows);

            var table4Rows = GetTable4Rows(id);
            SetTable4(table4Rows);

            var table5Rows = GetTable5Rows(id);
            SetTable5(table5Rows);

            var table6Rows = GetTable6Rows(id);
            SetTable6(table6Rows);

            var table7Rows = GetTable7Rows(id);
            SetTable7(table7Rows);

            var table8Rows = GetTable8Rows(id);
            SetTable8(table8Rows);
        }

Il ne suffit pas de résoudre uniquement le nombre d'arguments de fonction

En passant, je vais donner un exemple avec un petit nombre d'arguments mais un problème.

        private List<Table1Row> _table1Rows = null;
        private List<Table2Row> _table2Rows = null;
        private List<Table3Row> _table3Rows = null;
        private List<Table4Row> _table4Rows = null;
        private List<Table5Row> _table5Rows = null;
        private List<Table6Row> _table6Rows = null;
        private List<Table7Row> _table7Rows = null;
        private List<Table8Row> _table8Rows = null;

        void Main(int id)
        {
            //Traitement d'affichage initial de l'écran
            _table1Rows = GetTable1Rows(id);
            _table2Rows = GetTable2Rows(id);
            _table3Rows = GetTable3Rows(id);
            _table4Rows = GetTable4Rows(id);
            _table5Rows = GetTable5Rows(id);
            _table6Rows = GetTable6Rows(id);
            _table7Rows = GetTable7Rows(id);
            _table8Rows = GetTable8Rows(id);

            InitializeView();
        }

        /**Traitement d'affichage initial**/
        private void InitializeView()
        {
            //Réglez sur l'écran.
            SetView();

        }

        /**Processus de remplacement mystérieux appelé lors du processus d'affichage initial**/
        private void SetView()
        {
            SetTable1(_table1Rows);
            SetTable2(_table2Rows);
            SetTable3(_table3Rows);
            SetTable4(_table4Rows);
            SetTable5(_table5Rows);
            SetTable6(_table6Rows);
            SetTable7(_table7Rows);
            SetTable8(_table8Rows);
        }

Cela a l'air rafraîchissant, mais le taux de bogues est beaucoup plus élevé. Le problème est qu'il utilise une variable privée, et il est très difficile de comprendre quand cette variable a été mise à jour. Dans l'exemple, il est facile à comprendre car il n'y a qu'un seul emplacement d'affectation, mais dans la plupart des cas, un bogue se produit souvent en mettant à jour la variable privée dans un autre traitement d'événement.

Résumé

Il est possible de raccourcir l'argument en raccourcissant la portée, veuillez donc le pratiquer. De plus, si vous avez beaucoup d'arguments, vous devriez réfléchir à des moyens de les réduire, mais il n'est pas non plus bon d'utiliser des variables privées. Il existe également une méthode pour regrouper les arguments dans une classe, mais il est préférable de le faire après avoir considéré la portée de la variable. Dans ce cas, vous n'avez même pas besoin de les rassembler dans une classe. Note) Le code réel qui était la source de l'échantillon fonctionne et cela dérange la personne responsable chaque fois qu'une enquête est nécessaire.

Article précédent (Gestion du type Bool)

Article suivant (Pouvons-nous séparer les appels de fonction et les conditions?)

Table des matières

Recommended Posts

Trop d'arguments de fonction - je veux vous donner une chance d'écrire du bon code. 8 [Exemple de refactoring C #]
Easy Null Check-Je veux vous donner une chance d'écrire du bon code. 6 [Exemple de refactoring C #]
Une petite collection de code inquiétante - je veux vous donner une chance d'écrire du bon code. 2 [Exemple de refactoring C #]
Branchement conditionnel compliqué - je veux vous donner une chance d'écrire du bon code. 1 [Exemple de refactoring C #]
Gestion des types booléens - Je veux vous donner une chance d'écrire du bon code. 7 [Exemple de refactoring C #]
Traitement inutile des collections - je veux vous donner une chance d'écrire du bon code. 5 [Exemple de refactoring C #]
Est-il possible de séparer les appels de fonction et les branches conditionnelles? - Je veux vous donner une chance d'écrire du bon code. 9 [Exemple de refactoring C #]
Une interface fluide? -Je veux vous donner l'occasion d'écrire du bon code. 3 [Exemple de refactoring C #]
Comment écrire du bon code
Je veux écrire un joli build.gradle
Je veux écrire un test unitaire!