jueves, 16 de marzo de 2017

Gestión de Proyectos

Gestión de Proyectos

Todo diseño de proyecto requiere de una coordinación satisfactoria. Dentro de este escenario, girará lo que concierne al tiempo de desarrollo, los personajes que intervendrán en el diseño, los costes, etc. Por tanto, las preguntas que nos debemos hacer inicialmente son las siguientes:

  • ¿Qué es?
  • ¿Quién lo hace?
  • ¿Por qué es tan importante?
  • ¿Cuáles son los pasos?
  • ¿Cuál es el producto obtenido?
  • ¿Cómo puedo estar seguro de que lo he hecho correctamente?
Muchos son los temas en que gira este proceso. En el terreno de lo personal, podemos citar los tan discutidos y promulgados expertos y la madurez de la capacidad de gestión humana. Ello hace énfasis en los expertos del software y como motivar a que estos produzcan lo mejor de si y el mejor software posible. Además de esto, la organización y la búsqueda de desarrolladores o ingenieros con dotes de capacidad y talento, etc.
Luego, aparece el producto como punto de partida del desarrollo. Esta fase resulta ser tan crucial cuando el desarrollador y el cliente se sientan a conversar y a trazar el objetivo general en base a la necesidad del cliente y las pautas que este impone en dicho escenario.
La fase del proceso, que emerge de las trazas de los objetivos y donde se planifica la mecánica operacional del desarrollo que contempla lasa actividades, los hitos, los requisitos del proyecto, las mediciones, la calidad del software, etc.
Por último, hablamos del proyecto en los se sumergen las planificaciones y que son controlados por la razón principal. Esto se practica a los efectos de evitar desviaciones durante las fases evolutivas del proyecto. El secreto y el éxito de producir software con bajos márgenes de errores, quizá, dependerá de tener presente tanto los objetivos, los datos de relevamiento lo más fidedignos posibles y los improvistos controlados. Todo esto mejorará la calidad productiva de la construcción y guía del proyecto en general.

El Personal

El capital más poderoso, creativo e incidente del éxito de una empresa resulta ser la calidad de sus profesionales y sus empleados en una compañía. Así mismo, para el caso del desarrollo de software esta regla es similar. El personal es clave en el éxito del desarrollo del software.

Ahora bien, para lograr que esta sinergia de personas realice sus actividades de forma eficiente y eficaz se requiere de una basta estrategia de organización. Por tanto, la coordinación y la organización serán claves en el desarrollo exitoso del software. Es por ello que la organización debe ser coordinada por un gestor que administre competencias humanas más que competencias técnicas y es allí donde surge la brecha entre organizadores humanos y técnicos. En consecuencia, lo que se debe preconizar es la administración humana y como lograr el mejor éxito coordinado de las mismas para que estas produzcan en el terreno de la creatividad y el esfuerzo técnico.
El ingeniero Mantei considera que un equipo puede administrarse mediante tres pilares básicos y ellos son:

  • Descentralizado Democrático DD – Este equipo no tiene un jefe permanente. Se nombran coordinadores a coro plazo y se sustituyen por otras diferentes tareas. Se utiliza el consenso como poder comunicativo, es decir, se trata de una comunicación horizontal.
  • Descentralizado Controlado DC – Este equipo posee un jefe de cabeza y otros por debajo de este. Se mantiene el grupo pero la implementación de soluciones se reparte e subgrupos por el jefe del equipo. La comunicación entre subgrupo e individuos es horizontal y vertical a lo largo de la jerarquía de control.
  • Centralizado Controlado – El jefe se encarga de la resolución de los problemas a alto nivel y la coordinación interna del equipo. La comunicación entre el jefe y el equipo es vertical.
Además de estas características, el ingeniero Mantei ha descripto esta tarea de coordinación en siete etapas, las cuales, le pueden ayudar a replantear la organización de equipos de producción de proyectos y estos son los siguientes:
  • Dificultad del Problema a Resolver
  • El Tamaño del Programa – Resultante en líneas de código o puntos de función
  • El Tiempo que el Equipo Permanecerá Unido – Tiempo de vida del equipo
  • El Grado del Problema puede ser Modularizado
  • Calidad y Fiabilidad del Sistema a Construir
  • Rigidez de Fecha de Entrega
  • Grados de Sociabilidad – Comunicación requerida para el proyecto
En consecuencia, la organización de los grupos depende del tipo de proyecto y su envergadura. Resulta interesante saber, que según las recomendaciones del ingeniero Mantei, que el manejo de soluciones sencillas conviene que las administre equipos tanto DC o CC. Sin embargo, cuando los problemas no resultan ser sencillos, resulta recomendable pensar en un equipo DD.

El Producto

Quizá uno de los pasos más complejos es la de determinar los costes y los valores cuantitativos del producto. La complejidad de un proyecto y la difícil situación de ponderar componentes y personas, surge de la necesidad de encontrar un punto que determina la forma en cómo obtener el beneficio del coste de forma segura. Algunos tienden a aplicar la ley de Maquiavelo, “divide y vencerás”. De hecho suele ser una estrategia interesante. Un problema muy complejo puede ser dividido en problemas más pequeños o atomizados. Si esto es posible, Ud., puede cuantificar mejor los costes de desarrollo de cada área y juntarlos para obtener el coste global. Sin embargo, no resulta en una tarea sencilla. Peor aún, puede que sus costes se vayan distorsionando con el correr del avance del proyecto dado que la inconsistencia de los recursos se hace notar en estas etapas. Es por ello que la cuantificación de los costes se establezca con un meditado plan de desarrollo que contemple estas y otras desviaciones posibles de la presupuestación.
El gran problema que se tiene de entrada es que no se puede determinar con precisión la calidad del software. Lamentablemente, la calidad se podrá notar cuanto el modelo empírico y de prueba inicie sus primeras horas de vida. Es por ello que crear prototipos demo no resulta en una locura después de todo. Yo diría que el prototipo podría ser un generador de cuantificaciones que pueden servir para obtener los costes finales o, al menos, contar con un tanteo del coste del producto a simple vista. En resumen, la clave está en la coordinación, los objetivos y el desarrollo evolutivo del proyecto más el prototipo de muestra y evaluación.

El Proceso

Ha de estudiarse con mucho cuidado el proceso que se aplicará para el desarrollo del proceso. Si bien se ha estudiado que existen varias formas de practicar esta fase, la clave del proceso erradica en aplicar el método adecuado. Pasamos a recordarlos a continuación:
  • Modelo Secuencial
  • Modelo de Prototipo
  • Modelo DRA (Desarrollo Rápido de Aplicaciones)
  • Modelo Incremental
  • Modelo Espiral y Espiral WINWIN
  • Modelo de Desarrollo de Ensamblaje y Componentes
  • Modelo de Desarrollo Concurrente
  • Modelo de Métodos Formales
  • Modelos de Técnicas de Cuarta Generación
