domingo, 8 de diciembre de 2019

Implementación y Adaptación de Patrones de Diseño


Patrón de diseño



Los patrones de diseño son soluciones para problemas típicos y recurrentes que nos podemos encontrar a la hora de desarrollar una aplicación, es decir, un patrón de diseño es una manera de resolver un problema que ocurre normalmente a la hora de programar. En la década de 1990 fue cuando los patrones de diseño tuvieron un gran éxito en el mundo de la informática a partir de la publicación del libro Design Patterns escrito por el grupo Gang of Four (GoF)

Patrones GoF

En ingeniería de software, un patrón de diseño es una solución repetible general a un problema común en el diseño de software. Un patrón de diseño no es un diseño terminado que pueda transformarse directamente en código. Es una descripción o plantilla sobre cómo resolver un problema que se puede utilizar en muchas situaciones diferentes.
A principios de la década de 1990 los patrones de diseño tuvieron un gran éxito en el mundo de la informática gracias a la publicación del libro Design Patterns escrito por el grupo Gang of Four (GoF) compuesto por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, en el que se recogían 23 patrones de diseño comunes.
Los patrones GoF se dividen en tres tipos fundamentales, agrupados según el tipo de soluciones que aplican.
  •    Los patrones creacionales, que son aquellos que aplican soluciones que crean objetos de manera determinada. De este modo buscan encapsular la instanciación de objetos dentro de los métodos de otros objetos opacos, ocultándola al usuario del código.
  •     Los patrones estructurales, que abstraen la composición de interfaces a través de otros recursos, como la herencia o la agregación. Se encargan de proporcionar al usuario del código un objeto de firma simple que agrupa múltiples objetos de manera opaca.
  •     Los patrones de comportamiento, que buscan proporcionar al usuario del código objetos que aporten una funcionalidad determinada. De este modo los objetos presentan una firma cuyos métodos resuelven un problema específico sin exponer su funcionamiento.

Double Dispatch

Double Dispatch

     En la ingeniería de software , el double dispatch  es una forma especial de multiple dispatch , y un mecanismo que envía una llamada de función a diferentes funciones concretas en función de los tipos de tiempo de ejecución de dos objetos que participan en la llamada. En la mayoría de los sistemas orientados a objetos , la función concreta que se llama desde una llamada de función en el código depende del tipo dinámico de un solo objeto y, por tanto, que se conoce como dispatch single.

Type Object

¿Qué es un Type Object?

     Según Nystrom (2009) los type object “permiten la creación flexible de nuevas clases al crear una clase en particular, de la cual cada instancia representa un distinto tipo de objeto”. El propósito de los type object, según Johnson y Wolf (1996) es: Disociar instancias de sus clases, para que esas clases puedan ser implementadas como instancias de otra clase. 

¿Cuándo usar los type objects?


     Según Nystrom (2009), este diseño es “muy útil cada vez que se requiere definir una variedad o una gran cantidad de distintos tipos de cosas, pero el sistema de tipos de lenguaje del que se está haciendo uso es demasiado rígido”. En particular, según Johnson y Wolf (1996) conviene usar los type objects cuando se cumpla cualquiera de estas condiciones: 

  • Las instancias de una clase necesitan ser agrupadas de acuerdo a sus atributos y/o su comportamiento en común. 
  • La clase necesita una subclase para cada conjunto, con el fin de poder implementar los atributos y/o comportamiento de cada grupo.
  • La clase requiere de una gran cantidad de subclases y/o la cantidad de subclases requerida es desconocida. 
  • Se necesita la capacidad de crear nuevos grupos durante el tiempo de ejecución, que no fueron considerados durante el período de diseño. 

Wrappers

Wrappers

Generalmente se usa para describir una clase que contiene una instancia de otra clase, pero que no expone directamente esa instancia. El objetivo principal de la envoltura es proporcionar una forma "diferente" de usar el objeto envuelto (quizás la envoltura proporcione una interfaz más simple o agregue alguna funcionalidad).

