# Módulo (patrón de diseño)

En ingeniería de software, el patrón de diseño módulo es un patrón de diseño utilizado para implementar el concepto de módulos de software definidos por el paradigma de programación modular, en un lenguaje de programación que no lo soporta, o lo soporta parcialmente.
Este patrón se puede considerar una variante del singleton o instancia única, con un propósito, más específico.

## Definición

La meta del patrón para diseño de software, consiste en proporcionar las características y estructura sintáctica, definida por el paradigma de programación modular, a lenguajes de programación, que no son compatibles totalmente, o que solo lo son a medias.

## Estructura

Este patrón requiere 2 elementos, un elemento es el elemento de definición; el cual, puede ser un grupo de código fuente, un solo objeto, o una sola clase, que aplica este patrón. Y el otro, es el elemento de implementación, el cual es un grupo de código fuente, un solo objeto, o una sola clase, que utiliza el elemento de definición.
Un elemento, puede utilizar ambos casos, definir un patrón, y aplicar otro. Es común, en este patrón, que se aplique varias veces, en una misma aplicación.

## Concepto

En el proceso de desarrollo de software, existen varias metodologías o paradigmas, para organizar el código fuente en componentes, agrupándolo y separándolo en varios componentes, en ocasiones, como clases u objetos. El paradigma de programación modular es una de esas metodologías, la cual se aplica, generalmente, junto con el paradigma de programación procedimental, como si fuesen una sola técnica. Por lo tanto, a veces, se considera que no debiese ser parte de el paradigma de programación orientada a objetos.
En muchos lenguajes orientados a objetos, el concepto de módulo está implementado de forma incompleta, o sin implementar. Sin embargo, el código fuente orientado a objetos es comúnmente distribuido en varios archivos, en donde hay elementos agrupados, físicamente, como archivos, y agrupados conceptualmente como espacios de trabajo (namespaces).
Varios lenguajes de programación soportan los espacios de trabajo, agrupando lógicamente clases, por medio de un identificador, como Java y C++.

## Características

Para poder considerar un objeto singleton, o cualquier agrupamiento de código relacionado, que está implementando este patrón de diseño, las siguientes características deben estar presentes, en dicho código fuente:
* Cuando sea implementado por una clase u objeto, solo podrá existir una única instancia en todo el programa.
* El código deberá tener acceso público, y como propósito, deberá ser considerado para acceso público, no como un objeto singleton regular, que en ciertas ocasiones, podría tener acceso privado o acceso protegido.
* El código deberá tener acceso global, o ser miembro de una entidad con acceso global.
* Cuando sea implementado como orientado a objetos, las clases deberán preferentemente ser consideradas, que no serán extendidas.
* Deberá tener una función o procedimiento para inicialización, que podría ser la misma, equivalente, o complementaria, a un método constructor, de un objeto. Esta característica no es soportada por espacios de trabajo regulares.
* Deberá tener una función o procedimiento para finalización, que podría ser la misma, equivalente, o complementaria, a un método destructor, de un objeto. Esta característica no es soportada por espacios de trabajo regulares.
* Soporta y encapsula varios miembros relacionados, que también podrían ser singletons.
* En caso de tener miembros, esos elementos, podrían requerir su propio código para inicialización, y su propio código para finalización, que deberá ser ejecutado, por la función de inicialización, y por la función de finalización, respectivamente, del módulo principal.
* Varios de los elementos o miembros, serán funciones que realizan operaciones, en elementos externos a la clase u objeto, que implementa el patrón, y son proporcionados como parámetros de cada función. Esas funciones tienen el propósito de ser utilizadas como herramientas o bibliotecas.

## Similitudes y diferencias con conceptos similares
### Espacios de trabajo frente a módulos

Tanto los espacios de trabajo y los módulos, permiten agrupar entidades relacionadas con un identificador único, y en algunas situaciones intercambiarse. Ambos conceptos, se utilizan globalmente. Por lo tanto, su propósito principal, es el mismo.
Hay escenarios en donde un espacio de trabajo requiere que alguno o algunos de los elementos globales que lo componen, sean inicializados, y en ocasiones, se les aplique un proceso de finalización, ejecutando una función o método.
Debido a que un espacio de trabajo, solo está considerado para agrupar y contener elementos, y no realizar comportamiento alguno, el módulo tiene además el propósito para soportar tanto el proceso de inicialización, como el proceso de finalización.