Por tanto, toda planificación comienza con un proceso de maduración del desarrollo. Esta fase de maduración permite establecer las siguientes pautas evolutivas del proyecto:

  • Comunicación con el Cliente – Tareas requeridas para establecer la obtención de requisitos eficiente entre el desarrollador y el cliente.
  • Planificación – Tareas requeridas para definir los recursos, la planificación temporal del proyecto y cualquier información relativa a él.
  • Análisis del Riesgo – Tareas requeridas para valorar los riesgos técnicos y de gestión.
  • Ingeniería – Tareas requeridas para construir una o más representaciones de la aplicación.
  • Construcción y Entrega – Tareas requeridas para construir, probar, instalar y proporcionar asistencia al usuario (por ejemplo: documentación y formación)
  • Evaluación del Cliente – Tareas del cliente basadas en la evaluación de las representaciones de software creadas durante la fase de ingeniería e implementadas durante la fase de instalación.
La descomposición de los procesos resulta una tarea muy importante y, como hace mención el ingeniero Mantei en sus observaciones, resulta importante considerar el modo ECP (Estructura Común de Procesos). Por ejemplo, para un pequeño proyecto se tiene los siguientes pasos:

  1. Desarrollar una lista de aspectos que se han de clarificar
  2. Reunirse con el cliente para resolver los aspectos que se han de clarificar
  3. Desarrollar conjuntamente una exposición del ámbito del proyecto
  4. Revisar al alcance del proyecto con todos los implicados
  5. Modificar el alcance del proyecto cuando se requiera
Estos son aspectos que pueden resolver pequeños problemas y establecer un lineamiento de fases bastante fáciles de seguir y con resultados satisfactorios a corto plazo. Sin embargo, en un proyecto más complejo surgen otras variantes que pueden complicar este tipo de lineamientos. Por ejemplo, para el caso de un proyecto cuyas fases muestren un escenario más amplio, las fases evolutivas del proceso podrían ser las siguientes:

  1. Revisar la petición del cliente
  2. Planificar y programar una reunión formal con el cliente
  3. Realizar una investigación para definir soluciones propuestas y enfoques existentes
  4. Preparar un documento de trabajo y una agenda para la reunión formal
  5. Realizar la reunión
  6. Desarrollar conjuntamente mini-especificaciones que reflejen la información, función y características de comportamiento del software
  7. Revisar todas las mini-especificaciones para comprobar su corrección, su consistencia, la ausencia de ambigüedades
  8. Ensamblar mini-especificaciones un documento de alcance del proyecto
  9. Revisar ese documento general con todo lo que pueda afectar
  10. Modificar el documento de alcance del proyecto cuando se requiera

El Proyecto

Cuando se establece el seguimiento de un proyecto, la mayor preocupación estriba en la desviación y en que las cosas puedan ir yendo en un sentido inadecuado. Si esta desviación se nota en las fases del proyecto, deberá de inmediato, tomarse decisiones acertadas. Existen las famosas reglas de señales de peligro definidas por el ingeniero John Reel en el que ha elaborado una tabla de notaciones negativas de la evolución de un proyecto que tiene una tendencia al desvío de los objetivos. Estas reglas son las siguientes:
  1. La gente del software no comprende las necesidades de los clientes
  2. El ámbito del producto está definido pobremente
  3. Los cambios están mal realizados
  4. La tecnología elegida cambia
  5. Las necesidades del negocio cambian o están mal definidas
  6. Las fechas de entrega no son realistas
  7. Los usuarios se resisten
  8. Se pierden los patrocinantes o nunca se obtuvieron adecuadamente
  9. El equipo del proyecto carece del personal con habilidades propias
  10. Los gestores y los desarrolladores, evitan buenas prácticas y sabias lecciones
Bien, para conducir el proyecto bajo un carril adecuado, el ingeniero John Reel establece el llamado “sentido común” y lo ha especificado en cinco reglas básicas y estas son las siguientes:
  • Empezar con el pie derecho – Esta tarea se realiza trabajando duro, pero muy duro, para comprender el problema a solucionar y estableciendo entonces objetivos y expectativas realistas para que cualquiera que vaya a estar involucrado en el proyecto. Se refuerza construyendo el equipo adecuado y dando al equipo la autonomía, autoridad y la tecnología necesaria para realizar el trabajo.
  • Mantenerse – Muchos proyectos no realizan un buen comienzo y entonces se desintegran lentamente. Para mantenerse, el gestor del proyecto debe proporcionar incentivos para conseguir una rotación del personal mínimo, el equipo debería destacar la calidad en todas las tareas que desarrolle y los gestores veteranos deberían hacer todo lo posible por permanecer fuera de la forma de trabajo del equipo.
  • Seguimiento del Progreso – Para un proyecto de software, el progreso se sigue mientras se realizan los productos del trabajo (por ejemplo, especificaciones, código fuente, conjunto de casos de prueba) y se aprueban (utilizando revisiones técnicas formales) como parte de una actividad de garantía de calidad. Además, el proceso del software y las medidas del proyecto pueden ser reunidas y utilizadas para evaluar el progreso frente a promedios desarrollados por la organización de desarrollo de software.
  • Tomar Decisiones Inteligentes – En esencia, las decisiones del gestor del proyecto y del equipo de software deberían “seguir siendo sencillas”. Siempre que sea posible, utilice software del mismo comercial o componentes de software existentes. Evite personalizar interfaces cuando estén disponibles aproximaciones estándar. Identifique y elimine entonces riesgos obvios. Asigne más tiempo del que pensaba necesitar para tareas arriesgadas o complejas (necesitará cada minuto).
  • Realizar Análisis Postmorten, después de finalizar el proyecto – Establecer un mecanismo consistente para extraer sabias lecciones de cada proyecto. Evaluar la planificación real y la prevista, reunir y analizar métricas del proyecto de software y realimentar con datos de los miembros del equipo y de los clientes y guardar los datos obtenidos en formato escrito.

Autor: Wagner, Ariel Alejandro.

Métricas de Proyectos

Métricas de Proyectos

