2012-09-05 18 views
6

Soy relativamente nuevo en el lenguaje C# pero con mucha ayuda de las búsquedas de Google y Stack Overflow. He realizado varias aplicaciones que incluyen trabajar con Office, System Services, Processes, WMI, SQL, Linq y Active. Directorio ...Cuándo usar las clases en C#?

Aunque a pesar de tener éxito con la obtención de estas aplicaciones funcionales todavía estoy seguro de muchas cosas en el lenguaje C# como buenas prácticas de código y usando muchas de las palabras clave, etc ..

C# clases; Sé lo que puedo hacer con ellos, sé sobre Constructores y Destructores, Instanciación y Propiedades, pero no estoy seguro de cuando Debería usarlos. Hasta ahora he escrito todos de mi código en mi archivo Form1.cs dentro de diferentes métodos. Estos métodos hacen una variedad de cosas diferentes con API completamente diferentes. Esto obviamente significa que tratar de mantener ese código puede ser bastante difícil y me resulta cada vez más frustrante encontrar cualquier cosa dentro de mi Form1.cs.

Mi pregunta a ustedes, ¿debería dividir mi código en diferentes clases? Intenté dividir las cosas relacionadas con SqlConnection y SqlCommands en una clase separada, pero sin crear una instancia de la misma clase varias veces en Form1.cs no puedo ver que esto sea más fácil o beneficioso.

He estado intentando juntar una nueva aplicación, pero esta vez manteniendo la funcionalidad en su propia clase, esperaba que alguien me dijera que soy estúpido y lo estoy haciendo mal o al menos que me dé alguna orientación.

Esta aplicación cargará eventualmente mi cadena de conexión desde App.Config, se conectará a una base de datos SQL y completará un DataSet con múltiples tablas de la base de datos. Esto de ninguna manera es funcional ya que no entiendo todo el tema de Clases.

Muchas gracias :)

partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    string myConnectionString; 

    private void Form1_Load(object sender, System.EventArgs e) 
    { 
     AppConfig cfg = new AppConfig(); 
     if (cfg.loadConfig()) 
     { 
      myConnectionString = cfg.myConnectionString(); 
     } 

     if (!String.IsNullOrEmpty(myConnectionString)) 
     { 
      SQLConn SQL = new SQLConn(); 
      if (SQL.createConnection(myConnectionString)) 
      { 
       MessageBox.Show("Connected!"); 
      } 
     } 
    } 
} 

class myDataSet 
{ 
    DataSet DataSet() 
    { 
     DataSet ds = new DataSet(); 

     SQLConn sql = new SQLConn(); 

     return ds; 
    } 

