Palabras clave: Programación modular
, Función
, Módulo
.
1. El proceso general
EL proceso general para una programación modular consiste en:
-
Descomponer el problema en subproblemas más pequeños.
-
Definir muy claramente cada subproblema estableciendo:
-
Los datos que se necesitan de entrada, determinando quién los suministrará.
-
Los subproblemas que son necesarios resolver para suministrar esos datos de entrada.
-
Los datos o acciones que genera la resolución del problema.
-
Los procesos que se necesitan para relacionar los datos de entrada con los datos de salida.
-
Determina claramente si la salida afectará a otras partes del problema y en concreto si interviene en la resolución final del problema global.
Con ello deberás de establecer claramente que "interacción" hay entre dos subproblemas y que le es propio a cada uno.
-
-
Repetir el proceso para cada uno de los subproblemas que se hayan establecido en el paso anterior hasta que se considere que el subproblema es de "resolución inmediata" (es decir, no cuesta demasiado programarlo).
Cada uno de estos subproblemas define un módulo. Un subproblema de "resolución inmediata" genera una función de dicho módulo.
Tanto la cantidad de módulos que se pueden llegar a considerar como la cantidad de funciones dependerá del programador. No conviene ni quedarse ni a un nivel de poca descomposición (pocos módulos con pocas funciones muy complejas y extensas) ni a un nivel de descomposición trivial (muchos módulos con muchas funciones que constan de un par de líneas).
2. Variables globales y locales
Conviene recordar la diferencia entre estos dos tipos de variables.
En Processing tanto las variable declaradas en el bloque de una función como los parámetros de dicha función son solo accesibles en dicha función. Estas variables se llaman variables locales. Las variables locales de una función no son accesibles por las demás funciones; pero sí podemos hacer referencias a ellas desde cualquier bloque que se encuentre en dicha función.
Dada una función f() y otra función g() invocada o no en el cuerpo de f() , la función g() no puede acceder al valor de las variables locales de f() .
|
Las variables globales son aquellas que son accesibles por todas las funciones del programa. En Processing las variables globales son todas aquellas que no están declaradas ni dentro del cuerpo de una función ni son parámetros de las mismas.
Se llama ámbito de aplicación de una variable, a aquellos lugares del programa en los que una variable puede ser referenciada (o utilizada). El ámbito de una variable local es solo el de la función donde fue declarada; pero el ámbito de una variable global es todo el programa (se extiende a todas las funciones).
3. Relación entre subproblemas y ámbito de una variable
Como se ha indicado, en la resolución de un problema, los subproblemas intercambian la información para generar una solución. En programación se traduce en que las funciones encargadas de resolver los distintos subproblemas deben intercambiar su información, cada cual la que le es propia al subproblema que resuelve.
Se podría pensar que el intercambio de información se podría llevar a cabo mediante variables globales pero esto es un error. Se debe evitar el uso de variables globales. Pero ¿por qué? … |
En la programación modular un programa se reduce a un agregado de módulos. La información propia de cada módulo queda oculta a los demás módulos. De alguna forma cada módulo está aislado del exterior. El aislamiento protege los datos asociados al módulo, evita la modificación por aquellas funciones que "no tenga derecho" a acceder a ellos, elimina la posibilidad de efectos secundarios e interacciones imprevistas o incontroladas.
Ten siempre presente que si se usaran variables globales pueden conllevar un efecto secundario o lateral. Un efecto lateral es cualquier modificación de una variable producida en una función en la que la variable no está declarada. Estos efectos deben evitarse pues introducen dependencias indeseables.
Si tu función solo es capaz de resolver un subproblema utilizando variables globales … tienes un problema. Si tu función depende de una variable global, como tal puede ser modificada en cualquier otra función del módulo en el que se encuentra o ¡¡ de cualquier otro módulo !! Si modificas el valor de la variable global modificarás el comportamiento de la función y por tanto de la solución que obtiene. Un error en el valor asignado de la variable global, puede ser causa de errores muy difíciles de detectar.
No tienes permiso para usar variables globales, salvo en un caso.
Sólo tienes "derecho" a declarar aquellas variables globales que sean imprescindibles para el uso de draw() .
|
4. Algunos consejos para la creación de módulos o funciones
La mayor complejidad a la hora de aplicar programación estructurada y modular es saber decidir correctamente cuándo extraer código para colocarlo en una función o en otra. Realmente no hay una regla fija, solo la experiencia, el sentido común y algunas reglas orientativas nos pueden ayudar en la tarea. Se describen algunas.
-
Normalmente existe 3 grandes grupos de procedimientos en un programa: los que leen o solicitan datos; los que muestran, visualizan o escriben datos; y aquellos que los procesan. Intenta identificar cada uno de estos subproblemas.
-
Construye módulos/funciones donde no intervengan nunca los 3 tipos de procedimientos indicados anteriormente. Lo deseable es que tengas módulos/funciones para cada uno de estos procedimientos.
Por ejemplo, es bueno tener una función que indique si un número es primo o no; pero es malo que esa función también muestre un mensaje pues el cómo se muestra un mensaje puede ser diferente dependiendo del programa final.
-
Construye funciones encargadas de la inicialización de las variables del algoritmo que vayas a aplicar. Si el proceso es muy extenso, sudivide el proceso en otros procedimientos o funciones.
-
Construye módulos que implementen algoritmos que sean "independientes" de cualquier tipo de programa. Por ejemplo, los algoritmos de búsqueda y ordenación (que estudiaremos más adelante) son algoritmos genéricos para cualquier tipo de datos: crea tu propio módulo para la búsqueda y ordenación.
-
Piensa siempre en hacer funciones que puedan ser reutilizadas en otros problemas.
-
Lee detenidamente el enunciado del problema. En muchas ocasiones las oraciones del enunciado determinarán un procedimiento de alto nivel que debe implementarse. Pregúntate si dicho procedimiento se puede descomponer en problemas más pequeños.
-
Cuando hagas una función y te ocupe más de una pantalla, tienes un indicativo de que te puede convenir descomponer la función en otras funciones de menor extensión.
-
Cuando en la implementación de un algoritmo repitas código pero se diferencia en uno o pocos valores, esos valores serán los parámetro de la función que tendrás que programar y que será la encargada de ejecutar las líneas de dicho código (que ahora aparecerá solo una vez).
5. Repaso
-
Los problemas se deben descomponer en problemas más pequeños. Cada problemas más pequeño es un módulo.
-
El módulo encargado de resolver un subproblema consta de funciones que intercambia su información mediante sus parámetros.
-
Si un módulo debe suministrar información a otro módulos, las funciones correspondientes de cada módulo intercambiarán su información mediante sus parámetros.
-
En programación modular está "prohibido" usar variables globales para evitar efectos laterales difíciles de detectar.
-
Solo puedes usar variables globales sin son imprescindibles para usar funciones interactivas como
draw()
. -
Solo la práctica y el sentido común te determinará cuántos módulos/funciones debe tener tu programa.