La ingeniería se basa en medidas, en consecuencia, la ingeniería del software no escapa a esta regla. La medida se hace necesaria por varias razones. Se permite obtener a través de las medidas indicadores que resultan útiles para reconocer el proceso de una tarea o análisis, que más tarde, sirve para mejorar las cosas, para organizar o clasificar tipos de procesos, costes, seguimientos, rendimiento, etc.
Las medidas en el mundo de la ingeniería física se clasifican en dos tipos o clases:
  • Medidas Directas - Las medidas directas se trata de indicadores cuyos valores hacen mención a dimensiones físicas de un objeto, por ejemplo, un tornillo tiene un determinado tamaño, peso, etc.
  • Medidas Indirectas – Las medidas indirectas se trata de indicadores cuyos valores no hacen mención a características dimensionales físicas de un objeto, más bien, se basa en la interpretación de calidad y rendimiento. Por ejemplo, la evaluación del resultado final de fabricación de tornillos incluyendo los artículos defectuosos.

Métricas de Tamaño del Software

Medir el tamaño de un programa puede resultar en una tarea crítica. En el basto universo de la programación y desarrollo del software, se han diseñado un sin fin de procesos de mediciones. Sin embargo, tan solo dos se han hecho notar y son los que aún mantienen arduas discusiones entre expertos de la ingeniería. Estos métodos son los siguientes:
  • LDC – Líneas de Códigos – Este modelo de medidas utiliza la cantidad de líneas escritas y las utiliza para cuantificar un indicador que le permite determinar el tamaño, que más tarde, será comparado con las líneas escritas corregidas, agregadas o borradas al programa.
  • PF – Puntos de función - Este modelo de medidas se basa en cantidad de funciones y tiene incidencia en la cantidad de procesos del programa, procedimientos o eventos del mismo. Utiliza un factor de 3D (tres dimensiones) como indicadores de interpretación.
El PF o punto de función, responde a la siguiente relación matemática y de ella deriva el PF 3D.

PW = N x W 
Donde:
PF es el punto de función
N es la apariencia o el número total de cuentas de entradas obtenidas
W es el factor de ajuste de complejidad que va del 0 al 14
PW = (Nb x Wb) + (Nm x Wm) + (Na x Wa)
PF 3D (tres dimensiones) donde:
Nb, Nm y Na son las apariencias (baja, media y alta)
Wb, Wm y Wa los factores de complejidad (baja, media y alta)
La variable W estriba de 14 formulaciones que debe hacerse el desarrollador para calificar el ajuste de complejidad que consta de 14 preguntas y que ponderan según los criterios que se enmarcan a continuación:

1. ¿Requiere el sistema copias de seguridad y de recuperación fiables?
2. ¿Se requiere comunicación de datos?
3. ¿Existen funciones de procesamiento distribuido?
4. ¿Es crítico el rendimiento?
5. ¿Se ejecutará el sistema en un entorno operativo existente y fuertemente utilizado?
6. ¿Requiere el sistema entrada de datos interactiva?
7. ¿Requiere la entrada de datos interactiva que las transacciones de entradas lleven a cabo sobre múltiples pantallas u operaciones?
8. ¿Se actualización los archivos maestros de forma interactiva?
9. ¿Son complejas los archivos maestros de forma interactiva?
10. ¿Son complejas las entradas, las salidas, los archivos o las peticiones?
11. ¿Se ha diseñado el código para ser reutilizable?
12. ¿Están incluidas en el diseño la conversión y la instalación?
13. ¿Se ha diseñado el sistema para soportar múltiples instalaciones en diferentes organizaciones?
14. ¿Se ha diseñado la aplicación para facilitar los cambios y para ser fácilmente utilizada por el usuario?

Nivel
Estado
0…5
No importantemente aplicable
5…14
Absolutamente esencial

Lenguaje de programación
LDC/PF (medio)
Ensamblador
320
C
128
COBOL
106
FORTRAN
106
Pascal
90
C++
64
Ada95
53
Visual Basic
32
Smalltalk
22
Powerbuilder (generador de código)
16
SQL
12
Abra que recordar que este método PF como el método LDC, son descriptivos. Existe toda una relativización al respecto. Sin embargo, puede resulta útil por varias razones. Por ejemplo, si estamos en fase de optimizar el código, estos métodos podrían resultar en muy útiles. La métrica que surge de ello resulta en un indicador que puede ser eje comparativo durante las fases de refinamiento de código.
Puede calcular el coste de desarrollo por fases y, quizá, esto puede darle una idea de la envergadura del proyecto que se pretende confeccionar. De todos modos, el coste debe calcularse bajo otras razones y no bajo un mero concepto de medida lineal como pretende mostrar la tabla. Recuérdese que este se trata de una tabla de orientación y no puede ser representativamente una medida estandarizada. Tan solo, se trata de un número y simplemente eso, un número.

Economía en Base al Sistema COCOMO

El modelo COCOMO (Constructive Cost Model) se trata de uno de los modelos de construcción de software industrial de escala, diseñado por el ingeniero Barry Bohem. Presenta un acertado marco de estimación de costes de desarrollo, estimaciones de personal en función al tiempo, procesos diversos de ingeniería y gestión, etc. Además de ello, posee una jerarquía dividida en tres fases:

  • Modelo de composición de aplicación
  • Modelo de fase de diseño previo
  • Modelo de fase posterior a la arquitectura
El gráfico muestra un modelo de diseño en las alboradas de un diseño de software. Se detalla los costes, la cantidad de líneas, los puntos de función, las desviaciones de esfuerzo estimadas y normales, etc. Mediante este software que puede obtenerse gratuitamente en el sitio del colegio de ingenieros en USA y cuya dirección de Internet es la siguiente: Site Web http://csse.usc.edu/csse/index.html, Ud., podrá construir y estimar costes y otras razones de ingeniería a través de un pequeño pero poderoso programa de ingeniería para el desarrollo de proyectos de sistemas. 

Autor: Wagner, Ariel Alejandro.

Refactory - Refactoreo del Software - Parte III

Refactoreo de Una Librería Sencilla de Capa de Negocio

En esta oportunidad, analizaremos el refactoreo de una librería de Capa de Negocio utilizada para obtener datos desde una base de datos y cargarla en pantalla mediante el uso de una grilla. La librería, fue desarrollada de forma deliberada y a discresión. El refactoreo de esta librería nos permitirá comprender cómo se puede refinar el código y qué beneficios podemos obtener a cambio de ello. La idea central de este artículo es la de hacerlo reflexionar acerca de esta noble tarea de construir software de mejor calidad, aprovechando al máximo las virtudes del refinamiento y refactoreo del software. Mi mayor anhelo es despertar en Ud., la curiosidad de reflexión y, quien sabe, quizá contribuya a despertar su genialidad. Si logro ese acometido, me sentiré más que realizado.

Analizando el Código Original de la Librería 

A continuación dejo el código para que puedan conocer el estado orignal del mismo y como fue concebido este. La librería utiliza el proveedor de datos OleDB.

