Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript
Code

La herencia y la extensión de objetos con JavaScript

by
Difficulty:IntermediateLength:MediumLanguages:

Spanish (Español) translation by Ana Paulina Figueroa Vazquez (you can also view the original English article)

Si estás familiarizado con la programación orientada a objetos, lo más probable es que estés acostumbrado a la creación de subclases y a la herencia. Sin embargo, la herencia se ha estado ganando una mala reputación. Creo que esto se debe a que algunos desarrolladores la ven como una solución general cuando es necesario modificar un programa. El problema con esto es que las jerarquías de clases pueden volverse imposibles de administrar.

Existen otros patrones de diseño que podemos usar para que nuestras aplicaciones sean más fáciles de entender y que estén listas para los cambios. Te mostraré ejemplos de cómo puedes usar la herencia así como los patrones decorador y compuesto para mejorar el diseño de tu programa.

Herencia

La idea detrás de la herencia es que un objeto "es una" versión especializada de otro objeto. Existe una clase padre (también conocida como superclase) que define las propiedades básicas de nuestro objeto. Y hay una clase hija (subclase) que hereda las propiedades de la clase padre.

Un ejemplo de herencia es un perro y un caniche. Todos los perros poseen ciertas características, como tener cuatro patas y la capacidad de ladrar. Un caniche "es un" un tipo de perro. Un SUV es un vehículo. Un círculo es una figura. Esta es la forma en la que se vería nuestra jerarquía de clases si diseñáramos un programa para crear figuras.

A basic inheritance diagram

El beneficio de tener una clase Shape (Figura) es que podemos reutilizar en otras clases las propiedades y métodos que definimos en ella.

Toma en cuenta que el método getArea fue redefinido en cada una de nuestras subclases. No era necesario definirlo de nuevo, pero lo hicimos para reemplazar la implementación del método de nuestra clase padre. Esto se debe a que cada figura tendrá su propia forma de calcular el área.

Sobrescribir un método padre en una clase hija es un ejemplo de polimorfismo. El polimorfismo es la habilidad que poseen los objetos para tener múltiples formas. Esto permite que las subclases tengan métodos con el mismo nombre que los de sus superclases pero con diferentes implementaciones.

Este es un ejemplo de la forma en la que se vería nuestro código para crear una clase Shape (Figura) y una subclase Circle (Círculo):

Una de las desventajas de esta opción de diseño es que, si decides que la clase padre necesita un cambio, entonces es posible que las subclases necesiten un cambio también junto con todos los objetos que hayamos creado.

Por ejemplo, supongamos que más adelante decidimos que sería mejor reemplazar los parámetros "x" y "y" de la clase Shape con un objeto. En consecuencia, necesitaríamos cambiar el constructor de todas nuestras subclases y los argumentos de cada objeto que hayamos instanciado.

Podemos observar que esto puede volverse problemático fácilmente. Tendríamos que asegurarnos de tener un diseño correcto desde la primera vez para evitar hacer cambios. Pero esto no es práctico ni es en lo que deberíamos esforzarnos. Un programa es una entidad en constante evolución, y es mejor para nosotros como desarrolladores el tener la flexibilidad de hacer cambios fácilmente. Como mínimo deberíamos evitar tener más de un nivel de clases hijas.

Patrón decorador

Un decorador nos permite adjuntar propiedades a un objeto después de que haya sido creado. Esto significa que podemos añadir funcionalidad sin tener subclases y podemos dejar de preocuparnos por la implementación de nuestro objeto.

En vez de pensar en un círculo como una figura, podemos usar la clase Shape (Figura) para crear círculos y envolverla con las propiedades adicionales que queramos. Esta es una alternativa a la creación de objetos Circle (Círculo) usando un decorador:

Podemos añadir o modificar miembros de nuestra clase Shape (Figura) con un decorador en vez de crear subclases a partir de ella. Con nuestro ejemplo de figuras, es posible que descubras que solamente quieres crear un objeto círculo que tenga todas las propiedades que necesites y hacer lo mismo con otras figuras. Eso está bien. Pero un decorador nos permite reutilizar el código de nuestra clase Shape (Figura) y modificarla con la funcionalidad que difiere en cada figura. Como resultado tendremos más objetos, pero tener más objetos es más fácil de administrar que tener más subclases.

Este patrón no está limitado a la creación de gráficos. Puedes usarlo en cualquier situación en la que quieras añadir responsabilidades a un objeto.

Por ejemplo, podemos tener una clase que maneje el registro de usuarios a nuestra cuenta. Antes de guardar su información en nuestra base de datos, sería conveniente revisar que la entrada sea válida y que no contenga secuencias de comandos maliciosas. Podemos decorar la clase con un método para validar la información primero. Este mismo decorador puede reutilizarse en cualquier parte de nuestra aplicación en la que aceptemos valores de entrada del usuario.

El patrón compuesto

Los objetos pueden estar compuestos por otros objetos. Puedes pensar en la vista de una aplicación como un componente conformado por otras vistas. Si estuviéramos creando un juego, el mundo de nuestro juego mostraría todos los gráficos que hayamos creado, tales como círculos y cuadrados. Cada vez que actualizáramos nuestra vista necesitaríamos volver a dibujar cada elemento. Necesitamos una forma de administrar todos los elementos como un grupo.

Aquí es en donde el patrón compuesto puede ayudarnos. Podemos crear una clase que sea la responsable de todos los elementos. Cuando queramos volver a dibujar los elementos invocaremos al método de dibujo de esta clase y éste a su vez invocará al método de dibujo de cada elemento individual.

Puedes pensar en una página web como un componente también. Este componente puede tener un menú, una barra lateral y una entrada de blog. Esta entrada sería un subcomponente que tiene una imagen, un título y un cuerpo. El método draw (dibujar) del componente principal de nuestra aplicación dibujará el menú, la barra lateral y la entrada del blog. A su vez, el componente de la entrada dibujará la imagen, el título y el cuerpo de la misma.

Esta es una vista de cómo se vería una página web dividida en componentes:

The Composite Pattern

Este patrón no está limitado a la creación de vistas. Por ejemplo, si estuviéramos creando un juego podríamos tener un componente para gestionar los elementos de la pantalla, un componente para gestionar el audio y uno para manejar el estado del juego.

Todos estos estarían dentro de un componente al que llamo el motor del juego. Este motor tendría un método de inicialización que invocaría al método inicializar de cada uno de sus subcomponentes. Ese es el poder del uso del patrón compuesto. En vez de trabajar con objetos individuales podemos tratarlos como un solo objeto.

Conclusión

La herencia nos permite reutilizar código definiendo un objeto en términos de otro objeto. El patrón decorador nos permite añadir responsabilidades a un objeto sin cambiar el código original ni las subclases. El patrón compuesto modela relaciones parte-todo. Estos patrones no están destinados a ser usados de forma aislada.

JavaScript se ha convertido en el lenguaje para trabajar en la web. No está exento de curvas de aprendizaje, y hay muchos frameworks y bibliotecas para mantenerte ocupado también. Si estás buscando recursos adicionales para estudiar o usar en tu trabajo, consulta lo que tenemos disponible en Envato Market.

Estos pueden ser combinados como mejor te parezca. Los ejemplos que he proporcionado tampoco deben ser tomados como la única aplicación de los patrones. Estos solamente son una guía. Tómate la libertad de usar tu creatividad para aplicarlos. No hay solamente una manera de implementarlos ni un solo caso de uso.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.