2010-11-21 15 views
6

Soy un estudiante universitario (ciencias de la computación) y acabo de comenzar una clase de programación de C#. Para nuestras asignaciones, he estado usando una clase llamada "Pantalla" donde pongo cualquier salida de consola que pueda usarse varias veces a lo largo de un proyecto. Por ejemplo, una solicitud para continuar o salir del programa. En lugar de tipearlo varias veces en Main(), solo llamo al método de la clase Display.uso correcto de las clases?

Otro estudiante en una clase de nivel superior me ha dicho que no debería hacer esto. Que es una práctica de codificación pobre y que debería incluir todos los métodos dentro de la clase primaria (que contiene Main()) y solo usar otra clase cuando sea absolutamente necesario.

Estoy buscando algunas sugerencias y consejos.

Me pidieron que incluyera el código. Originalmente iba a ir, pero no quería hacer esta publicación demasiado tiempo. He elegido una tarea que es bastante corta. Quiero aclarar que solo estoy aprendiendo, por lo que el código no es tan elegante como muchos de ustedes pueden escribir. La crítica constructiva es muy bienvenida.

En última instancia, estoy jugando con el uso de las clases. Sé que algunos de los métodos en la clase Display podrían ser tan fácilmente en Main().

Esta es la clase de programa que contiene Principal()

namespace Chapter_6_10 
{ 
class Program 
{ 
    static void Main() 
    { 
     string triangle = "", result = " ";; 
     char printingCharacter = ' '; 
     int peakNumber = 0; 
     Display.Instructions(); 
     Display.Continue(); 
     // perform a do... while loop to build triangle up to peak 
     do 
     { 
      Console.Clear(); 
      Request.UserInput(out printingCharacter, out peakNumber); 
      int counter = 1, rowCounter = 0; 
      do 
      { 
       do 
       { 
        triangle += printingCharacter; 
        rowCounter++; 
       } 
       while (rowCounter < counter); 
       counter++; 
       rowCounter = 0; 
       triangle += "\n"; 
      } 
      while(counter != peakNumber); 
      // perform a do... while loop to build triangle from peak to base 
      do 
      { 
       do 
       { 
        triangle += printingCharacter; 
        rowCounter++; 
       } 
       while (rowCounter < counter); 
       counter--; 
       rowCounter = 0; 
       triangle += "\n"; 
      } 
      while (counter != 0); 
      Console.Clear(); 
      Console.WriteLine(triangle); // display triangle 
      Display.DoAgain(out result); // see if user wants to do another or quit 
      triangle = "";     
     } 
     while (result != "q"); 
    } 
} 

Ésta es la clase de visualización

namespace Chapter_6_10 
{ 
// This class displays various outputs required by program 
class Display 
{ 
    // This method display the instructions for the user 
    public static void Instructions() 
    { 
     Console.WriteLine("\nThis program will ask you to enter a character to be used " 
      + " to create triangle." 
      + "\nThen you will be asked to enter a number that will represent the" 
      + "\ntriangles peak." 
      + "\nAfter your values have been received a triangle will be drawn."); 
    } 
    // This method displays the choice to continue 
    public static void Continue() 
    { 
     Console.WriteLine("\n\nPress the enter key when you are ready to continue..."); 
     Console.ReadLine(); 
    } 
    // This method displays an error message 
    public static void Error(string ErrorType) 
    { 
     Console.WriteLine("\nYou have entered \"{0}\", which is a value that is not valid!" 
      + "\nThis is not rocket science." 
      + "\n\nTry agian...", ErrorType); 
    } 
    // This method will ask user to press enter to do again or 'q' to quit 
    public static void DoAgain(out string Result) 
    { 
     string input = " "; 
     Console.WriteLine("\nPress enter to run program again" 
      + "\nor type the letter 'q' to close the application."); 
     input = Console.ReadLine(); 
     // convert input to lowercase so that only one test needed 
     Result = input.ToLower(); 
    }   
} 

Ésta es la clase de solicitud

namespace Chapter_6_10 
{ 
// This class is used to get user input 
class Request 
{ 
    public static void UserInput(out char PrintingCharacter, out int PeakNumber) 
    { 
     string input = " "; 
     char testCharacter = ' '; 
     int testNumber = 0; 

     // a do... while loop to get Printing Character from user 
     // use TryParse() to test for correct input format 
     do 
     { 
      Console.Write("\nPlease enter a character to be used to build triangle : "); 
      input = Console.ReadLine(); 
      bool result = char.TryParse(input, out testCharacter); 
      if (result) 
      { 

      } 
      else 
      { 
       Console.Clear(); 
       Display.Error(input); 
       input = " "; 
      } 
     } 
     while (input == " "); 
     // a do... while loop to get number from user 
     // use TryParse() to test for correct input format 
     do 
     { 
      Console.Write("\nPlease enter a number <between 1 and 10> for the peak of the triangle : "); 
      input = Console.ReadLine(); 
      bool result = int.TryParse(input, out testNumber); 
      if (result) 
      { 
       if ((testNumber > 0) && (testNumber < 11)) 
       {       
       } 
       else 
       { 
        Console.Clear(); 
        Display.Error(testNumber.ToString()); 
        input = " "; 
       } 
      } 
      else 
      { 
       Console.Clear(); 
       Display.Error(input); 
       input = " "; 
      } 
     } 
     while (input == " "); 
     // assigned received values to 'outs' of method 
     PrintingCharacter = testCharacter; 
     PeakNumber = testNumber; 
    } 
} 

Eso es todo. ¿Sería esto una manera ineficaz de codificar? ¿Cómo puedo mejorarlo?

Gracias por toda la información hasta ahora. Es muy valioso para mi

+2

¿Puede compartir el código? Es más fácil comentar el código cuando realmente lo veas ... –

+3

No voy a poner esto como una respuesta, ya que se trata más o menos a continuación, pero sí quiero decir que este otro alumno es una de las razones por las que hay tanto código malo por ahí. Enviarle este enlace a SO y deleitarse. :) –

+0

He agregado el código de una de mis tareas, según Fredrick Mörk. Cualquier entrada sería apreciada. – subcan

Respuesta

14

Una estructura de clase completa y bien diseñada es extremadamente importante en la adhesión a los principios object-oriented design.

Éstas son sólo algunas de las razones para considerar romper el código relacionado en clases separadas:

  • crea una división del trabajo y segrega tareas diferenciales. Esto a veces se explica como Single Responsibility Principle, que dice que cada objeto (clase) debe tener una responsabilidad única y centrarse en completar una sola tarea. Encapsulation también se convierte rápidamente en un principio importante aquí, básicamente significa que los datos se incluyen con los métodos que son responsables de operar con esos datos. Esto también ayuda a reducir las oportunidades de que los errores entren en tu código.

  • Puede ayudar a promover code reuse. A menudo es mucho más fácil tomar una clase existente con el código que ya ha escrito e integrarla en otra aplicación que si ese código estuviera disperso por la aplicación. ¿Por qué reescribir el mismo código una y otra vez?

  • Una estructura de clase bien diseñada puede crear una jerarquía lógica que hace que su código sea más fácil de entender y conceptualizar, y también hace que su aplicación sea más fácil de mantener a largo plazo. Es la misma razón por la que organizamos los archivos en nuestra computadora en carpetas, y todo lo demás en nuestras vidas (o al menos lo intentamos).

+0

Gracias por su respuesta. He visto la página wiki sobre diseño orientado a objetos. En él, el autor dice: "Se podría decir que una clase es un modelo o fábrica que describe la naturaleza de algo". He agregado el código a mi publicación original. ¿Dirías que mi clase de pantalla no sigue este principio? Estoy tratando de evitar demasiado desorden en Main(). Puedo seguir mi código bastante fácilmente de un programa a otro, pero ¿alguien más tendría dificultades para seguirlo? – subcan

6

Nunca escuchar a alguien que dice "Esta es una buena práctica" o "Esta es una mala práctica" si no pueden explicar por qué es bueno o malo. Al igual que en cualquier otro campo, hay muchos estereotipos en la programación, trate de evitarlos.

Para su ejemplo particular, que es un poco vago, porque realmente no sé lo que hace su clase, no creo que separar la funcionalidad de IO en una clase separada es una idea terriblemente mala. Sin embargo, que realmente depende de lo que hace, si es o no es independiente, etc., etc. También depende del gusto personal :)

+1

El tipo que criticó mi código me dijo que al usar las clases de la forma en que lo hice, significa que el programa necesita usar más ubicaciones de memoria para almacenar la clase y ralentizará el programa a una escala mayor. Le dije que solo estaba jugando con los usos de las clases. Me dijo que no lo hiciera y que al reutilizar el código no aprendería a codificar mejor. A esto le dije que estoy cambiando constantemente estas clases a medida que aprendo más 'trucos'. Él todavía insistía en que estaba usando la clase incorrectamente. No lo sé. He estado leyendo sobre las clases en MSDN y aún estoy indeciso. – subcan

+0

@subcan, en estos días, generalmente no necesita preocuparse de si sus objetos ocuparán uno o dos bytes adicionales SI eso significa que su código es más fácil de entender, más fácil de mantener, más fácil de extender, etc. Piense en la memoria cuando diseña algoritmos y estructuras de datos, * no * cuando diseña el modelo de objetos de su programa. Aquí no hablamos de lenguaje ensamblador, sino de un lenguaje OOP razonablemente de alto nivel (C#). Perdón por ser tan poco diplomático, pero ese chico que criticó tu código definitivamente no suena como un buen tutor para hacer OOP. – stakx

+0

Sé que esta es una publicación anterior, pero Amen "si no pueden explicarte ** por qué ** es bueno o malo" porque * cada * buena práctica tiene una razón tangible, generalmente fácil de explicar. – Crisfole

8

que es una práctica de codificación pobre y que sólo debe incluir todos los métodos dentro de la clase primaria [...] y solo use otra clase cuando sea absolutamente necesario.

Estoy absolutamente en desacuerdo. Esta línea de pensamiento eventualmente llevaría a unas pocas clases de lavabos de cocina que terminan haciendo todo.

Su colega sería correcto si estábamos hablando de la programación estructurada , en la que sólo podría tener subrutinas pero no hay clases — el principal medio de la organización de funcionalidad sería dividirlo en subrutinas. Pero aquí estamos hablando programación orientada a objetos, que también le da los medios para dividir la funcionalidad en diferentes clases. Las clases están ahí para ser utilizadas, después de todo, de lo contrario no estaríamos llamando a este OOP!

Si yo fuera usted, preferiría un enfoque bastante liberal de definir nuevas clases cuando las necesite.


P.S .: No hace falta decir que hay de hecho las mejores prácticas que le ayudan a decidir si necesita una nueva clase de algo, y cómo se debe diseñarlo. (Véase, por ejemplo, la respuesta de Cody Gray.) Simplemente quiero señalar aquí que definitivamente no tiene sentido en OOP para evitar activamente las clases.

0

En general, si está escribiendo la misma cosa varias veces, creo que algo va mal. Las rutinas de visualización encapsuladas como esa son en realidad buenas formas. Le permite cambiar fácilmente la salida en varias instancias, especialmente para cosas como mensajes de error.

Es posible que provenga de más de un estilo C de fondo, mientras que C# es más como un java que nada. El uso liberal de clases está permitido, incluso fomentado.

+3

Incluso los programadores de C saben no tirar todo en un solo lugar. –