Imports System.Data
Imports System.Data.OleDb
Public Class DBTotalAccess

    Private conn As OleDbConnection
    Private dtAd As OleDbDataAdapter
    Private dtSt As DataSet
    Private _connectionString As String
    Private _source As String

    Public Property ConnectionString() As String
        Get
            Return _connectionString
        End Get
        Set(ByVal value As String)
            _connectionString = value
        End Set
    End Property

    Public Property Source() As String
        Get
            Return _source
        End Get
        Set(ByVal value As String)
            _source = value
        End Set
    End Property

    Public Sub New(ByVal setConnectionString As String, _
                   ByVal setSource As String)
        _connectionString = setConnectionString
        _source = setSource
    End Sub

    Private Function conectar() As OleDbConnection
        Try
            conn = New OleDbConnection
            conn.ConnectionString = _connectionString
            conn.Open()
            Return conn
        Catch ex As OleDb.OleDbException
            Return Nothing
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

    Public Sub openDataBase(ByVal Grilla As DataGridView)
        Try
            dtAd = New OleDbDataAdapter(_source, _connectionString)
            dtSt = New DataSet()
            dtAd.Fill(dtSt, "Tabla")
            Grilla.DataBindings.Clear()
            Grilla.DataBindings.Add("DataSource", dtSt, "Tabla")
        Catch ex As OleDb.OleDbException
            Grilla.DataBindings.Clear()
        Catch ex As Exception
            Grilla.DataBindings.Clear()
        End Try
    End Sub

    Protected Overrides Sub Finalize()
        conn = Nothing
        dtAd = Nothing
        dtSt = Nothing
        MyBase.Finalize()
    End Sub
End Class

Cómo puede observar, la librería integra una serie de funciones, eventos, propiedades y procedimientos para su construcción. El código en aparencia tiene aspecto de ser escueto y de hecho lo es. Se puede afirmar que pese a su composición ha mantenido cierto grado de racionalidad en su construcción. Sin embargo, el rendimiento tiene sus puntos críticos que al final de este artículo señalare con una tabla de comparaciones. Ahora, debajo de este párrafo, muestro el refactoreo de esta librería.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Imports System.Data.OleDb
Public Interface IConnect
    Function getConectar() As OleDbConnection
End Interface
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Imports System.Data
Imports System.Data.OleDb
Public Class DBConnect
    Implements IConnect

    Private _conn As OleDbConnection
    Private _connectionString As String

    Public Sub setConnectionString(ByVal value As String)
        _connectionString = value
    End Sub

    Public Function getConnectionString() As String
        Return _connectionString
    End Function

    Public Sub New()
        'Vacío Obligatorio.
    End Sub

    Public Sub New(ByVal cConnectionString As String)
        _connectionString = cConnectionString
    End Sub

    Public Function getConectar() As System.Data.OleDb.OleDbConnection _
    Implements IConnect.getConectar
        Try
            With _conn
                .ConnectionString = _connectionString
                .Open()
            End With
            Return _conn
        Catch ex As OleDb.OleDbException
            Return Nothing
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

    Protected Overrides Sub Finalize()
        _conn = Nothing
        MyBase.Finalize()
    End Sub
End Class
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Imports System.Windows.Forms.DataGridView
Public Interface IDBStatic
    Sub openDataBase(ByVal Grilla As DataGridView)
End Interface
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Imports System.Data
Imports System.Data.OleDb
Public Class DBStatic
    Inherits DBConnect
    Implements IDBStatic

    Private _dtAd As OleDbDataAdapter
    Private _dtSt As DataSet
    Private _source As String

    Public Sub setSource(ByVal value As String)
        _source = value
    End Sub

    Public Function getSource() As String
        Return _source
    End Function

    Public Sub New()
        'Vacío Obligatorio.
    End Sub

    Public Sub New(ByVal cConnectionString As String)
        MyBase.New(cConnectionString)
    End Sub

    Private Shared Sub cargarGrilla(ByVal Grilla As System.Windows.Forms.DataGridView, _
                                    ByVal xDtSt As DataSet, _
                                    ByVal xTabla As String)
        With Grilla
            .DataBindings.Clear()
            .DataBindings.Add("DataSource", xDtSt, xTabla)
        End With
    End Sub

    Private Shared Sub limpiarGrilla(ByVal setGrilla As System.Windows.Forms.DataGridView)
        setGrilla.DataBindings.Clear()
    End Sub

    Public Sub openDataBase(ByVal setGrilla As System.Windows.Forms.DataGridView) _
    Implements IDBStatic.openDataBase
        Try
            _dtAd = New OleDbDataAdapter(getSource(), getConnectionString())
            _dtSt = New DataSet()
            _dtAd.Fill(_dtSt, "Tabla")
            cargarGrilla(setGrilla, _dtSt, "Tabla")
        Catch ex As OleDb.OleDbException
            limpiarGrilla(setGrilla)
        Catch ex As Exception
            limpiarGrilla(setGrilla)
        End Try
    End Sub

    Protected Overrides Sub Finalize()
        _dtAd = Nothing
        _dtSt = Nothing
        MyBase.Finalize()
    End Sub
End Class


El refactoreo de esta librería presenta la construcción de dos clases y dos interfaces. Empezaremos analizando la clase e interfaz utilizada para manipular las conexiones.
La interfaz IConnect tan solo contiene una función llamada getConectar(). La clase llamada DBConnect contiene el código para la manipulación de las conexiones. La clase DBConnect implementa la interfaz IConnect. Notará que aquí también he omitido el particular proceso de encapsulación que se acostumbra utilizar en Visual Basic .NET, me refiero a los Property. En lugar de ello, he tomado la normalización que es muy utilizada en Java. El uso de procedimientos y funciones, a mi juicio, resultan más efectivas para estos casos. Sin embargo, existe una excepción a esta regla. Si se prevee la construcción de clases para a bases de datos orientada a objetos, típico en el lenguaje LINQ, quizá resulte más adecuado el uso de encapsulaciones de campos y propiedades utilizando los Property clásicos. Dado que este no es el caso, he decidido sujetarme a las normalizaciones típicas utilizadas en Java y que creo convenientes utilizar en Visual Basic .NET.
Dentro de la clase DBConnect he creado una función que es implementada desde la intefaz IConnect llamada getConectar() que permite la conexión hacia la base de datos. La ubicación y otros parámetros utiliza el conjunto de Setter & Getter llamado ConnectionString. A través de este conjunto de atributos, se le pasa la ubicación de la base de datos y todos sus parámetros que incluyen el tipo de proveedor, la versión, el tamaño del buffer, tipo de aislación, seguridad, etc. A continuación, muestro una típica cadena de conexión sencilla que bien podría servir de ejemplo en esta ocasión.

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\RentaCars\Agencia.mdb

