You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesi贸n a prueba de IA

Antes: $249

Currency
$209
Suscr铆bete

Termina en:

0 D铆as
8 Hrs
17 Min
31 Seg

Code Smells

6/14
Resources

What is a co-smell and how to identify it?

The term co-smell is fundamental to ensure that the code we develop is efficient and understandable. It is a concept that refers to the "feeling" that something is not right in the code, similar to when something "smells bad". Although we do not have an exact equivalent in English, we can say that we perceive that something is not right or can be improved. These perceptions develop with practice and experience, allowing us to identify errors quickly. Let's explore some common examples of co-smells and how to recognize them.

How do we recognize a co-smell in the appointment?

One of the most common co-smells is the improper naming of variables, methods or classes. Names should be as descriptive as possible. Otherwise, when reading the code, the lack of clarity in the names can confuse the developer and make it difficult to understand the logical flow. If the names do not correctly inform about their function or content, there is a high probability that we are dealing with a co-smell.

Are long methods and classes an indicator?

Yes, overly long classes and methods represent another co-smell. Although there is no exact standard for length, if a class exceeds 1000 or 1500 lines of code, it is a red flag. Generally, this indicates that the class has too many responsibilities that could be divided into smaller, specialized components, thus improving code comprehension and maintainability.

What happens with methods that use many parameters?

When a method or function begins to accumulate many parameters, it can trigger a co-smell. The multiplicity of parameters can indicate that there is a lot of logic and flows within the function that complicate its readability. If you see a method overloaded with parameters, it is likely that internally there are problems that need to be evaluated and corrected.

What are magic numbers and how to avoid them?

"Magic numbers" are numeric values that are directly inserted into the code, without a clear explanation of their purpose. Their use is considered bad practice because developers must perform additional analysis to understand what they mean and why they are there. This co-smell can be solved by using constants with descriptive names or by enumerations.

enum Menu{ Add = 1, Remove = 2, List = 3, Exit = 4}

In this example, we have replaced straightforward numbers with a clear enumeration for a menu, which makes the code easier to understand. Thus, instead of the number, we see a name that explains the functionality.

How to improve the code by avoiding co-smells?

The key to avoid co-smells is to apply good practices from the beginning of the development:

  • Descriptive name: Use clear and meaningful names for variables, functions and classes.
  • Divide and conquer: If a method or class is too large, break it into smaller, more manageable parts.
  • Avoid excessive parameters: If a method needs too many parameters, review its structure; it may need to be reorganized or subdivided.
  • Assign meanings: Replace magic numbers with constants or descriptive enumerations.

These tips are not exhaustive, but they are a good starting point. Exploring documentation and continuing to learn about new coding practices will be crucial to refine your skills. The world of development is vast and there is always something new to learn!

Contributions 19

Questions 4

Sort by:

Want to see more contributions, questions and answers from the community?

Code Smell, "Demasiados parametros"
Creo que se puede resolver pasando una clase o dos como parametro algo como esto:

var numerosSumados = new ValoresNumericos
{
  primerValor = 20, 
  segundoValor = 20
}

var opcionesCalculoSuma = new opcionesDeFormato
{
   cantidadDecimales  = 2, 
   tituloSalidaTerminal = "Total de suma 2 parametros",
   tipoDeOperacion = OperacionAritmetica.Suma

}


public double Calculation( VarloresNumericos numerosCalculo, opcionesDeFormato opcionesFormatoCalculo)
.
.
.

creo que hay otras formas mas elegantes de escribir ese codigo, lo importante es que me parece que las funciones con menos de 4 parametros son mas faciles de leer.

驴Que opinan?

Para evaluar code smells, us茅 mucho Sonarqube, como herramienta de an谩lisis est谩tico. Las reglas para detectar code smells (incluso otras reglas que veremos mas adelante) me ayudaron a entender y mejorar mucho la programaci贸n, vale la pena revisarlas e ir entendi茅ndolas.
https://rules.sonarsource.com/csharp/type/Code Smell

