2010-06-25 8 views
9

¿Alguien tiene algún consejo para mantener la lógica fuera de mis clases de GUI? Intento utilizar un buen diseño de clase y mantenerme lo más separado posible, pero mis clases de Formulario generalmente terminan con más elementos no relacionados con la interfaz de usuario de los que me gustaría, y esto hace que el mantenimiento sea un verdadero dolor.Separación de la IU y la lógica en C#

(Visual Studio 2008 Professional, C#, aplicaciones de Windows).

Muchas gracias.

Respuesta

6

Deja tus lógica en un ensamblado independiente; y, construir ese ensamblaje sin hacer referencia a ningún paquete de GUI (por ejemplo, System.Drawing, System.Windows.Forms, etc.).

+0

Gracias - Creo que este es un buen punto de partida práctico para ayudarme a pensar de la manera correcta. – Andy

3

que hay que buscar en patrones de diseño como:

Model-View-Controller (MVC) a menudo utilizados por los sitios web (ASP.NET)
Model-View-View Model (MVVM) a menudo utilizados por WPF

Al mantener a una de estos deberían ser capaces de mantener separadas las distintas partes de su aplicación.

Hay otros patrones que hacen un trabajo similar.

Además, el desarrollo de WPF puede ayudar a que la interfaz de usuario se define por el XAML y el código que hace el trabajo es el C#. Esto puede proporcionar un grado básico de separación. Si te encuentras escribiendo código C# que simplemente manipula la interfaz de usuario, puedes dar un paso atrás y pensar "¿Debería hacer esto en XAML?". Obviamente, puede haber cosas que tengas que hacer en el código, pero es un comienzo.

1

La arquitectura de 3 capas es lo que busca.

usted construye 2 capas reutilizables:

  • Data Access Layer (DAL), que sólo contiene el código necesario para de lectura/escritura de la base de datos
  • lógica de negocios de capa (BLL), que consume el DAL, contiene reglas de negocio, validación, y proporciona una fachada para la interfaz de usuario para utilizar

a continuación, en su proyecto de interfaz de usuario Haz referencia a las capas reutilizables y maneja solo las cosas específicas de UI. Las conversaciones de proyectos interfaz de usuario única a la BLL, sin conexión directa con el DAL:

IU < ---> BLL < ---> DAL

Puede tener varias capas de interfaz de usuario que consumen sus componentes reutilizables, así como múltiples DAL intercambiables si desea admitir múltiples tipos de bases de datos.

4

no deja de ser una cuestión de práctica y la autodisciplina. Quiero decir, todos lo hemos hecho. Y todos seguimos haciéndolo de vez en cuando bajo las condiciones incorrectas (gerente/cliente gritando para hacer algo "en este momento" frente a "correcto", etc.).

Una cosa que hago al escribir código para conducir la IU (más en el lado web, pero lo mismo se aplica) es preguntarme a mí mismo con cada unidad de código (una sola línea, un condicional, un bucle, etc.) si ese fragmento de código depende de la presencia de la IU. Si escribo en un cuadro de texto, eso depende de la interfaz de usuario, por lo que va allí. Pero si estoy calculando el resultado que irá en ese cuadro de texto, esa es probablemente la lógica comercial.

Otro enfoque (como ChrisW aludió mientras estoy escribiendo) es desarrollar la lógica primero en una biblioteca de clases que no sean UI. Pon toda la lógica que puedas (sin embargo, usa tu juicio sobre lo que define la "lógica") que no depende de las bibliotecas basadas en la interfaz de usuario. Luego crea la interfaz de usuario para hacer uso de esa lógica. Existen diferentes enfoques para permitir el desarrollo simultáneo de estas dos piezas, como anular el ensamblaje lógico detrás de las clases de interfaz y simplemente codificar las piezas de UI en esas interfaces (luego usar la inyección de dependencia para conectar las clases de ensamblaje a las interfaces), etc.

0

Normalmente en situaciones como esta; Creo una clase de método auxiliar que hace todo el trabajo pesado.

En cuanto a mantener la lógica separada; identificar cuáles son los componentes clave y refactorizarlos en esa clase de método auxiliar. Por ejemplo; si estoy procesando un GridView para actualizar los registros en función de si están o no seleccionados; y si lo son, actualice ShipDate, en el formulario; primero descubriría si la fila está seleccionada; luego extrae el campo Id, luego ShipDate, y luego pasa el Id y ShipDate a un método en mi clase de ayudante que hace todo el trabajo.

Las pruebas de unidad pueden ser su amigo aquí; Básicamente, si tiene un código que escriba cosas "lógicas"; debe tener una prueba de unidad. Si está en las clases de GUI; es difícil de probar; sin embargo, una vez que lo refactorice; la prueba unitaria debe ser trivial.

0

Usted debe buscar en los siguientes patrones:

MVC (Modelo-Vista-Controlador) MVVM (Model-View-Vista-Modelo) - Generalmente se utiliza en WPF con su soporte de enlace de datos ricos. MVP (Model-View-Presenter): a menudo se utiliza para WinForms y aplicaciones web (debido a la vista sin estado)

Consulte esta publicación de blog que muestra un ejemplo de cómo usar MVP para alimentar tanto una web como una vista de WinForms con un presentador: http://www.cerquit.com/blogs/post/MVP-Part-I-e28093-Building-it-from-Scratch.aspx

Además, un puesto más blog aquí se describen utilizando el patrón MVP de la unidad de pruebas de la lógica de negocio: http://www.cerquit.com/blogs/post/Model-View-Presenter-Part-II---Unit-Testing.aspx

1

Aprender a escribir clases de controlador que puede ser enlazado a datos a la forma y cómo realizar el enlace de datos. En WinForms esto se reduce principalmente a las interfaces INotifyPropertyChanged e IDataErrorInfo en la clase de controlador y al uso de instancias de BindingSource en la clase de formulario.

A continuación, puede escribir una clase de controlador que contenga TODOS los datos y la lógica para la interfaz de usuario y la clase de interfaz de usuario simplemente se une a ella. Su clase de IU se vuelve muy delgada, y su lógica de IU (mantenida en el controlador) se vuelve muy comprobable (las pruebas unitarias son complicadas cuando se ejecutan contra clases UI, pero son mucho más fáciles cuando se ejecutan contra clases controladoras).

Esta es la base de todos los diseños de MVC/MVVM.

Herbie

1

En una palabra, se llama Refactorizando.

Hay sólo un par de razones para incluir código en la interfaz de usuario:

  1. Interacción con un control en el formulario
  2. Validación aunque esto puede ser colocado en una capa de lógica de negocio, pero lo general añadir un método de ayuda en el interfaz de usuario (más fácil)

Todo el otro código "lógica de negocios" va a otra clase llamada la clase de lógica de negocio. Todo el código de interacción de la Base de datos entra en una clase diferente llamada clase de acceso a datos.

Cuando escribe el código en la interfaz de usuario, simplemente pregúntese si el código está interactuando con un control en el formulario. Si no, probablemente pertenece a las otras dos clases.

Echa un vistazo a algunos libros de Martin Fowler sobre refactorización como "Refactorización: mejorar el diseño del código existente". Otra palabra de moda es la separación de preocupaciones. Sé que puede hacer todo esto en una sola clase, pero el código se vuelve mucho más legible y más fácil de depurar cuando se separa en clases como describí anteriormente.

Cuestiones relacionadas