Notará que esta cadena es extremadamente sencilla. Deseo puntualizar algo al respecto. Las cadenas de conexión pueden variar según el proveedor de datos e, incluso, el tipo de conexión que se desee hacer hacia la base de datos. Aquí expongo el ejemplo de una conexión hacia un gestor de base de datos basado en Microsoft Access. Sin embargo, podría utilizar cualquier tipo de proveedor de datos, siempre y cuando, utilice el proveedor adecuado. Ud., podría utilizar SQL Server y estas líneas quizá serían distintas. Es más, si utiliza MySQL Server, también cambiarán e incluso tendrá que referenciar las librerías adecuadas mediante la palabra clave Imports y el espacio de nombre correspondiente a dicho proveedor de base de datos.

A continuación, dejo una tabla con la mayoría de los proveedores de datos y sus cadenas de conexión específicas para cada una de estas soluciones.


Tabla de Cadenas de Conexión para ConnectionString
DB
ConnectionString
Access
Access ODBC Connection String Driver
{Microsoft Access Driver (*.mdb)};Dbq=C:\demo.mdb;Uid=Admin;Pwd=;
Access OLEDB Connection String Driver
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\directory\demo.mdb;User Id=admin;Password=;
DB2
DB2 ODBC Connection String
driver={IBM DB2 ODBC DRIVER};Database=demodb;hostname=myservername;port=myPortNum;protocol=TCPIP; uid=myusername; pwd=mypasswd
DB2 OLEDB Connection String
Provider=IBMDADB2;Database=demodeb;HOSTNAME=myservername;PROTOCOL=TCPIP;PORT=50000;uid=myusername;pwd=mypasswd;
DBase
DBase ODBC Connection String
Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=c:\directory;
DBase OLEDB Connection String
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\directory;Extended Properties=dBASE IV;User ID=Admin;Password=
Excel
Excel ODBC Connection String
Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=C:\MyExcel.xls;DefaultDir=c:\directory;
Excel OLEDB Connection String
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties='"Excel 8.0;HDR=Yes;IMEX=1"'
Exchange
Exchange OLEDB Connection String
oConn.Provider = "EXOLEDB.DataSource" oConn.Open = "http://myServerName/myVirtualRootName"
Firebird
Firebird ODBC Connection String
DRIVER=Firebird/InterBase(r) driver;UID=SYSDBA;PWD=mypasswd;DBNAME=c:\directory\demo.fdb
Firebird OLEDB Connection String
User=SYSDBA;Password=mypasswd;Database=demo.fdb;DataSource=localhost;Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0
FoxPro
FoxPro ODBC Connection String
Driver={Microsoft Visual FoxPro Driver};SourceType=DBC;SourceDB=c:\demo.dbc;Exclusive=No;NULL=NO;Collate=Machine;BACKGROUNDFETCH=NO;DELETED=NO
FoxPro OLEDB Connection String
Provider=vfpoledb.1;Data Source=c:\directory\demo.dbc;Collating Sequence=machine
Informix
Informix ODBC Connection String
Driver={Informix-CLI 2.5 (32 Bit)};Server=demoservername;Database=demodb;Uid=myusername;Pwd=mypasswd
Informix OLEDB Connection String
Provider=Ifxoledbc.2;User ID=myusername;password=mypasswd;Data Source=demodb@demoservername;Persist Security Info=true
MySQL
MySQL ODBC Connection String
DRIVER={MySQL ODBC 3.51 Driver};SERVER=myservername;PORT=3306;DATABASE=mydemodb; USER=myusername;PASSWORD=mypasswd;OPTION=3;
MySQL OLEDB Connection String
Provider=MySQLProv;Data Source=mydemodb;User Id=myusername;Password=mypasswd;
Oracle
Oracle ODBC Connection String
Driver={Microsoft ODBC for Oracle};Server=myservername;Uid=myusername;Pwd=mypassword;
Oracle OLEDB Connection String
Provider=msdaora;Data Source=mydemodb;User Id=myusername;Password=mypasswd;
Oracle .Net Connection String
Data Source=mydemodb;User Id=myusername;Password=mypasswd;Integrated Security=no;
SQL Server
SQL Server ODBC Connection String - Database Login
Driver={SQL Server};Server=myservername;Database=mydemodb;Uid=myusername;Pwd=mypasswd;
SQL Server ODBC Connection String - Trusted Connection
Driver={SQL Server};Server=mysername;Database=mydemodb;Trusted_Connection=yes;
SQL Server OLEDB Connection String - Database Login
Provider=sqloledb;Data Source=myservername;Initial Catalog=mydemodb;User Id=myusername;Password=mypasswd;
SQL Server OLEDB Connection String - Trusted Connection
Provider=sqloledb;Data Source=myservername;Initial Catalog=mydemodb;Integrated Security=SSPI;
SQL Server .Net Connection String - Database Login
Server=myservername;Database=mydemodb;User ID=myusername;Password=mypasswd;Trusted_Connection=False
SQL Server .Net Connection String - Trusted Connection
Server=myservername;Database=mydemodb;Integrated Security=SSPI;
Sybase
Sybase ODBC Connection String
Driver={SYBASE ASE ODBC Driver};Srvr=myservername;Uid=myusername;Pwd=mypasswd
Sybase OLEDB Connection String
Provider=Sybase.ASEOLEDBProvider;Server Name=myservername,5000;Initial Catalog=mydemodb;User Id=myusername;Password=mypassword