Lo hice de esta forma, ya que usar if en un programa grande es mas optimo usar switch y ademas si la comparacion es de solo igual a, lo mejor es usar switch
<code>

TaskList = new List<string>();
            int menuselected = 0;
            do
            {
                menuselected = ShowMainMenu();
               switch (menuselected)
               {
                case 1:
                ShowMenuAdd();
                break;

                case 2:
                ShowMenuRemoveTask();
                break;

                case 3:
                ShowMenuTaskList();
                break;

               }
            } while (menuselected != 4);
***Code smell*** es un t茅rmino utilizado en el desarrollo de software para describir signos o indicios de que puede haber problemas en el c贸digo fuente. Estos indicios no son necesariamente errores de programaci贸n o bugs, pero sugieren que el c贸digo podr铆a beneficiarse de mejoras, refactoring o una revisi贸n m谩s detallada. 1. **Nombres de variables errados:** Nombres poco claros o gen茅ricos pueden hacer que el c贸digo sea dif铆cil de entender. 2. **Clases o m茅todos largos:** Clases o m茅todos que son excesivamente largos y realizan m煤ltiples tareas pueden ser dif铆ciles de entender y mantener. 3. **Demasiados par谩metros:** Clases o m贸dulos con una gran cantidad de atributos y m茅todos pueden indicar una falta de cohesi贸n y responsabilidades excesivas. 4. **N煤meros m谩gicos:** Se refiere a valores literales o constantes que se utilizan directamente en el c贸digo en lugar de ser asignados a variables con nombres descriptivos. Algunos otros son: 1. **C贸digo duplicado:** Repetici贸n innecesaria de fragmentos de c贸digo que podr铆an ser reutilizados o abstra铆dos en funciones o clases. 2. **Anidaci贸n excesiva de bucles o condicionales:** Demasiados niveles de anidaci贸n pueden complicar el flujo del programa. 3. **Dependencias circulares:** Cuando las clases tienen dependencias circulares, puede ser un signo de un acoplamiento excesivo y una mala arquitectura. 4. **Comentarios excesivos o in煤tiles:** La necesidad de comentarios excesivos a menudo indica que el c贸digo no es lo suficientemente claro por s铆 mismo. 5. **C贸digo muerto:** C贸digo que no se utiliza y est谩 presente en el repositorio, lo que puede confundir a los desarrolladores.

Recomiendo esta extension. SonarLint
Detects and helps fix issues in your C# code locally in your IDE

La traducci贸n al espa帽ol es "huele a chamusquina".

Esta clase me hizo recordar a cuando en mi trabajo pasado hab铆a un archivo con m谩s de 20k lineas de c贸digo

