Anything Array-11 [C # Refactoring Sample]

What is an array?

For programmers who do not know the class, it is often the case that all the parts that should be made into a class are represented by an array. For example, instead of using List, use an extensible array, or make all the parts that correspond to class members into arrays. Arrays may be all-purpose, given that they are ultimately used to complete production. On the other hand, maintainability is low, and even a small change in specifications will increase the number of code corrections, so it can be said to be a bad habit. Let's think concretely with the sample code.

Sample code

Consider an example of converting an array containing ID, Name, and Remarks into a two-dimensional array to TSV.

        /*A line number is added to the passed data line and returned.
         *However, it is in Tsv format excluding Name.
         *ID in row and column format for values,Name,Remarks are stored.
         */
        public List<string> GetTsvWithRowNumber(string[][] values)
        {
            var ids = new string[values.Length];
            var remarks = new string[values.Length];
            var rowNumbers = new int[values.Length];

            //Store in a row-by-row array.
            for (int i = 0; i < values.Length; i++)
            {
                ids[i] = values[i][0];
                remarks[i] = values[i][2];
                rowNumbers[i] = i + 1;
            }

            var returnValues = new List<string>();

            //Create a return value by prefixing the line number.
            for (int i = 0; i < ids.Length; i++)
            {
                var line =
                    rowNumbers[i] + "\t" +
                    ids[i] + "\t" +
                    remarks[i];
                returnValues.Add(line);
            }

            return returnValues;
        }

java
    /*A line number is added to the passed data line and returned.
     *However, it is in Tsv format excluding Name.
     *ID in row and column format for values,Name,Remarks are stored.
     */
    public List<String> getTsvWithRowNumber(String[][] values) {
        String[] ids = new String[values.length];
        String[] remarks = new String[values.length];
        int[] rowNumbers = new int[values.length];

        //Store in a row-by-row array.
        for (int i = 0; i < values.length; i++) {
            ids[i] = values[i][0];
            remarks[i] = values[i][2];
            rowNumbers[i] = i + 1;
        }

        ArrayList<String> returnValues = new ArrayList<String>();

        //Create a return value by prefixing the line number.
        for (int i = 0; i < ids.length; i++) {
            String line =
                    rowNumbers[i] + "\t" +
                    ids[i] + "\t" +
                    remarks[i];
            returnValues.add(line);
        }

        return returnValues;
    }

problem

This code puts each item in an array, and every array must match the number of rows. An error outside the index bounds occurs when the array is declared incorrectly. If the number of items is small, it can be managed, but in business applications, there are usually 10 or more items, so it is difficult to arrange them all.

After refactoring

Converting to Dto and then processing will improve readability and solve the index problem. Also, in order to reduce the magic number, it was modified to values [i] [j ++]. Readability is reduced, but the range of correction when adding items is reduced.

       /*A line number is added to the passed data line and returned.
         *However, it is in Tsv format excluding Name.
         *ID in row and column format for values,Name,Remarks are stored.
         */
        public List<string> GetTsvWithRowNumber(string[][] values)
        {
            var dtoes = new List<Dto>(values.Length);

            //Convert to Dto.
            for (int i = 0; i < values.Length; i++)
            {
                int j = 0;
                var dto = new Dto();
                dto.Id = values[i][j++];
                dto.Name = values[i][j++];
                dto.Remarks = values[i][j++];
                dto.RowNumber = i + 1;

                dtoes.Add(dto);
            }

            var returnValues = new List<string>();

            //Create a return value by prefixing the line number.
            foreach (var dto in dtoes)
            {
                var line =
                    dto.RowNumber + "\t" +
                    dto.Id + "\t" +
                    dto.Remarks;
                returnValues.Add(line);
            }

            return returnValues;
        }

        /**Intermediate class for processing**/
        private class Dto
        {
            public int RowNumber { get; set; }
            public string Id { get; set; }
            public string Name { get; set; }
            public string Remarks { get; set; }

        }

java
    /*A line number is added to the passed data line and returned.
     *However, it is in Tsv format excluding Name.
     *ID in row and column format for values,Name,Remarks are stored.
     */
    public List<String> getTsvWithRowNumber(String[][] values) {
        List<Dto> dtoes = new ArrayList<Dto>(values.length);

        //Convert to Dto.
        for (int i = 0; i < values.length; i++) {
            int j = 0;
            Dto dto = new Dto();
            dto.setId(values[i][j++]);
            dto.setName(values[i][j++]);
            dto.setRemarks(values[i][j++]);
            dto.setRowNumber(i + 1);

            dtoes.add(dto);
        }

        List<String> returnValues = new ArrayList<String>();

        //Create a return value by prefixing the line number.
        for (Dto dto : dtoes) {
            String line =
                    dto.getRowNumber() + "\t" +
                    dto.getId() + "\t" +
                    dto.getRemarks();
            returnValues.add(line);
        }

        return returnValues;
    }

    /**Intermediate class for processing**/
    private class Dto {
        private int rowNumber;
        private String Id;
        private String name;
        private String remarks;

        public int getRowNumber() {
            return rowNumber;
        }

        public void setRowNumber(int rowNumber) {
            this.rowNumber = rowNumber;
        }

        public String getId() {
            return Id;
        }

        public void setId(String id) {
            Id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getRemarks() {
            return remarks;
        }

        public void setRemarks(String remarks) {
            this.remarks = remarks;
        }

Summary

If it's a data structure, you should first consider making it a class. If you don't understand the class, why not start by studying object-oriented programming?

Also, writing with arrays was common in VB6, but I think many programmers couldn't shift to object-oriented when they moved to .Net.

2017/4/9 postscript In the comment section, it was pointed out that the process of converting to Dto should be a method, so I will list the code that made the process a method.

After refactoring

Not only values => Dto, but also Dto => Tsv is a method.

        /*A line number is added to the passed data line and returned.
         *However, it is in Tsv format excluding Name.
         *ID in row and column format for values,Name,Remarks are stored.
         */
        public List<string> GetTsvWithRowNumber(string[][] values)
        {
            var dtoes = CreateDtoes(values);

            var returnValues = ConvertToTsv(dtoes);

            return returnValues;
        }

        /**Generate Dto**/
        private List<Dto> CreateDtoes(string[][] values)
        {
            var dtoes = new List<Dto>(values.Length);

            //Convert to Dto.
            for (int i = 0; i < values.Length; i++)
            {
                int j = 0;
                var dto = new Dto();
                dto.Id = values[i][j++];
                dto.Name = values[i][j++];
                dto.Remarks = values[i][j++];
                dto.RowNumber = i + 1;

                dtoes.Add(dto);
            }

            return dtoes;
        }

        /**Convert Dto to Tsv.**/
        private List<string> ConvertToTsv(List<Dto> dtoes)
        {
            var lines = new List<string>();

            //Create a return value by prefixing the line number.
            foreach (var dto in dtoes)
            {
                var line =
                    dto.RowNumber + "\t" +
                    dto.Id + "\t" +
                    dto.Remarks;
                lines.Add(line);
            }
            return lines;
        }

        /**Intermediate class for processing**/
        private class Dto
        {
            public int RowNumber { get; set; }
            public string Id { get; set; }
            public string Name { get; set; }
            public string Remarks { get; set; }

        }
java
   /*A line number is added to the passed data line and returned.
     *However, it is in Tsv format excluding Name.
     *ID in row and column format for values,Name,Remarks are stored.
     */
    public List<String> getTsvWithRowNumber(String[][] values) {

        List<Dto> dtoes = createDtoes(values);

        List<String> returnValues = convertToTsv(dtoes);

        return returnValues;
    }

    private List<Dto> createDtoes(String[][] values) {
        List<Dto> dtoes = new ArrayList<Dto>(values.length);

        //Convert to Dto.
        for (int i = 0; i < values.length; i++) {
            int j = 0;
            Dto dto = new Dto();
            dto.setId(values[i][j++]);
            dto.setName(values[i][j++]);
            dto.setRemarks(values[i][j++]);
            dto.setRowNumber(i + 1);

            dtoes.add(dto);
        }
        return dtoes;
    }

    private List<String> convertToTsv(List<Dto> dtoes) {
        List<String> lines = new ArrayList<String>();

        //Create a return value by prefixing the line number.
        for (Dto dto : dtoes) {
            String line =
                    dto.getRowNumber() + "\t" +
                    dto.getId() + "\t" +
                    dto.getRemarks();
            lines.add(line);
        }
        return lines;
    }

    /**Intermediate class for processing**/
    private class Dto {
        private int rowNumber;
        private String Id;
        private String name;
        private String remarks;

        public int getRowNumber() {
            return rowNumber;
        }

        public void setRowNumber(int rowNumber) {
            this.rowNumber = rowNumber;
        }

        public String getId() {
            return Id;
        }

        public void setId(String id) {
            Id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getRemarks() {
            return remarks;
        }

        public void setRemarks(String remarks) {
            this.remarks = remarks;
        }



Previous article (Getter, Setter inverse problem)

Next article (when processing after conditional branching is redundant)

Table of Contents

Recommended Posts

Anything Array-11 [C # Refactoring Sample]
Getter, Setter Inverse Problem-10 [C # Refactoring Sample]
Problems using screen display values-13 [C # refactoring sample]
When the processing after conditional branching is redundant-12 [C # refactoring sample]
Convert Swift 2D array to C 2D array