Por último, la clase DBConnect proporciona un evento llamado Finalize(). Este evento resulta ser muy importante. Permite liberar de la memoria las referencias de todas las variables que han sido cargadas por la clase. En pocas palabras, contribuye a mejorar la liberación de los recursos. Cabe puntualizar que el evento Finalize() solo contribuye como un elemento más para la cooperación de liberación de recursos, aunque quien realmente está encargado de liberar todos los recursos de forma responsable y directa es GC "Garbage Collector" o Recolector de Basura.
He construido una interfaz llamada IDBStatic y una clase llamada DBStatic. Esta clase y su interfaz, tiene como objetivo, preparar el uso de sus funciones para el proceso de acceder hacia la base de datos y cargar los datos en pantalla a través de una grilla, mediante el uso del objeto DatagridView. La interfaz IDBStatic tan solo contiene un procedimiento con un parámetro formal llamado openDataBase(). En la clase DBStatic, podemos ver como se implementa este procedimiento. Además de todo ello, la clase DBStatic, hereda de la clase DBConnect. Esto me permite proporcionar las operaciones y atributos de la clase DBConnect para utilizarlos dentro de las funcionalidades de la clase DBStatic.
En la clase DBStatic, más precisamente, dentro del procedimiento openDataBase(), Ud., podrá hallar el llamado hacia otro procedimiento que se llama cargarGrilla() y que es de caracter privado. Este procedimiento llamado cargarGrilla() tan solo está disponible para uso exclusivo interno de la clase DBStatic. Dentro del mismo, podrá encontrar parte de la lógica que controla el comportamiento de carga hacia la grilla, además claro está, de pasarle parámetros tales como el DataSet y un nombre para la tabla que resulta optativo. Puede colocar cualquier nombre, pero debe haber al menos uno para que el proceso funcione satisfactoriamente.
Respecto a la separación en partes que mencione recientemente, este extracto de código permite mejorar la mantenibilidad. Al crear este extracto, la mantenibilidad subió un punto de forma positiva. Como seguramente recordará en planteos anteriores acerca de la ley maquivélica "divide y vencerás" que hice en artículos pasados sobre refactoreos, bueno pues bien, he aquí tiene un ejemplo conciso.

Analizando Rendimientos

A continuación les dejo la tabla de comparación de ambos procesos de construcción. Seguramente, Ud., sacará las conclusiones por mi.

Tabla del Código Original

Mantenibilidad
74
Ciclo de Complejidad
25
Profundidad de Herencia
7
Acomplamiento de Clases
22
Líneas de Código
56
Tabla del Código Refactoreado

Mantenibilidad
87
Ciclo de Complejidad
33
Profundidad de Herencia
7
Acomplamiento de Clases
25
Líneas de Código
64

Muchas Gracias por su Atención.
Job Systems Solutions

Refactory - Refactoreo del Software - Parte II

Refactoreo y Reutilización del Código

En el siguiente estudio vamos a ver cómo utilizar Refactoreo y la Reutilización de código para mejorar la construcción del software. En esta oportunidad, se trata de una simple aplicación útil en matemática geométrica, que permite calcular las áreas de algunas figuras geométricas. 
Bien, a continuación, vuelco el código de construcción de esta aplicación. Más adelante de estos párrafos, iremos optimizando esta aplicación. Aplicaremos refactoreo y la reutilización de código para mejorar dicha aplicación. 