Ejemplo con el Enum Menu y con switch: ```js do { menuSelected = ShowMainMenu(); switch ((Menu)menuSelected) { case Menu.Add: ShowMenuAdd(); break; case Menu.Remove: ShowMenuRemove(); break; case Menu.List: ShowMenuTaskList(); break; } } while ((Menu)menuSelected != Menu.Exit); ```
**Code smell:** * **Nombramiento:** Mal nombramiento. * **M茅todos o clases largas:** Muchas l铆neas de c贸digo agrupadas en un bloque. * **N煤mero de par谩metros considerable:** Muchos par谩metros (ej: 6 en adelante). * **N煤meros m谩gicos:** N煤meros que se utilizan directamente quemados y se desconoce el significado o utilidad. * **Entre otros.**
yo opte por swicht ya que se me hace mas practico para ste caso en especifico sin hacer el enum ` do` ` {` ` menuSelected = ShowMainMenu();` ` switch (menuSelected)` ` {` ` case 1:` ` menuSelected = 1;` ` ShowMenuAdd();` ` break;` ` case 2:` ` menuSelected = 2;` ` ShowMenuRemove();` ` break;` ` case 3:` ` menuSelected = 3;` ` ShowMenuTaskList();` ` break;` ` case 4:` ` menuSelected = 4;` ` break;` ` default:` ` Console.WriteLine("porfavor ingresa una opcion valida");` ` break;` ` }` ` } while (menuSelected != 4);`
public enum Menu {聽 聽 聽 聽 Add =1,聽 聽 聽 聽 Remove = 2,聽 聽 聽 聽 List = 3,聽 聽 聽 聽 Exit = 4 聽 聽 }
"Tu c贸digo huele feo" puede ser literal. Algo m谩s en t茅rminos de espa帽ol, un poco m谩s v铆vida la misma idea, ser铆a: "Tu c贸digo est谩 escrito con las patas." o quiz谩: "Tu c贸digo no tiene pies ni cabeza."
Los "code smells" (o "malos olores del c贸digo") en C# se refieren a ciertos patrones o estructuras en el c贸digo que indican posibles problemas de dise帽o o implementaci贸n. Estos "smells" a menudo se帽alan 谩reas donde el c贸digo podr铆a mejorarse para tener una mejor legibilidad, mantenibilidad y eficiencia. Aqu铆 tienes algunos "code smells" comunes en C#: 1\. \*\*M茅todos largos\*\*: Los m茅todos excesivamente largos pueden ser dif铆ciles de entender, probar y mantener. Div铆delos en m茅todos m谩s peque帽os y enfocados. 2\. \*\*Clases grandes\*\*: Similar a los m茅todos largos, las clases que son demasiado grandes a menudo indican que est谩n haciendo demasiado. Considera dividirlas en clases m谩s peque帽as y cohesivas. 3\. \*\*Obsesi贸n por lo primitivo\*\*: El uso excesivo de tipos primitivos (como cadenas o enteros) en lugar de crear tipos espec铆ficos del dominio puede conducir a un c贸digo menos expresivo y menos mantenible. Crea tipos personalizados para representar conceptos del dominio. 4\. \*\*C贸digo repetido\*\*: El c贸digo duplicado debe evitarse ya que conlleva sobrecarga de mantenimiento y posibles errores. Refactoriza el c贸digo duplicado en m茅todos o clases reutilizables. 5\. \*\*Listas de par谩metros largas\*\*: Los m茅todos con un gran n煤mero de par谩metros pueden ser dif铆ciles de usar y entender. Considera usar objetos de par谩metros o dividir el m茅todo en otros m谩s peque帽os y enfocados. 6\. \*\*Intimidad inapropiada\*\*: Las clases que est谩n demasiado acopladas violan el principio de encapsulaci贸n y pueden ser dif铆ciles de mantener y probar. Reduce las dependencias entre clases usando interfaces, inyecci贸n de dependencias u otros patrones de dise帽o. 7\. \*\*Nomenclatura inconsistente\*\*: Las convenciones de nomenclatura inconsistentes hacen que el c贸digo sea m谩s dif铆cil de entender. Usa una nomenclatura clara y consistente en todo tu c贸digo. 8\. \*\*Envidia de caracter铆sticas\*\*: Cuando un m茅todo accede a los datos de otra clase m谩s que a los suyos propios, puede indicar que el m茅todo pertenece a la otra clase. Considera mover el m茅todo a la clase que posee los datos. 9\. \*\*Grandes instrucciones SWITCH o IF-ELSE\*\*: Las instrucciones switch y las cadenas if-else largas pueden ser dif铆ciles de mantener y extender. Considera usar polimorfismo, el patr贸n de estrategia o tablas de b煤squeda para manejar estos casos de manera m谩s elegante. 10\. \*\*Grupos de datos\*\*: Cuando grupos de campos de datos se pasan frecuentemente juntos, puede indicar que deber铆an estar juntos en su propia clase. Crea una nueva clase para encapsular campos de datos relacionados. 11\. \*\*Clases Dios\*\*: Clases que saben o hacen demasiado, violando el Principio de Responsabilidad 脷nica. Refactoriza estas clases en otras m谩s peque帽as y enfocadas. 12\. \*\*Complejidad ciclom谩tica\*\*: Alta complejidad ciclom谩tica en los m茅todos puede indicar una l贸gica demasiado compleja que es dif铆cil de entender y probar. Refactoriza estos m茅todos en piezas m谩s peque帽as y manejables. Al identificar y abordar estos "code smells", puedes mejorar la calidad, legibilidad y mantenibilidad de tu base de c贸digo en C#.
Code Smells en C#: ------------------ **驴Qu茅 son?** Los Code Smells son indicadores de posibles problemas en tu c贸digo que pueden afectar su mantenimiento, legibilidad y probabilidad de errores. **Ejemplos comunes en C#:** * **Clases grandes:** Dificultad de comprensi贸n y mantenimiento. * **M茅todos largos:** Complejidad y dificultad para refactorizar. * **Duplicaci贸n de c贸digo:** Mantenimiento ineficiente y errores repetitivos. * **Nombres inconsistentes:** Dificultad para comprender el prop贸sito del c贸digo. * **Comentarios excesivos:** Posible indicador de c贸digo complejo o mal escrito. * **Falta de pruebas:** Dificultad para detectar y corregir errores. **驴Por qu茅 son importantes?** Detectar y corregir los Code Smells a tiempo puede ayudarte a: * **Mejorar la legibilidad y mantenibilidad del c贸digo.** * **Reducir la probabilidad de errores.** * **Facilitar la refactorizaci贸n y el mantenimiento del c贸digo.** **驴C贸mo prevenirlos?** * **Seguir buenas pr谩cticas de codificaci贸n.** * **Utilizar herramientas de an谩lisis de c贸digo.** * **Realizar revisiones de c贸digo con regularidad.**
Hay unos libros recomendados para aprender estas buenas pr谩cticas "The clean code" y de "Clean Coder" escritos por Bob Martin, conocido tambi茅n Como Uncle Bob, y tienen acumulados muchos a帽os de desarrollo y buenos pr谩cticas

