Reutilización de código, mantenimiento de aplicaciones (IV)
Introducción
Seguimos avanzando en nuestro desarrollo mejorándolo poco a poco.
Esto me recuerda a aquellos maravillosos años de la normalización de nuestras bases de datos para llegar a tercera forma normal (3NF) o llegar al éxtasis con Boyce-Codd.
Implementación de la solución
En este caso, la implementación de nuestra solución partiendo del código anterior nos sugiere partir el código en módulos o de una forma tal que nos permita depurar y mantener mejor nuestra aplicación, al mismo tiempo que podemos abordar la posibilidad de reutilizar el código.
Para llevar a cabo nuestro propósito, hemos creado un proyecto en Visual Studio que será una biblioteca de clases a la que he llamado Foo.Framework.
Dentro de este proyecto, vamos a crear nuestra lista enumerada que ya vimos en la entrada anterior, y un objeto que se encargará de llevar a cabo el proceso de lectura y escritura de ficheros de texto y documentos Excel.
Dicho de otro modo, vamos a separar algunas responsabilidades iniciales de modo que aporte diferentes beneficios.
La lista enumerada se llamará ConnectorType y tendrá este aspecto:
El código de esta lista enumerada corresponderá con lo que se indica a continuación:
1: namespace Foo.Framework
2: {
3:
4: public enum ConnectorType
5: {
6: Excel,
7: Text
8: } // ConnectorType
9:
10: } // Foo.Framework
El código dentro del cuál vamos a trabajar con ficheros de texto y documentos Excel estará alojado en una clase de nombre ConnectorProcess:
El código de esta clase es el que se indica a continuación:
1: namespace Foo.Framework
2: {
3:
4: using System;
5:
6:
7: public sealed class ConnectorProcess
8: {
9:
10: public ConnectorProcess(ConnectorType connectorType)
11: {
12: this.Connector = connectorType;
13: } // ConnectorProcess Constructor
14:
15: private ConnectorType Connector { get; set; }
16:
17: public string Read()
18: {
19: switch (this.Connector)
20: {
21: case ConnectorType.Excel:
22: // Excel
23: return "Excel leída";
24: // Hacemos algo con la información leída.
25: // ...
26: break;
27: default:
28: // Texto
29: return "Texto leído";
30: // Hacemos algo con el texto leído.
31: // ...
32: break;
33: }
34: return String.Empty;
35: } // Read
36:
37: public void Write()
38: {
39: switch (this.Connector)
40: {
41: case ConnectorType.Excel:
42: // Excel
43: // Escribimos Excel.
44: break;
45: default:
46: // Texto
47: // Escribimos Texto.
48: break;
49: }
50: } // Write
51:
52: } // ConnectorProcess
53:
54: } // Foo.Framework
Y finalmente, nuestra interfaz de usuario.
No queda otra de momento, que crear una vinculación fuerte entre nuestra interfaz de usuario y Foo.Framework, ya que vamos a utilizar las clases que tenemos dentro de ese ensamblado.
Habiendo incluido una referencia a Foo.Framework, lo que tenemos que hacer es escribir el código de nuestra aplicación y que tendrá el siguiente aspecto:
1: namespace UI_Sample
2: {
3:
4: using System;
5: using System.Collections.Generic;
6: using System.ComponentModel;
7: using System.Drawing;
8: using System.Windows.Forms;
9:
10: using Foo.Framework;
11:
12:
13: public partial class MainForm : Form
14: {
15:
16: public MainForm()
17: {
18: InitializeComponent();
19: // Por defecto es un fichero de texto.
20: this.Connector = ConnectorType.Excel;
21: } // MainForm Constructor
22:
23: public ConnectorType Connector { get; set; }
24:
25: private void btnSampleTest_Click(object sender, EventArgs e)
26: {
27: ConnectorProcess connectorProcess = new ConnectorProcess(this.Connector);
28: // Leemos la información.
29: string data = connectorProcess.Read();
30: // Escribimos el resultado del supuesto proceso anterior.
31: connectorProcess.Write();
32: // Mostramos un mensaje en pantalla tipo fake.
33: MessageBox.Show(
34: data +
35: Environment.NewLine +
36: "Lectura y escritura realizada.");
37: } // btnSampleTest_Click
38:
39: } // MainForm
40:
41: } // UI_Sample
Como podemos apreciar, el código de nuestra interfaz de usuario se ha reducido bastante y está ahora quizás, mucho más claro que antes.
Posibles problemas
Hemos mejorado mucho algunos de los problemas detectados en las fases de desarrollo iniciales, y no decimos nada con respecto a como empezamos el proyecto y como está ahora. Sin embargo, seguimos teniendo problemas y se nos siguen ocurriendo mejoras.
El problema más molesto es quizás que nuestra interfaz de usuario tiene una relación fuerte con nuestro ensamblado Foo.Framework.
Por otro lado algo resuena en nuestras cabezas… algo denominado como principios básicos de programación orientada a objetos… en una sola palabra: Los principios SOLID.
Retomando la idea que indiqué al principio sobre 3NF y Boyce-Codd con respecto al modelado de una base de datos, SOLID es para mí su espejo con respecto a la programación orientada a objetos.
Cierto es que si queremos, podemos preparar una base de datos sin normalizar y que podemos trabajar con ella sin necesidad de llegar a 3FN o Boyce-Codd, pero que duda cabe que evitaremos problemas a largo plazo si la tenemos normalizada correctamente desde un principio.
También y por similitud, podemos desarrollar una aplicación Software sin tener en cuenta ningún principio SOLID, pero que duda cabe, que tenerlos presentes todos y cumplirlos, nos aportará beneficios notables de mantenimiento y reutilización.
La idea principal es la de adaptar nuestra aplicación a los cambios, ser ágiles ante esos cambios, y tratar de evitar que dichos cambios afecten a otras partes de la aplicación.
Pero quizás antes de seguir mejorando nuestro ejemplo, debamos hacer una pequeña pausa en el camino…
One Responseso far
Es interesante la comparación que haces entre SOLID y normalización de bases de datos.
Sobre todo porque al final pasa lo mismo, igual que no siempre la forma óptima de diseñar una base de datos es tenerla completamente normalizada, en el código hay veces en que es preferible violar SOLID para conseguir otros objetivos.
Muy buena la serie, me gusta además que el avance sea «tan lento» porque da tiempo a pensar en cada paso.