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 denomina objeto base. Alguna información que un metaobjeto puede definir incluye el tipo , la interfaz , la clase , los métodos , los atributos , el árbol de análisis , etc. del objeto base. Los metaobjetos son ejemplos del concepto informático de reflexión , donde un sistema tiene acceso (normalmente en tiempo de ejecución) a su propia estructura interna. La reflexión permite a un sistema reescribirse esencialmente sobre la marcha, para alterar su propia implementación a medida que se ejecuta. [1]
Un protocolo de metaobjetos (MOP) proporciona el vocabulario ( protocolo ) para acceder y manipular la estructura y el comportamiento de los sistemas de objetos. Las funciones típicas de un protocolo de metaobjetos 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 establece una distinción entre extender un objeto añadiéndole cosas y modificarlo redefiniéndolo, proponiendo que lo primero es una cualidad deseable (" los objetos deben ser extensibles para cumplir con los requisitos de futuros casos de uso "), mientras que lo segundo es indeseable (" los objetos deben proporcionar una interfaz estable que no esté sujeta a una revisión sumaria "). 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 en sí. En la práctica, esto significa que los programadores pueden utilizar los objetos para redefinirse a sí mismos, posiblemente de formas bastante complejas.
Además, el protocolo de metaobjetos no es meramente una interfaz a 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 meta -metaobjetos, y así sucesivamente hasta que se determina 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.
Implementar sistemas de objetos de esa manera abre la posibilidad de un rediseño discrecional radical, brindando una gran flexibilidad 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 auto-representación interna- pero la potencial destructividad de algunas actualizaciones no es trivial de predecir y puede ser difícil de razonar), dependiendo de la profundidad recursiva a la que se propaguen las modificaciones deseadas. [3] Por esta razón, el protocolo de metaobjetos, cuando está presente en un lenguaje, generalmente se usa con moderación y para propósitos 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 para el código compilado con una definición de modelo de clase alternativa. Algunos entornos han encontrado soluciones innovadoras para esto, por ejemplo, al manejar 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 la 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 clase en evolución. [6]
El primer protocolo de metaobjetos fue 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 a través de funciones genéricas en lugar de 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. En prácticamente todos los entornos comerciales de desarrollo integrado, reingeniería y CASE existe algún tipo de protocolo de metaobjetos para representar y manipular los artefactos de diseño. [10] [11] [12]
Un protocolo de metaobjetos es una forma de implementar la programación orientada a aspectos . Muchos de los primeros fundadores de las MOP, incluido Gregor Kiczales , se han convertido desde entonces 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 metaobjetos nativo.