Vivi toda mi vida enganado pensando que utilizar los numero magicos estaba bien

De la clase anterior (Y)

using System;
using System.Collections.Generic;

namespace ToDo
{
    internal class Program
    {
        private static List<string> taskList;

        //public static List<string> TL { get; set; } --> Malas practicas
        public static List<string> GetTaskList()
        {
            return taskList;
        }

        //public static List<string> TL { get; set; } --> Malas practicas
        public static void SetTaskList(List<string> value)
        {
            taskList = value;
        }

        static void Main(string[] args)
        {
            SetTaskList(new List<string>());
            int menuSelected = 0;
            do
            {
                menuSelected = ShowMainMenu();
                if (menuSelected == 1)
                {
                    ShowMenuAdd();
                }
                else if (menuSelected == 2)
                {
                    ShowMenuRemove();
                    //Mala practica ShowMenuDos: debe decir siempre la funci贸n que cumple!
                }
                else if (menuSelected == 3)
                {
                    ShowMenuTaskList();
                    //Mala practica ShowMenuTres: debe decir siempre la funci贸n que cumple!

                }
            } while (menuSelected != 4);
        }
        /// <summary>
        /// Show the main menu 
        /// </summary>
        /// <returns>Returns option indicated by user</returns>
        public static int ShowMainMenu()
        {
            Console.WriteLine("----------------------------------------");
            Console.WriteLine("Ingrese la opci贸n a realizar: ");
            Console.WriteLine("1. Nueva tarea");
            Console.WriteLine("2. Remover tarea");
            Console.WriteLine("3. Tareas pendientes");
            Console.WriteLine("4. Salir");

            // Read line
            string taskIndex = Console.ReadLine();
            return Convert.ToInt32(taskIndex);
        }