### Clases frente a espacios de trabajo

Las clases son utilizadas, a veces, también como Espacios de Trabajo, e incluso, combinados. En algunos lenguajes de programación que no soportan espacios de trabajo (por ejemplo: versiones anteriores de PHP, JavaScript o C), pero sí implementan clases y objetos; las clases son utilizadas por sí mismas, permitiendo acceso a sus elementos, sin tener que instanciar directamente cada clase en objetos.
En estas circunstancias, las clases están tomando la función de los espacios de trabajo y de los módulos.
A veces, para este propósito; la característica o modificador de compilación estática es aplicada a la clase misma, o alguno de los miembros de la clase.

### Singleton frente a espacios de trabajo

En los lenguajes de programación en donde los Espacios de Trabajo no están soportados, o están soportados solo parcialmente; y los miembros individuales de una clase no pueden ser accesados, la solución es generar un único objeto de una clase específica, aplicando el patrón de diseño singleton.

### Relaciones con otros patrones de diseño

El patrón de diseño módulo, puede ser implementado utilizando una especialización de el patrón de diseño singleton. Sin embargo, puede combinarse con otros patrones de diseño también.
Este patrón puede utilizarse, junto con los patrones decorador, objeto ligero y adaptador.

## Implementaciones de el patrón de diseño módulo en diversos lenguajes de programación

La semántica y sintaxis de cada lenguaje de programación, puede causar que la implementación de este patrón varie. Cada nueva versión de cada lenguaje de programación, soportando nuevas características, puede causar que haya varias implementaciones, para el mismo lenguaje.
Los siguientes ejemplos muestran una posible implementación de este patrón, pero, podrían existir otros casos, para el mismo lenguaje, versión del lenguaje, y versión de compilador.
Note, que en algunos casos, el patrón de diseño adaptador o envoltorio, ha sido también aplicado, pero no es un requisito.

### Ejemplos de implementaciones en lenguajes de programación orientados a objetos
#### Java

Aunque Java soporta el concepto de espacios de trabajo, una versión reducida del módulo, hay algunos escenarios en donde un desarrollado de software quisiera aplicar este patrón en este lenguaje.
Archivo para definición
Archivo para implementación

#### C# (C Sharp.Net)

C#, al igual que Java, soporta el concepto de espacios de trabajo, una versión reducida de un módulo; hay algunos escenarios, en donde un desarrollador de software quiera implementar este patrón en este lenguaje.
Archivo para definición
Archivo para implementación

### Ejemplo de implementaciones en lenguajes de programación funcional
#### JavaScript

Archivo para definición
Archivo para implementación

### Ejemplo de implementaciones en lenguajes de programación procedimentales

Este patrón, puede ser visto, como una extensión Procedural en Lenguajes Orientados a Objetos. pero, también aplica en otros escenarios.
Aunque, los paradigmas de programación procedimental y programación modular, se utilizan juntos, frecuentemente existen algunos casos en donde un lenguaje de programación procedimental, no aplique completamente el concepto de módulos.

#### PHP (modo procedimental)

Note que este ejemplo aplica en versiones procedimentales, sin espacios de trabajo, de PHP.
Archivo para definición
Archivo para implementación

#### "C Puro"

Archivo para definición (encabezado)
Archivo para definición (cuerpo)
Archivo para implementación

## Razones para considerar un módulo como patrón de diseño, por sí mismo

El patrón de diseño módulo puede ser considerado tanto como un patrón de creación o como un patrón estructural. Permite la creación de otros elementos, tal y como lo hace un patrón de creación. Al mismo tiempo, sirve para organizar otros elementos, y agruparlos, de la misma manera que lo hace, un patrón de estructura.
Este patrón, es comúnmente utilizado con el patrón adaptador, cuando se trata de normalizar un espacio de trabajo ya existente, aunque no es requisito necesario.
Un objeto que aplica este patrón, provee la misma funcionalidad de un espacio de trabajo, pero, adicionando el proceso de inicialización, y el proceso de finalización, que no está presente en el mismo.
Proporciona las mismas características que ofrece una clase estática, o una clase con miembros estáticos; pero con una sintaxis y semántica más clara, y precisa.
Soporta diversos escenarios, en donde una clase u objeto, puede ser tratado como datos estructurados y procedimentales. Y, viceversa, migrar datos estructurados y procedimentales, y puedan tratarse como datos orientados a objetos.