    public void fillData() 
    { 
     try 
     { 
      SqlCommand sqlCmd = new SqlCommand("SELECT * FROM hardware");     
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 
} 

class SQLConn : IDisposable 
{ 
    SqlConnection sqlConn; 
    public bool createConnection(string myConnectionString) 
    { 
     sqlConn = new SqlConnection(); 
     sqlConn.ConnectionString = myConnectionString; 
     try 
     { 
      sqlConn.Open(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     return false; 
    } 

    public void Dispose() 
    { 
     if (sqlConn.State == ConnectionState.Open) 
     { 
      sqlConn.Close(); 
      sqlConn.Dispose(); 
     } 
    } 
} 

class AppConfig 
{ 
    Configuration cfg; 

    public bool loadConfig() 
    { 
     try 
     { 
      cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
      if (!File.Exists(cfg.FilePath)) 
      { 
       MessageBox.Show("No configuration file"); 
      } 
      return true; 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     return false; 
    } 

    public string myConnectionString() 
    { 
     string connectionString = ConfigurationManager.ConnectionStrings["IT_ProjectConnectionString"].ConnectionString; 
     return connectionString; 
    } 
} 
+8

Necesita leer más acerca de la Programación Orientada a Objetos y los patrones de diseño posteriores – Habib

+0

Cuando * usted * desea crear un nuevo * tipo *. – adatapost

+1

Su código está lleno de clases. ¿Estás preguntando cuándo ponerlos en sus propios archivos? Tengo que estar de acuerdo con @Habib, tienes un par de cosas que desaprender aquí. –

Respuesta

6

Los principios detrás de OOP dicen más o menos que debe dividir todo lo posible para que las cosas relacionadas se agrupen en su propia clase, como las cosas SQL en su ejemplo. Otro ejemplo que se usa a menudo es el de un automóvil: si necesita tratar los datos de los automóviles, haría una clase de automóvil que contenga variables relevantes como velocidad máxima, nombre, color y métodos apropiados, como por ejemplo drive(double distance) o algo así.

Si no quiere objetos diferentes de esa clase y necesita el mismo comportamiento en varios puntos, puede evitar varias instancias de varias maneras: si todos los puntos están en su Form1, solo necesita instanciar su clase una vez como un miembro de la clase y puede usarlo en la clase Form1. Si necesita acceder a él desde diferentes clases, puede tener una variable global (que se considera mala práctica para la mayoría) o hacer que la clase que necesita acceda al static, de esa manera, no necesita crear una instancia en absoluto.

Si su aplicación es realmente pequeña, puede salirse con la suya poniendo todo en su clase Form1, pero como usted mismo ha notado, puede volverse confusa y complicada muy rápidamente. Piense en las clases como una oportunidad para ordenar su código. Piensa en lo que está conectado con qué, y lo que esperarías encontrar juntos, y pon eso en clases. Si te adhieres a eso, terminas con un código que es menos frustrante para encontrar el código y que tiene una estructura clara y lógica. Puede aprovechar cosas como la herencia una vez que las cosas se vuelven más complejas y puede reutilizar las clases que hacen cosas (de nuevo, cosas de bases de datos, por ejemplo) que podría necesitar en diferentes aplicaciones.

Esta es una descripción muy breve y muy aproximada. No conozco ningún buen libro sobre el tema (excepto los que son para principiantes de programación total, lo que parece inapropiado aquí), pero sugiero encontrar uno en OOP o buscar buenos artículos de introducción a ese tema. Personalmente, considero que CodeProject es una buena fuente de artículos. Here is one on OOP.

+0

Gracias, creo que dio en el clavo y era el tipo de guía que estaba buscando. También me has mostrado cómo puedo usar la palabra clave 'static' ya que no sabía que las clases' static' no necesitan ser creadas, ¡genial! Creo que he tenido la idea correcta y he querido usar clases para dividir la funcionalidad de mi clase Form1, pero no estaba seguro de si lo estaba haciendo bien. Gracias de nuevo :) – Robula

+0

Genial, podría ayudarte. Temía que mi respuesta fuera demasiado compleja: tengo la costumbre de explicar las cosas de una manera realmente extraña que parece tener sentido para nadie más que para mí :) – Christian

4

que utilizan el principio de responsabilidad única como una guía para el diseño de clases. Aquí es un buen discussion de este, siendo el punto saliente:

El punto es que cada clase debe implementar un conjunto coherente de funciones relacionadas. Una manera fácil de seguir el principio de Responsabilidad única es preguntarse constantemente si cada método y funcionamiento de una clase está directamente relacionado con el nombre de esa clase. Si encuentra algunos métodos que no encajan con el nombre de la clase, usted debería considerar mover esos métodos a otra clase.

Teniendo esto en cuenta, creo que tiene razón en dividir la funcionalidad de la aplicación de muestra en clases separadas. De lo contrario, terminará con una clase conglomerada Form1 que posee múltiples responsabilidades: leer valores de configuración, conectarse a bases de datos, leer datos. Como observa, dividir el código en clases separadas también hace que el programa sea más fácil de entender y navegar.

+0

Gracias Phillip, creo que este es el tipo de información que necesito. Leyendo a través de él ahora. :) – Robula

0

Piensa en tus clases que encapsulan algún tipo de funcionalidad. En su caso, SQLConn está manejando las conexiones a la base de datos, lo que significa que esta clase posee la conexión de la base de datos, y todo el tráfico ahora debe pasar por esta clase.Eso también significa que su clase myDataSet debe hacer uso de su clase SQLConn para todas las comunicaciones, por lo tanto, es un error que crea una instancia de un SqlCommand dentro de él.

Creo que puede estar confundiendo instancias con clases en su implementación. Está creando varias instancias de la clase SQLConn, primero en su método OnLoad donde se conecta a la base de datos, más adelante dentro de su clase myDataSet. Esto es no el mismo instace de la clase. Por lo tanto, su clase myDataSet usará un SQLConn que no se ha conectado a la base de datos.

Puede compartir lugar el mismo ejemplo, proporcionando la clase myDataSet con el SQLConn ejemplo desea que funcione en:

public myDataSet(SQLConn conn) 
{ 
    SQLConn sql = conn; 
} 

{ 
    SQLConn conn = new SQLConn(); 
    conn.createConnection(...); 
    myDataSet ds = new myDataSet(conn); 
} 

esto todavía no es un buen diseño, pero ilustra cómo transmitir una instancia frente a hacer referencia a una clase directamente.

+0

Gracias Simon, por supuesto, deseo evitar el mal diseño y la práctica. Anteriormente solía pasar mi Clase Form1 a otras Clases para acceder a mis datos de Form1 directamente de la otra clase que recientemente descubrí que es * mala *. Gracias por aclarar mi comprensión de instancias también. – Robula

Cuestiones relacionadas