        public static void ShowMenuRemove()
        {
            try
            {
                Console.WriteLine("Ingrese el n煤mero de la tarea a remover: ");
                // Show current taks
                for (int i = 0; i < GetTaskList().Count; i++)
                {
                    Console.WriteLine((i + 1) + ". " + GetTaskList()[i]);
                }
                Console.WriteLine("----------------------------------------");

                string taskIndex = Console.ReadLine();
                // Remove one position
                int indexToRemove = Convert.ToInt32(taskIndex) - 1;
                if (indexToRemove > -1)
                {
                    if (GetTaskList().Count > 0)
                    {
                        string taskToRemove = GetTaskList()[indexToRemove];
                        GetTaskList().RemoveAt(indexToRemove);
                        Console.WriteLine("Tarea " + taskToRemove + " eliminada");
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public static void ShowMenuAdd()
        {
            try
            {
                Console.WriteLine("Ingrese el nombre de la tarea: ");
                string task = Console.ReadLine();
                GetTaskList().Add(task);
                Console.WriteLine("Tarea registrada");
            }
            catch (Exception)
            {
            }
        }

        public static void ShowMenuTaskList()
        {
            if (GetTaskList() == null || GetTaskList().Count == 0)
            {
                Console.WriteLine("No hay tareas por realizar");
            }
            else
            {
                Console.WriteLine("----------------------------------------");
                for (int i = 0; i < GetTaskList().Count; i++)
                {
                    Console.WriteLine((i + 1) + ". " + GetTaskList()[i]);
                }
                Console.WriteLine("----------------------------------------");
            }
        }
    }
}

C贸digo actualizado:

using System;
using System.Collections.Generic;

namespace ToDo
{
    internal class Program
    {
        public static List<string> TaskList { get; set; }

        static void Main(string[] args)
        {
            TaskList = new List<string>();
            int menuOption = 0;
            do
            {
                menuOption = ShowMainMenu();
                if ((Menu)menuOption == Menu.Add)
                {
                    AddTask();
                }
                else if ((Menu)menuOption == Menu.Remove)
                {
                    RemoveTask();
                }
                else if ((Menu)menuOption == Menu.List)
                {
                    ShowTaskList();
                }
            } while ((Menu)menuOption != Menu.Exit);
        }
        /// <summary>
        /// Show the main menu 
        /// </summary>
        /// <returns>Returns menuOption indicated by user</returns>
        public static int ShowMainMenu()
        {
            Console.WriteLine("----------------------------------------");
            Console.WriteLine("Ingrese la opci贸n a realizar: ");
            Console.WriteLine("1. Nueva tarea");
            Console.WriteLine("2. Remover tarea");
            Console.WriteLine("3. Tareas pendientes");
            Console.WriteLine("4. Salir");

            // Read taskIndex
            string taskIndex = Console.ReadLine();
            return Convert.ToInt32(taskIndex);
        }

        public static void RemoveTask()
        {
            try
            {
                Console.WriteLine("Ingrese el n煤mero de la tarea a remover: ");
                // Show current taks
                for (int i = 0; i < TaskList.Count; i++)
                {
                    Console.WriteLine((i + 1) + ". " + TaskList[i]);
                }
                Console.WriteLine("----------------------------------------");

                string taskIndex = Console.ReadLine();
                // Remove one position
                int indexToRemove = Convert.ToInt32(taskIndex) - 1;
                if (indexToRemove > -1)
                {
                    if (TaskList.Count > 0)
                    {
                        string taskToRemove = TaskList[indexToRemove];
                        TaskList.RemoveAt(indexToRemove);
                        Console.WriteLine("Tarea " + taskToRemove + " eliminada");
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public static void AddTask()
        {
            try
            {
                Console.WriteLine("Ingrese el nombre de la tarea: ");
                string taskToAdd = Console.ReadLine();
                TaskList.Add(taskToAdd);
                Console.WriteLine("Tarea registrada");
            }
            catch (Exception)
            {
            }
        }

        public static void ShowTaskList()
        {
            if (TaskList == null || TaskList.Count == 0)
            {
                Console.WriteLine("No hay tareas por realizar");
            } 
            else
            {
                Console.WriteLine("----------------------------------------");
                for (int i = 0; i < TaskList.Count; i++)
                {
                    Console.WriteLine((i + 1) + ". " + TaskList[i]);
                }
                Console.WriteLine("----------------------------------------");
            }
        }
    }

    public enum Menu
    {
        Add = 1,
        Remove = 2,
        List = 3,
        Exit = 4
    }
}