Framework

Un framework es un conjunto de archivos y pautas que definen la estructura y metodología, sobre cómo hacer el desarrollo de un proyecto software. Se podría decir que es una guía o esquema que nos ayuda a programar de forma sencilla y rápida. 


Tiene como objetivo el desarrollo ágil de aplicaciones mediante la aportación de librerías y/o funcionalidades ya desarrolladas. Principalmente, nos permite centrarnos en el problema, en vez de preocuparnos por implementar funcionalidades que son de uso común en muchas aplicaciones. Generalmente los frameworks están basados en un lenguaje de programación, aunque no siempre es así.



Librerías

Qué son las librerías o bibliotecas

Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos.
Son un conjunto de instrucciones que realiza funciones básicas como leer, escribir en pantalla, trabajar números y funciones matemáticas, manejo de memoria, entre otros. Reducen la cantidad de instrucciones de un programa. Cada librería está delimitada por el trabajo que desempeñará y cada lenguaje de programación tiene sus propias librerías que deben ser escritas al inicio de la redacción de un programa. Algunas están ligadas, por lo que es necesario conocer las más relevantes para el lenguaje elegido.

Framework vs Librería

Framework

Un framework, entorno de trabajo o marco de trabajo es un conjunto estandarizado de conceptos, prácticas y criterios para enfocar un tipo de problemática particular que sirve como referencia, para enfrentar y resolver nuevos problemas de índole similar.
En el desarrollo de software, un entorno de trabajo es una estructura conceptual y tecnológica de asistencia definida, normalmente, con artefactos o módulos concretos de software, que puede servir de base para la organización y desarrollo de software. Típicamente, puede incluir soporte de programas, APIs, bibliotecas, y un lenguaje interpretado, entre otras herramientas, para así ayudar a desarrollar y unir los diferentes componentes de un proyecto.

Buenas Prácticas

a) “Once and Only once”

El principio Once and Only Once puede considerarse como un subconjunto del principio No te repitas, y es uno de los principios más fundamentales del desarrollo de software. Once and Only Once básicamente establece que cualquier comportamiento dado dentro de una aplicación se define una sola vez. La duplicación del comportamiento es una de las fuentes más comunes de errores en los sistemas de software, ya que cada vez es más probable que los cambios en el comportamiento definidos en una ubicación no se propaguen a todas las ubicaciones donde se define este comportamiento. La eliminación de la duplicación causada por no seguir el principio Once and Only Once es una de las razones principales para la refactorización y también está en el centro de muchos patrones de diseño.

El principio No te repitas (DRY- Don’t Repeat Yourself) establece que la duplicación en la lógica debe eliminarse mediante abstracción y la duplicación en el proceso debe eliminarse mediante la automatización.

Otras Buenas Prácticas Y Patrones de Comportamiento

Desarrollo guiado por pruebas (TDD)

Escribir pruebas primero ofrece muchas ventajas, como verificabilidad, prevención de regresión y documentación, entre otras.

Una prueba en sí misma puede considerarse como un usuario de algún código que eventualmente se escribirá, y como resultado de ello, escribir código utilizando el primer enfoque de pruebas impone un buen diseño del código. Esto significa que el código escrito usando TDD generalmente está mejor diseñado, ya que escribir las pruebas primero obliga al desarrollador a escribir código que sea fácil de probar, que generalmente es un código bien diseñado.

Vale la pena señalar que TDD debe usarse junto con el Desarrollo Conducido por el Comportamiento (BDD). TDD generalmente se basa demasiado en la implementación específica que un desarrollador decidió usar, mientras que BDD prueba el comportamiento del código. Esto es especialmente útil durante la refactorización, ya que aún puede saber si el nuevo código implementa correctamente el comportamiento requerido del código anterior, sin tener que actualizar ninguna prueba de comportamiento.