En informática , un metaobjeto es un objeto que manipula, crea, describe o implementa objetos (incluido él mismo). El objeto al que pertenece el metaobjeto se llama objeto base. Alguna información que un metaobjeto podría definir incluye el tipo , interfaz , clase , métodos , atributos , árbol de análisis , etc. del objeto base. Los metaobjetos son ejemplos del concepto informático de reflexión , donde un sistema tiene acceso (generalmente en tiempo de ejecución) a su propia estructura interna. La reflexión permite que un sistema esencialmente se reescriba a sí mismo sobre la marcha, para alterar su propia implementación a medida que se ejecuta. [1]
Un protocolo de metaobjeto (MOP) proporciona el vocabulario ( protocolo ) para acceder y manipular la estructura y el comportamiento de sistemas de objetos. Las funciones típicas de un protocolo de metaobjeto incluyen: [2]
El protocolo de metaobjetos es contrario al principio abierto/cerrado de Bertrand Meyer , que sostiene que los sistemas de objetos de software deben estar abiertos a la extensión pero cerrados a la modificación . Este principio efectivamente establece una distinción entre extender un objeto agregándole y modificar un objeto redefiniéndolo, proponiendo que el primero es una cualidad deseable (" los objetos deben ser extensibles para cumplir con los requisitos de futuros casos de uso "), mientras que el Esto último no es deseable (" los objetos deben proporcionar una interfaz estable no sujeta a revisión resumida "). El protocolo de metaobjetos, por el contrario, expone de forma transparente la composición interna de los objetos y todo el sistema de objetos en términos del sistema mismo. En la práctica, esto significa que los programadores pueden utilizar objetos para redefinirse a sí mismos, posiblemente de maneras bastante complejas.
Además, el protocolo de metaobjeto no es simplemente una interfaz para una implementación "subyacente"; más bien, a través del protocolo de metaobjetos, el sistema de objetos se implementa recursivamente en términos de un sistema de metaobjetos , que a su vez se implementa teóricamente en términos de un sistema de metaobjetos , y así sucesivamente hasta que se llega a un caso base arbitrario (un estado consistente del sistema de objetos). ), siendo el protocolo como tal la relación funcional recursiva entre estos niveles de implementación.
La implementación de sistemas de objetos de esta manera abre la posibilidad de un rediseño discrecional radical, proporcionando una flexibilidad profunda pero introduciendo problemas de metaestabilidad posiblemente complejos o difíciles de entender (por ejemplo, el sistema de objetos no debe actualizar destructivamente su propio protocolo de metaobjetos: su autocontrol interno). representación, pero el potencial destructivo de algunas actualizaciones no es trivial de predecir y puede ser difícil de razonar), dependiendo de la profundidad recursiva a la que se propagan las modificaciones deseadas. [3] Por esta razón, el protocolo de metaobjeto, cuando está presente en un lenguaje, generalmente se usa con moderación y para fines especializados, como software que transforma otro software o a sí mismo de maneras sofisticadas, por ejemplo en ingeniería inversa. [4]
Cuando la compilación no está disponible en tiempo de ejecución, existen complicaciones adicionales para la implementación del protocolo de metaobjetos. Por ejemplo, es posible cambiar la jerarquía de tipos con dicho protocolo, pero hacerlo puede causar problemas en el código compilado con una definición de modelo de clase alternativa. Algunos entornos han encontrado soluciones innovadoras para esto, por ejemplo, manejando problemas de metaobjetos en tiempo de compilación. Un buen ejemplo de esto es OpenC++. [5] El modelo orientado a objetos de la Web Semántica es más dinámico que la mayoría de los sistemas de objetos estándar y es consistente con los protocolos de metaobjetos en tiempo de ejecución. Por ejemplo, en el modelo de Web Semántica se espera que las clases cambien sus relaciones entre sí y existe un motor de inferencia especial conocido como clasificador que puede validar y analizar modelos de clases en evolución. [6]
El primer protocolo de metaobjeto estaba en el lenguaje de programación orientado a objetos Smalltalk desarrollado en Xerox PARC . El Common Lisp Object System (CLOS) llegó más tarde y fue influenciado por el protocolo Smalltalk, así como por los estudios originales de Brian C. Smith sobre 3-Lisp como una torre infinita de evaluadores. [7] El modelo CLOS, a diferencia del modelo Smalltalk, permite que una clase tenga más de una superclase ; esto plantea una complejidad adicional en cuestiones como la resolución del linaje de la jerarquía de clases en alguna instancia de objeto. CLOS también permite el envío dinámico de múltiples métodos , que se maneja mediante funciones genéricas en lugar del paso de mensajes como en el envío único de Smalltalk . [8] El libro más influyente que describe la semántica y la implementación del protocolo de metaobjetos en Common Lisp es The Art of the Metaobject Protocol de Gregor Kiczales et al. [9]
Los protocolos de metaobjetos también se utilizan ampliamente en aplicaciones de ingeniería de software. Prácticamente en todos los entornos CASE, de reingeniería y de desarrollo integrado comerciales existe alguna forma de protocolo de metaobjetos para representar y manipular los artefactos de diseño. [10] [11] [12]
Un protocolo de metaobjeto es una forma de implementar programación orientada a aspectos . Muchos de los primeros fundadores de MOP, incluido Gregor Kiczales , desde entonces se han convertido en los principales defensores de la programación orientada a aspectos. Kiczales et al. de PARC fueron contratados para diseñar AspectJ para Java , un lenguaje que no posee un protocolo de metaobjeto nativo.