Estudios,  Software,  Tecnología

Inversión de Control en Ingeniería de Software

La Inversión de Control en Ingeniería de Software consiste básicamente en una estrategia para el desacoplamiento de componentes de software. En esencia, el propósito de la Inversión de Control es evitar dependencias (acoplamientos) innecesarios, que resten flexibilidad (e incluso elegancia) al diseño del sistema. En este post abordaremos brevemente este tema de la Ingeniería de Software. Anteriormente habíamos repasado algunas nociones de Clases Abstractas e Interfaces.

Supongamos que tenemos una clase Editor para editar y componer textos, al estilo de programas como Microsoft Word, Libre Office, Notepad, etc.

public class Editor {
    private WordReader wordReader;
    public Editor() {
        this.wordReader = new WordReader();
    }
    ...
    public void LoadTextFile()
        text = wordReader.read();
    }

Asumamos que la clase WordReader es un componente para leer un documento de texto desde un archivo en formato Microsoft Word. Observemos que en nuestra clase Editor estamos creando una instancia de WordReader y la usamos en métodos de la clase, por ejemplo, LoadTextFile. Aunque carece de elegancia, este diseño funcionará bien siempre y cuando el único tipo de documento que aceptemos en nuestro editor sean documentos en formato Microsoft Word. Sin embargo, ¿qué ocurre si en el futuro deseamos agregar soporte para otro formato de archivo? Por ejemplo, si quisiéramos que nuestro editor cargue archivos XML o de LibreOffice. Una barbaridad sería algo como ésto:

public class Editor {
    private WordReader wordReader;
    private XMLReader xmlReader;  
    private LibreReader libreReader;  

    public Editor() {
        this.wordReader = new WordReader();
        this.xmlReader = new XMLReader();
        // etc
    }
   ...
}  

Más allá de lo retorcido del anterior código, también podríamos tener que afrontar problemas de nomenclatura. Por ejemplo, observemos que la clase WordReader tiene un método “read”. Pero podría ocurrir que el diseño de la clase XMLReader haya ocurrido de forma independiente al de la clase WordReader, y entonces en XMLReader el método equivalente a WordReader.read se llame “readFile”. El código sería un lío aún mayor. Perdemos el “control” sobre la lectura de los archivos, porque dependemos de la instancia o instancias de lectores que se hayan agregado a la clase. Una opción mucho mejor es desacoplar el lector de archivos, invirtiendo el control. Por ejemplo, con una interfaz ITextReader que deben implementar todos los lectores, y además, suministrando el lector particular en el constructor del editor. En la interfaz ITextReader tendríamos un método “read”. Y entonces, nuestra clase Editor cambiaría:

public class Editor {
    private ITextReader textReader;

    public Editor(ITextReader textReader) {
        this.textReader = textReader;
    }
    ...
    public void LoadTextFile()
        text = textReader.read();
    }
}

Así hemos transferido el control al cliente de la clase Editor, que puede decidir qué lector usar. Notemos la “inversión”: ahora se crearía primero la instancia de la dependencia textReader y luego la instancia de la clase Editor. En nuestro enfoque original, primero se creaba la instancia del Editor y luego la instancia del textReader.

Hay muchas otras formas de lograr esta inversión de control en ingeniería de software. Por ejemplo, con callbacks, muy típico de sistemas basados en GUI. En una aplicación de consola podríamos tener un programa que solicita datos al usuario: Ingrese nombre, (Leer nombre), Ingrese edad, (Leer edad), Ingrese lugar de nacimiento, (Leer lugar de nacimiento), etc. Con una interfaz de usuario, “invertimos el control”, porque entonces podríamos permitir que el usuario seleccione la caja de texto GUI para la edad y proporcione primero ese dato, y luego podría elegir la caja de texto para el nombre, y así sucesivamente. Hemos invertido el control.

Admitamos que el término Inversión de Control en Ingeniería de Software a veces no resulta muy claro. Pero es un término que proviene de los 70, cuando el análisis sintáctico ascendente se consideraba una “inversión” del análisis sintáctico descendente. Y más o menos ha continuado aplicándose en diversos contextos. Para algunos, la Inversión de Control en Ingeniería de Software es una estrategia. Para otros, un patrón de diseño.

Resumiendo, la idea con la Inversión de Control en Ingeniería de Software es desacoplar los componentes, reduciendo dependencias y aumentando la flexibilidad del diseño.

Leave a Reply

Your email address will not be published. Required fields are marked *