Public Class Form2

    Private Sub controlBotones(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click, Button2.Click, Button3.Click, Button3.Click, _
    Button4.Click, Button5.Click, Button6.Click

        Dim area As Double = 0.0
        Dim base As 
Double = 0.0
        Dim altura As 
Double = 0.0
        Dim radio As 
Double = 0.0
        If sender.Equals(Button1) Then
            Try
                base = TextBox1.Text
                altura = TextBox2.Text
                area = (base * altura) / 2
                TextBox3.Text = area
            Catch ex As Exception
                TextBox1.Text = 0
                TextBox2.Text = 0
                TextBox3.Text = 0
            End Try
        End If
        If sender.Equals(Button2) Then
            Try
                base = TextBox4.Text
                area = base * base
                TextBox5.Text = area
            Catch ex As Exception
                TextBox4.Text = 0
                TextBox5.Text = 0
            End Try
        End If
        If sender.Equals(Button3) Then
            Try
                base = TextBox8.Text
                altura = TextBox7.Text
                area = base * altura
                TextBox6.Text = area
            Catch ex As Exception
                TextBox6.Text = 0
                TextBox7.Text = 0
                TextBox8.Text = 0
            End Try
        End If
        If sender.Equals(Button4) Then
            Try
                radio = TextBox10.Text
                area = Math.PI * radio * radio
                TextBox9.Text = area
            Catch ex As Exception
                TextBox9.Text = 0
                TextBox10.Text = 0
            End Try
        End If
        If sender.Equals(Button5) Then
            Try
                radio = TextBox12.Text
                area = 4 * Math.PI * radio * radio
                TextBox11.Text = area
            Catch ex As Exception
                TextBox11.Text = 0
                TextBox12.Text = 0
            End Try
        End If
        If sender.Equals(Button6) Then
            TextBox1.Text = 0
            TextBox2.Text = 0
            TextBox3.Text = 0
            TextBox4.Text = 0
            TextBox5.Text = 0
            TextBox6.Text = 0
            TextBox7.Text = 0
            TextBox8.Text = 0
            TextBox9.Text = 0
            TextBox10.Text = 0
            TextBox11.Text = 0
            TextBox12.Text = 0
        End If
    End Sub
End Class


Antes de comenzar a plantear el refactoreo, primero hay que idealizar una estrategia de distribución, a los efectos de normalizar el proyecto. Una normalización permite estandarizar algunos aspectos de contacto con el software. De esta forma, cuando distribuimos parte del código refactoreado, los distintos trozos de código se coloquen donde se corresponda, respetando ciertos criterios primarios. Por ejemplo, todo aquello que atañe a la interfaz gráfica, conviene que esté dentro de la clase del formulario o, en todo caso, utilizar una clase de apoyo para el formulario. En nuestro caso, utilizaremos al propio formulario si los elementos optimizados hacen referencia a la interfaz gráfica. A continuación, vuelco el código por partes.
El refactoreo lo he planteado en dos áreas distintas. Un área, lo que concierne a la interfaz gráfica. En esa sección, he diseñado una Interfaz de modo de que implmente los métodos de limpieza para cada tipo de figura geométrica más un limpiador general de pantalla. A continuación, vuelco la interfaz.

Public Interface IClear
    Sub limpiarGeneral()
    Sub limpiarTriangulo()
    Sub limpiarCuadrado()
    Sub limpiarRectangulo()
    Sub limpiarCirculo()
    Sub limpiarEsfera()
End Interface


En el siguiente código, vuelco el resto de las modificaciones que plantea el refactoreo y la reutilización del código sobre el formulario principal de la aplicación.

Public Class Form2
    Implements IClear

    Public Sub limpiarGeneral() Implements IClear.limpiarGeneral
        limpiarTriangulo()
        limpiarCuadrado()
        limpiarRectangulo()
        limpiarCirculo()
        limpiarEsfera()
    End Sub

    Public Sub limpiarCirculo() Implements IClear.limpiarCirculo
        TextBox9.Text = 0
        TextBox10.Text = 0
    End Sub

    Public Sub limpiarCuadrado() Implements IClear.limpiarCuadrado
        TextBox4.Text = 0
        TextBox5.Text = 0
    End Sub

    Public Sub limpiarEsfera() Implements IClear.limpiarEsfera
        TextBox11.Text = 0
        TextBox12.Text = 0
    End Sub

    Public Sub limpiarRectangulo() Implements IClear.limpiarRectangulo
        TextBox6.Text = 0
        TextBox7.Text = 0
        TextBox8.Text = 0
    End Sub

    Public Sub limpiarTriangulo() Implements IClear.limpiarTriangulo
        TextBox1.Text = 0
        TextBox2.Text = 0
        TextBox3.Text = 0
    End Sub

    Private Sub controlBotones(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click, Button2.Click, Button3.Click, Button3.Click, _
    Button4.Click, Button5.Click, Button6.Click

        If sender.Equals(Button1) Then
            Try
                Dim triangulito = New Triangulo(TextBox1.Text, TextBox2.Text)
                TextBox3.Text = triangulito.getGettingArea()
            Catch ex As Exception
                limpiarTriangulo()
            End Try
        End If
        If sender.Equals(Button2) Then
            Try
                Dim cuadradito = New Cuadrado(TextBox4.Text)
                TextBox5.Text = cuadradito.getGettingArea()
            Catch ex As Exception
                limpiarCuadrado()
            End Try
        End If
        If sender.Equals(Button3) Then
            Try
                Dim rectangulito = New Rectangulo(TextBox8.Text, TextBox7.Text)
                TextBox6.Text = rectangulito.getGettingArea()
            Catch ex As Exception
                limpiarRectangulo()
            End Try
        End If
        If sender.Equals(Button4) Then
            Try
                Dim circulito = New Circulo(TextBox10.Text)
                TextBox9.Text = circulito.getGettingArea()
            Catch ex As Exception
                limpiarCirculo()
            End Try
        End If
        If sender.Equals(Button5) Then
            Try
                Dim esferita = New Esfera(TextBox12.Text)
                TextBox11.Text = esferita.getGettingArea()
            Catch ex As Exception
                limpiarEsfera()
            End Try
        End If
        If sender.Equals(Button6) Then
            limpiarGeneral()
        End If
    End Sub
End Class


Ahora, veremos el resto de las clases e interfaz que he diseñado para soportar este proyecto. Al final, haré todos los comentarios al respecto. El siguiente pequeño código es la interfaz llamada IGeometria que implementará en todas las clases una función en común llamada getGettingArea() que es utilizada en cada uno de los cálculos geométricos.

Public Interface IGeometria
    Function getGettingArea() As Double
End Interface


Ahora, la siguiente clase llamada MathBase, nos permite construir la constante PI que la he personalizado para justificar esta aplicación más todos los campos encapsulados. Obsérvese que he realizado la encapsulación de modo similar a como se hace en lenguajes tales como Java, C++ o C# respectivamente. Esto es para facilitar una posible migración de código hacia estos tipos de lenguajes mencionados.

Public Class MathBase

    Public Const miPI As Double = 3.1415926535897931
    Private _area As Double
    Private _base As Double
    Private _altura As Double
    Private _radio As Double

    Public Sub setArea(ByVal value As Double)
        _area = value
    End Sub

    Public Function getArea() As Double
        Return _area
    End Function

    Public Sub setBase(ByVal value As Double)
        _base = value
    End Sub

    Public Function getBase() As Double
        Return _base
    End Function

    Public Sub setAltura(ByVal value As Double)
        _altura = value
    End Sub

    Public Function getAltura() As Double
        Return _altura
    End Function

    Public Sub setRadio(ByVal value As Double)
        _radio = value
    End Sub

    Public Function getRadio() As Double
        Return _radio
    End Function
End Class


A continuación, cada una de las clases según el tipo de figura geométrica a la que se desea calcular particularmente.

Public Class Triangulo
    Inherits MathBase
    Implements IGeometria

    Sub New()
        'Vacío obligatorio
    End Sub

    Sub New(ByVal _base As Double, ByVal _altura As Double)
        setBase(_base)
        setAltura(_altura)
        getGettingArea()
    End Sub

    Public Function getGettingArea() As Double Implements IGeometria.getGettingArea
        Return (getBase() * getAltura()) / 2
    End Function
End Class

Public Class Cuadrado
    Inherits MathBase
    Implements IGeometria

    Sub New()
        'Vacío obligatorio
    End Sub

    Sub New(ByVal _base As Double)
        setBase(_base)
        getGettingArea()
    End Sub

    Public Function getGettingArea() As Double Implements IGeometria.getGettingArea
        Return getBase() * getBase()
    End Function
End Class

Public Class Rectangulo
    Inherits MathBase
    Implements IGeometria

    Sub New()
        'Vacío obligatorio
    End Sub

    Sub New(ByVal _base As Double, ByVal _altura As Double)
        setBase(_base)
        setAltura(_altura)
        getGettingArea()
    End Sub

    Public Function getGettingArea() As Double Implements IGeometria.getGettingArea
        Return getBase() * getAltura()
    End Function
End Class

Public Class Circulo
    Inherits MathBase
    Implements IGeometria

    Sub New()
        'Vacío obligatorio
    End Sub

    Sub New(ByVal _radio As Double)
        setRadio(_radio)
        getGettingArea()
    End Sub

    Public Function getGettingArea() As Double Implements IGeometria.getGettingArea
        Return miPI * getRadio() * getRadio()
    End Function
End Class

Public Class Esfera
    Inherits MathBase
    Implements IGeometria

    Sub New()
        'Vacío obligatorio
    End Sub

    Sub New(ByVal _radio As Double)
        setRadio(_radio)
        getGettingArea()
    End Sub

    Public Function getGettingArea() As Double Implements IGeometria.getGettingArea
        Return 4 * miPI * getRadio() * getRadio()
    End Function
End Class


Seguramente estará tentado en incriminarme que esto no es un refactoreo y ni mucho menos una forma fácil de diseñar el software de esta aplicación. Quizá en parte le de la razón si lo analizamos desde el punto de vista complejidad. No obstante, quiero recordarle que la optimización del código y la mantenibilidad, son más fuertes y valen más que la complejidad a la hora de probar el rendimiento del programa. Es más, no lo digo yo por que se me ocurre, sino que si se dignara a leer todo el vademecum de recomendaciones que las normas ISO hacen sobre el diseño y construcción de software, seguramente me daría la razón. No repito como un loro estas normas, porque no tienen sentido práctico. En lugar de ello, prefiero realizar una práctica de modo de que esté al alcance de todos y, por su puesto, cada uno pueda sacar sus propias conclusiones.
Volviendo a nuestro acometido, verá que he dividido al programa en varias áreas específicas. Vamos a ir por partes de forma de poder comprender mejor cada uno de estos módulos.
Como señale antes, la interfaz llamada IGeometria la he utilizado para que me pueda facilitar la implementación de una función que resulta ser común en todos los cálculos operativos de área. Además de facilitar esta implementación, contribuye a delinear una normalización conveniente. La normalización me permite desarrollar el código bajo un patrón estable y legible. Otro aspecto interesante de las interfaces es que evitan potenciales errores de escalación del software. Es decir, con el uso de interfaces, se evita que se desvíen las normalizaciones, lo que podrían ocacionar diversos inconvenientes operativos y de escala. En otras palabras, permite limitar y poner un patrón de crecimiento del código. Para concluir, gracias a esta técnica que me ofrece la interfaz IGeometria, he facilitado el polimorfismo de forma satisfactoria.
La clase la que he llamado con el nombre de MathBase me proporciona los Setters & Getters o los campos de propiedades para manipular los valores de las variables para cada elemento de cálculo en cada uno de las operaciones. Luego, esta clase es heredada en cada una de las clases de las figuras geométricas.
Nótese que de no haber incorporado una clase como esta, tendría que haber duplicado el código en cada una de las clases de las figuras geométricas. Aquí hubiera tenido un serio problema de duplicación y, sin duda alguna, una cierta cantidad de líneas bastante considerables. Gracias a la clase MathBase, he ahorrado bastante código.
Por último, cada una de las clases que operan según la figura geométrica requerida, tiene su implementación de la interfaz IGeometria y heredan de la clase MathBase los Setters & Getters o propiedades de campos.
He optado el desarrollo de una clase por cada figura geométrica por una sencilla razón. Primero, de haber utilizado una sola clase, me vería obligado a crear funciones individuales por cada tipo de cálculo de figura geométrica. Por tanto, no pudiera utilizar interfaces y mucho menos encontrar una normalización adecuada si no se sacrifica sobreescribir o corregir la gran clase. Observe que el patrón de normalización no podía ser el adecuado bajo un escenario de esas características. Creo que no era lo correcto. Segundo, al diseñar clases totalmente individuales permiten escalar sin que esto altere el resto de las clases. 
Supongamos que nos piden calcular otras cosas más. Por ejemplo, nos piden que calculemos Casquetes, Husos y Zona esféricas. De haber utilizado una sola clase, esta misma se llenaría de más funciones y tendería a la maraña y confusión. Además, desde el punto de vista matemático, estaría casi mal visto. Es más, desde el sentido común, también lo estaría. Por tanto, no es adecuado un tipo de organización semejante. 
En cambio, como tenemos cada una de las clases individualizadas, bastará con tomar la clase Esfera y proceder a ampliarla según estas necesidades pertinentes. Puede construir una interfaz exclusiva para Esferas. Sin embargo, resulta demás dado que estas ampliaciones son exclusivas de la clase Esfera y, por tanto, no es necesario forzar una normalización estricta. Mal o bien, estas funciones estarían dentro de un conjunto de tipos de figuras geométricas que son adecuadas. A continuación, muestro un mapa de las clases y cómo han quedado. Al final, haremos un análisis de las métricas y otros estudios básicos de ingeniería.

Analizando Métricas y Rendimiento - Conclusiones

La hora a llegado y es tiempo de verificar el comportamiento de esta aplicación y su rendimiento final. A continuación, vuelco las dos tablas comparativas que nos darán el veredicto.

Tabla para el Código Original
Mantenibilidad
67
Ciclo de Complejidad
97
Profundidad de Herencia
7
Acoplamiento de Clases
26
Líneas de Código
420

Tabla para el Código Refactoreado

Mantenibilidad
87
Ciclo de Complejidad
134
Profundidad de Herencia
7
Acoplamiento de Clases
34
Líneas de Código
453

Los resultado son más que óptimos. Sin embargo, en algunos puntos del análisis, podemos encontrar algunas diferencias a favor y encontra. No cabe la menos duda que el valor de mantenibilidad es más que alto. Es excelente y por tanto este último desarrollo nos permite una mejor facilidad de mantenibilidad que el código original pese a que este mismo muestra una aparente código simple. En el último desarrollo, ha aumentado el grado de complejidad. Resulta evidente debido a que se han agregado muchas etapas al modelo como factoreo. La profundidad de herencia se ha mantenido exactamente igual. El acomplamiento de las clases ha aumentado y, como es lógico, es debido a la extensión realizada por el factoreo. Por último, han aumentado la cantidad de líneas.
Resulta una lástima que estos medidores de rendimiento no hagan énfasis al factor de escalabilidad. La escalabilidad es muy importante porque permite realizar un crecimiento exponencial de un software. Si la escala no es diseñada de forma adecuada o, al menos, no se tiene encuenta, los resultados podrían ser críticos. Por ejemplo, no podría imaginarme que escala puede tener el primer código. Comparando a ambos, el último refactoreo ofrece un mayor valor de escala que el modelo original. en consecuncia, el último refactoreo de código nos permite ampliar nuestra aplicación sin sufrir limitaciones o entuertos tal como, seguramente lo hará, el código original de esta aplicación.

Factor de Acoplamiento

El factor de acoplamiento puede afectar en determinados casos y en otros pueden resultar ser aceptables, tal es el caso de nuestra aplicación. Ingeniería recomienda valores de acoplamiento lo más bajo posible. El acoplamiento está basado en el proceso límite que permite separar módulos sistémicos de forma de hacerlos más manipulables, reutilizables y extensibles. La arquitectura del software evalúa mucho estos puntos valuativos dado que, en el caso de tecnologías que comparten entornos de sistemas en común, pueden resultar críticos. Por ejemplo, en un ambiente donde existen un gran compromiso en la convergencia de varios sistemas que comparten un medio. 
Piense en el acoplamiento como en las etapas que hay de entre medio de varias secciones para comunicar un objeto con otro. Ambos objetos dependen de la fiabilidad entre estos. Si el canal que los une es crítico, en consecuencia directa, la comunicación entre ambos objetos resultará crítica también. Por ejemplo, una base de datos Oracle, una librería para manipular las conexiones, etc., en C# y una capa de negocio intermedia con una capa de usuario en Visual Basic .NET. Aquí hay tres acoplamientos bien claros. Cada uno ofrece una propuesta y el factor de acoplamiento debe ser efectivo. Si por alguna razón, se utiliza una librería escrito en Java, suponiendo que fuera compatible, el factor de acoplamiento deberá ser óptimo. Para ello, la cantidad de capas que son utilizadas para garantizar la comunicación y la adaptación "impedancia baja" deben procurar ser lo más eficaces posibles. Por tanto, existe un enormes compromisos para favorecer altos factores de performance para los acomplamientos.

Continúa en la Parte III

Muchas Gracias por su Atención.
Job Systems Solutions