La refactorización en C# es clave para escalar con orden y claridad. Aquí verás cómo mover la lógica del proyecto a un motor de aplicación para separar responsabilidades, mejorar el mantenimiento y preparar datos de prueba reutilizables de forma rápida y segura, trabajando en Visual Studio Code con un enfoque profesional.
¿Cómo refactorizar y organizar el proyecto en C# de forma profesional?
La prioridad es ordenar el código y delegar responsabilidades. La clase Programa solo debe iniciar la ejecución; la lógica de la escuela debe vivir en un engine dedicado.
¿Qué cambios iniciales mejoran la estructura del proyecto?
Eliminar comentarios y código con arreglos ya obsoletos.
Crear carpeta app para la lógica principal.
Crear la clase Escuela Engine como el motor principal.
Unificar el namespace a Core Escuela y alinear todos los archivos.
Incorporar el espacio de nombres de entidades: core escuela punto entidades.
¿Cómo definir el motor con una propiedad pública?
Hacer pública la clase Escuela Engine.
Exponer una propiedad pública para acceder a la escuela: Escuela escuela.
Asegurar accesibilidad consistente: resolver el error inconsistent accessibility type haciendo pública la entidad Escuela.
publicclassEscuelaEngine{publicEscuela escuela {get;set;}publicEscuelaEngine(){// escuela = new Escuela(...);}publicvoidInicializar(){// Inicializa escuela y cursos.}}
¿Qué rol juega el namespace unificado Core Escuela?
Centraliza la identidad del proyecto.
Evita conflictos al mover archivos y carpetas.
Facilita ubicar clases como Escuela y colecciones de cursos.
¿Cómo inicializar la escuela sin sobrecargar el constructor?
El constructor debe ser rápido y evitar entrada y salida: nada de archivos, redes ni bases de datos. Por eso, la creación de datos se mueve a un método dedicado.
¿Qué patrón usar para la inicialización de datos?
Mantener el constructor vacío o mínimo: solo prepara el objeto.
Crear un método público void Inicializar para poblar escuela, cursos y demás.
Facilitar pruebas con datos rápidos y reutilizables.
¿Cómo organizar los cursos y colecciones?
Usar el namespace de colecciones cuando se manejen listas.
Mantener pocos cursos al inicio: tres son suficientes para comenzar.
Conservar los cursos 401 y 501 en jornada tarde.
Dejar configuraciones hasta grado quinto como base.
¿Qué ventajas trae separar responsabilidades?
Mejora la legibilidad: Programa inicia; el engine gestiona la lógica.
Permite crecer con asignaturas, alumnos y evaluaciones más adelante.
Facilita pruebas y cambios sin romper el arranque.
¿Cómo ejecutar y validar la refactorización en Visual Studio Code?
Con el engine listo, el Programa instancia, inicializa y usa los datos con claridad. Luego se valida la salida ejecutando el proyecto.
¿Qué pasos seguir en el programa principal?
Crear instancia: engine = new Escuela Engine.
Llamar a engine.Inicializar para poblar datos.
Reusar funciones como imprimir cursos de escuela pasando engine.escuela.
¿Cómo verificar el resultado y datos de ejemplo?
Abrir una terminal e iniciar con dotnet run.
Observar la salida: títulos como cursos de la escuela.
Ver listados contemplados: cursos 401 y 501 en jornada tarde.
¿Qué sigue para ampliar el dominio académico?
Agregar objetos del dominio: asignaturas, alumnos, evaluaciones.
Mantener el patrón: inicializar en métodos específicos, no en el constructor.
Preparar más datos de prueba reutilizables según escenarios.
¿Tienes dudas sobre la organización del engine o la inicialización de datos en C#? Cuéntalo en comentarios y conversemos sobre tu caso.
Considero que la refactorizacion que se define como una técnica de la ingeniería de software para reestructurar un código fuente, alterando su estructura interna sin cambiar su comportamiento externo, va a la mano con los principios solid que son
S-Responsabilidad simple Este principio trata de destinar cada clase a una finalidad sencilla y concreta.
O-Abierto/Cerrado Principio atribuido a Bertrand Meyer que habla de crear clases extensibles sin necesidad de entrar al código fuente a modificarlo. Es decir, el diseño debe ser abierto para poderse extender pero cerrado para poderse modificar.
L-Sustitucion Liskov Este principio fue creado por Barbara Liskov y habla de la importancia de crear todas las clases derivadas para que también puedan ser tratadas como la propia clase base. Cuando creamos clases derivadas debemos asegurarnos de no reimplementar métodos que hagan que los métodos de la clase base no funcionases si se tratasen como un objeto de esa clase base.
I-Segregacion del interface Este principio fue formulado por Robert C. Martin y trata de algo parecido al primer principio. Cuando se definen interfaces estos deben ser específicos a una finalidad concreta. Por ello, si tenemos que definir una serie de métodos abstractos que debe utilizar una clase a través de interfaces, es preferible tener muchos interfaces que definan pocos métodos que tener un interface con muchos métodos.
El objetivo de este principio es principalmente poder reaprovechar los interfaces en otras clases. Si tenemos un interface que compara y clona en el mismo interface, de manera más complicada se podrá utilizar en una clase que solo debe comparar o en otra que solo debe clonar.
D-Inversión de dependencias También fue definido por Robert C. Martin. El objetivo de este principio conseguir desacoplar las clases. En todo diseño siempre debe existir un acoplamiento pero hay que evitarlo en la medida de lo posible. Un sistema no acoplado no hace nada pero un sistema altamente acoplado es muy difícil de mantener
:thumbsup:
Excelente comentario. Gracias.
Se esta poniendo hardcore
Nota: Seria bueno colocar como nombre de espacio CoreEscuela.App a muestra clase EscuelaEngine por si queremos agregar mas motores a nuestro proyecto.
Realmente se esta volviendo confuso. No entiendo la técnica haberlo hecho "mal" para después refactorizar. Debería primero explicarse en base a la "buena practica" y después comparar con un código mal hecho. Otra cosa: los nombre del namespace las clases confunde, debería tener nombres mas representativos. Ademas, para ser "fundamentos" va un poco rápido, sin explicar ciertas cosas... bueno, igual seguimos.
y cierttas cosas como cuales? 😰
Precisamente al ser un curso básico se explican cosas de una forma básica, aunque ello conlleve a malas prácticas, lo importante es entenderlo poco a poco. Cuando ya ciertos conceptos se entienden se pasa a lo siguiente. Una vez se han asentado esos conocimientos y se entiende la base refactorizas el código para de una vez ver unas mejores prácticas. Es como cuando aprendes a ir en bicicleta con ruedas auxiliares y cuando sabes mantener el equilibrio las quitas.
Para esta clase la premisa principal es la de Refactorizar el código
Para: tenerlo ordenado, que a medida que vaya creciendo podamos tener un orden en nuestro código y sea más fácil de manejar
Lo primero que se hará es al ver la explicación en la carpeta donde está el proyecto crear otra más que se llamará Etapa 4
Dentro de esta carpeta de la misma manera que se hizo para Etapa 1 se digitará en la ventana de consola dotnet new console
Una vez realizado esto se creará los archivos que tenía hasta el instante la Etapa1. Se copiará el contenido.
Posterior a esto se irá borrando el código que no queramos entre ellos los comentarios.
A continuación se creará una carpeta que se llamará app, aquí irá la lógica de la aplicación.
En esta carpeta crearemos el motor de la aplicación con un archivo que se llamará EscuelaEngine.cs
Siguiendo con los cambios a implementar se cambia el namespace en Program.cs se llamará CoreEscuela. Posterior a este cambio se deberá verificar si está cambiado automáticamente el namespace para los otros archivos.
Se crea la clase EscuelaEngine.cs con una propiedad pública que pueda encapsular . Además en el constructor no se manipulará entrada y salida de datos debe ser tan rápido como sea posible, para ello se creará un método en donde contendrá la información de la escuela con sus cursos.
Para finalizar en el programa principal se inicializa este método y se imprime los cursos con la función que teníamos ya realizada
var engine=newEscuelaEngine();engine.Inicializar();imprimirCursosEscuela(engine.Escuela)
Es importante refactorizar nuestro código para mantenerlo ordenado.
El constructor de una clase tiene que ser tan rápido como sea posible, tiene que estar desconectado de cualquier cosa que implique entrada y salida.
Huy profe Juan, muy buenos lineamientos de refactorización !! Gracias …
El método ImprimirCursosEscuela no debería ir en la clase EngineEscuela también? ya que forma parte de la lógica de negocio.
Pienso igual.
Un poco confuso pero estoy tratando hay vamos
Animo, solo ten paciencia y ganas de aprender.
En el minuto 3:05 abre un cuadro blanco para las posibles soluciones ¿Cómo se activa aquello?
Colocar el puntero donde aparece subrayado
Ctrl + . para desplegar las opciones que recomienda VS Code.
Hola!
Alguien me puede indicar como solucionar este error
La verdad no se que hacer, ya intente cambiando la clase Curso a public y nada que me funciona
hola si bien no se puede ver el código deverias fijarte en alparte de referencias y hacer la referencia correspondiete por mas que tengas la clausula using .
Hola @Diiegor
¿que nivel de accesibilidad le diste a la clase Cursos ?
Asegurate se haberle puesto public , recuerdad que si no declaras la accesibilidad las clases o metodos por defecto quedan en private y no puedes accederlas desde otras clases.
por que los métodos la clases estáticas deben ser estáticos no lo explico dijo que lo iba hacer y no lo hizo alguien sabe
por fin pasamos a la etapa 4 del curso de este maravilloso lenguaje
Se nota lo que hemos aprendido durante el curso.
Ah alguien mas le tira error al crear la clase EscuelaEngine?? como lo solucionaron
Hola,
creo haber escrito el código con tanto cuidado como he tenido, se que generalmente los errores son por teclear mal, o por no definir correctamente las clases y métodos, el código compartido por Luis a la altura del video difiere, y no quiero utilizar ese código sin entenderlo.
podrían guiarme para resolver el problema que se me esta presentando?
por que al iniciar el List<Cursos> desde el método si funciona, y al iniciarlo desde el Constructor de la clase EngineEscuela, como se ve en el video, No?
Hago el codigo igual que el video y me da muchos errores.
1ro: el public class EscuelaEngine
Error: class CoreEscuela.EscuelaEngine
El espacio de nombres 'CoreEscuela' ya contiene una definición para 'EscuelaEngine' [etapa1, etapa1]csharp(CS0101)
2do public EscuelaEngine
Error: EscuelaEngine.EscuelaEngine()
El elemento propiedad "Escuela" que no acepta valores NULL debe contener un valor distinto de NULL al salir del constructor. Considere la posibilidad de declarar el elemento propiedad como que admite un valor NULL. [etapa1, etapa1, etapa1, etapa1, etapa1, etapa1, etapa1, etapa1]csharp(CS8618)
El tipo 'EscuelaEngine' ya define un miembro denominado 'EscuelaEngine' con los mismos tipos de parámetro [etapa1, etapa1]csharp(CS0111)
3ro public void Inicializar
Error: void EscuelaEngine.Inicializar()
El tipo 'EscuelaEngine' ya define un miembro denominado 'Inicializar' con los mismos tipos de parámetro [etapa1, etapa1]csharp(CS0111)
4to Escuela. Dentro de inicializar.
Error: Entidades.Escuela EscuelaEngine.Escuela { get; set; }
"Escuela" no es NULL aquí.
Ambigüedad entre 'EscuelaEngine.Escuela' y 'EscuelaEngine.Escuela' [etapa1, etapa1, etapa1, etapa1]csharp(CS0229)
Alguien me puede ayudar me estoy volviendo loco con este profesor. Borra - hace. Borra - hace. Borra - hace.
Y a mi me siguen saliendo errores
Pudiste solucionarlo?? me sale el mismo de "El espacio de nombres 'CoreEscuela' ya contiene una definición para 'EscuelaEngine' [etapa1, etapa1]csharp(CS0101)"
Bro, no se si ya hayas podido solucionar el error, pero te comparto lo que yo hice para resolver
Cree un proyecto en blanco en una carpeta de nombre "CoreEscuela"
Abri el proyecto en VSC y comence a crear las clases correspondientes del proyecto y a copiarlas y pegarlas en el nuevo proyecto (en la carpeta "CoreEscuela"), ejecute y sin errores..
Opte por realizar esto ya que al solucionar el error CS0101, me salian mas errores asociados a: [etapa1, etapa1], y en vista de que VSC me creo muchos archivos en los cuales ya estaba seteado el nombre "Etapa1", opte mejor por copiar el codigo de las clases en un proyecto nuevo
¿La palabra reservada void es para definir un método que no retorne algo concretamente con return, o que igual puede retornar algún mensaje con el Console.Write por ej.., pero no tener explícitamente el return?
¡Hola! void es para expresar explícitamente que tu función no va a retornar nada. Un Console.Write no retorna nada, sino que escribe en la consola. Se dice que tu función retorna algo en el momento en el que escribes return, pero si tú lo escribes dentro de una función void lo más probable es que te de un error 👀
Buenas comparto codigo utilizado en todo el curso practico...
using System;using System.Runtime.Serialization.Json;using CoreEscuela;// See https://aka.ms/new-console-template for more informationusing CoreEscuela.Entidades;var engine =newEscuelaEngine();Console.WriteLine("=======================================");Imprimir(engine.Escuela);staticvoidImprimir(Escuela escuela){Console.WriteLine("=======================");Console.WriteLine("Cursos de la Escuela 12");Console.WriteLine("=========================");if(escuela?.Cursos!=null){foreach(var curso in escuela.Cursos){Console.WriteLine($"Nombre: {curso.Nombre}, CursoId: {curso.CursoId}");}}}// Console.WriteLine("Hello, World!");/* Agregando datos Escuela */// Escuela es = new Escuela("Escuela Basicas",1995,TiposEscuela.Primaria,ciudad: "Medellin", pais: "Colombia");/* Agregando cursos
Curso cursos1 = new Curso();
cursos1.Nombre="Pruebas";
cursos1.Jornada =TiposJornada.Manaña;
var curso2 = new Curso()
{
Nombre = "102",
Jornada = TiposJornada.Tarde
};
*//* agregando cursos utilizando arrays[]
var arrayCursos = new Curso[3];
arrayCursos[0] = new Curso(){
Nombre = "301",
Jornada = TiposJornada.Noche
} ;
var cursos2 = new Curso(){
Nombre="302",
Jornada = TiposJornada.Noche
};
arrayCursos[1] = cursos2;
arrayCursos[2] = new Curso(){
Nombre = "303",
Jornada = TiposJornada.Noche
};
*//* Agregando cursos utilizando listas List<>
var listas1 = new List<Curso>(){
new Curso(){Nombre = "505"},
new Curso(){Nombre = "506"},
new Curso(){Nombre = "507"}
};
var listas2 = new List<Curso>(){
new Curso(){Nombre="401"},
new Curso(){Nombre="402"}
};
listas1.Add(new Curso{Nombre="508"});
*//*Agregando cursos Escuela
//es.Cursos.Add(new Curso(){Nombre="401", Jornada = TiposJornada.Manaña});
*//* Agregando cursos a otra lista existente
listas1.AddRange(listas2);
listas1.RemoveAll(delegate (Curso cur){
return cur.Nombre=="402";
});
*//* Eliminar un curso con un nombre especifico
listas1.RemoveAll((cur) => cur.Nombre.Equals("506"));
*/// SALIDAS// Console.WriteLine(es.Nombres);// Console.WriteLine("=======================================");// Console.WriteLine(cursos1.Nombre + "," + cursos1.Jornada + "," + cursos1.CursoId);// Console.WriteLine($"{curso2.Nombre} , {curso2.Jornada} , {curso2.CursoId}");// if(es?.Cursos != null){// ImprimirCurosNoche(arrayCursos);// }// Console.WriteLine("========================================");// foreach(var list in listas1){// Console.WriteLine($"Salon: {list.Nombre} ");// }// void ImprimirCurosNoche(Curso[] arrayCursos)// {// foreach(var curso in arrayCursos){// Console.WriteLine($"Nombre: {curso.Nombre} , Jornada: {curso.Jornada}, Id: {curso.CursoId}");// }// }
Haciendo esta clase me daba error con los namespace, el problema, visual estudio code no esta pensado para desarrollar c# y lo único que tube que hacer para arreglar el problema con los namespace fué reiniciar VSC y todo fue perfecto.