Interfaces

La superficie que otros pueden usar

Una interface arquitectónica describe qué capacidades, operaciones, datos o comportamiento expone deliberadamente un elemento a otros. Permite razonar sobre colaboración sin exigir que el consumidor conozca toda la implementación. El alcance necesita contexto: qué elemento ofrece la superficie, quién la usa y para qué.

En Commerce, Payments expone la capacidad de autorizar un pago. Orders necesita solicitarla y comprender el resultado; no necesita controlar los detalles privados del proveedor. Esa capacidad puede realizarse de distintas maneras, cada una con expectativas que deben documentarse.

Para el Atlas, usamos interface como superficie expuesta y contract para las expectativas u obligaciones que gobiernan su uso. Es una distinción de preguntas, no una separación universal de conceptos. Muchas fuentes incluyen semántica y obligaciones dentro de la documentación de interfaces.

El SEI propone documentar información sintáctica y semántica de las interfaces, incluyendo expectativas necesarias para usarlas correctamente. Por eso la lista de métodos o campos no basta para comprender una colaboración arquitectónica. Documenting Software Architecture: Documenting Interfaces.

Más que una palabra del lenguaje

Una declaración como public interface IOrderService puede materializar una interface arquitectónica. También puede ser un detalle local sin significancia para el análisis actual. La keyword no establece automáticamente un límite de responsabilidad ni una abstracción apropiada.

Una interface puede expresarse mediante funciones, un contrato HTTP, mensajes, un formato de archivo, una vista SQL, una CLI, un schema de evento o un contrato de plugin. Depende de qué interacción se expone y qué necesita comprender el consumidor.

Un archivo de conciliación es una interface si Payments lo ofrece a otra parte con un significado acordado. Las columnas y tipos importan; también qué período cubre, qué representa cada importe y qué sucede si el archivo se publica nuevamente. No requiere un servidor ni una clase interface.

A la inversa, hacer públicos todos los tipos de un módulo puede aumentar superficie accesible sin constituir una exposición deliberada y coherente. Conviene diferenciar lo técnicamente visible de aquello que se promete sostener para consumidores.

Interface y API

API es una forma común de interface, especialmente para uso programático. Interface no significa solamente REST API ni catálogo de endpoints. Otros medios también ofrecen capacidades o datos que alguien interpreta y utiliza.

Una colección de endpoints tampoco demuestra una boundary saludable. Si Orders debe conocer el schema privado del proveedor y reproducir su secuencia interna, el acceso puede estar organizado como API y conservar un acoplamiento que el diseño pretendía evitar.

La pregunta arquitectónica es qué responsabilidad se expone y qué decisiones quedan ocultas. Las convenciones del transporte pueden ayudar a usarla, pero no reemplazan ese análisis. No corresponde diseñar una API completa aquí: interesa su papel en la colaboración y los compromisos que crea.

Interface, contract y connector

Como ayuda de razonamiento del Atlas:

PreguntaEjemplo de Commerce
¿Qué puede usarse?Payments expone AuthorizePayment(command).
¿Cómo ocurre la interacción?Orders la solicita mediante HTTP request/response.
¿Qué obligaciones gobiernan el uso?Significado de autorizado, entradas legales, errores y compatibilidad.

connectors explica el mecanismo o relación que media la interacción. Contract puede incluir sintaxis, semántica, errores, supuestos temporales y reglas de compatibilidad. No presentamos esta separación como tres capas obligatorias ni como una clasificación estandarizada para toda literatura.

Una interface comparable puede realizarse mediante otro connector. Sin embargo, pasar de llamada local a mensajes puede cambiar cuándo se conoce el resultado y qué fallos son observables. Conservar el nombre AuthorizePayment no convierte esas alternativas en contratos idénticos.

También existen interfaces requeridas: el consumidor necesita cierta capacidad para cumplir su responsabilidad. Eso no obliga a describir el mecanismo de ensamblaje en toda vista. Conviene precisar qué ofrece Payments y qué espera Orders, y comprobar que ambas descripciones sean compatibles.

Semántica y obligaciones

AuthorizePayment debe aclarar si autorizado significa aceptación de la solicitud, confirmación del proveedor o permiso para capturar posteriormente. Un consumidor que interpreta aceptación como pago final podría liberar un pedido antes del resultado esperado, aunque el schema sea correcto.

El contrato puede expresar estados válidos, errores de negocio, efectos posibles y qué información permite reconocer una solicitud anterior. No todos los detalles internos merecen exposición. Deben aparecer aquellos necesarios para usar la capacidad sin inventar garantías.

Las expectativas temporales también importan. Una respuesta inmediata, una aceptación con resultado posterior y una consulta de estado son superficies diferentes o variantes con obligaciones diferentes. El consumidor necesita saber qué progreso está permitido y qué incertidumbre puede permanecer.

interoperability evalúa si los participantes pueden intercambiar información y usarla con significado compatible. Compartir schema, nombres de campos o protocolo no garantiza esa propiedad. Dos equipos pueden interpretar una fecha o un estado de maneras incompatibles usando exactamente la misma representación.

Ocultar decisiones sin ocultar el compromiso

Parnas propone organizar módulos alrededor de decisiones de diseño que conviene ocultar a otras partes, especialmente aquellas susceptibles de cambio. Las interfaces deben evitar exponer innecesariamente esos detalles. Lo tomamos como criterio para revisar una superficie, sin exigir una tecnología concreta. On the Criteria To Be Used in Decomposing Systems into Modules, 1972.

Payments puede traducir resultados del proveedor a estados públicos de Commerce. Orders depende de esos estados acordados y no de códigos privados que cambian al sustituir la integración. La traducción conserva obligaciones comerciales; no promete que cualquier proveedor soporte exactamente las mismas capacidades.

Una interface pequeña no es automáticamente una buena abstracción. Un único método Execute con un objeto genérico puede exigir conocer flags, tipos internos y secuencias privadas. Una superficie más explícita puede comunicar mejor obligaciones y limitar malentendidos.

Tampoco lo más genérico es siempre lo más reutilizable. Abandonar significado para aceptar cualquier entrada desplaza decisiones al consumidor. Una capacidad precisa puede ser útil en varios contextos precisamente porque sus límites son comprensibles.

Interfaces y dependencies

dependency-structure permite identificar qué necesita un consumidor para construir, operar o evolucionar. Una interface ofrece un objetivo explícito para algunas dependencias; no las elimina. Orders sigue dependiendo de la capacidad de autorizar, su semántica, disponibilidad y compatibilidad.

Depender de una abstracción puede evitar ciertos detalles concretos y conservar obligaciones importantes. Si autorizado cambia de significado, el consumidor necesita revisar comportamiento aunque la firma no cambie. El contrato público también es conocimiento compartido.

ports-and-adapters utiliza ports para expresar capacidades en una frontera y adapters para relacionarlas con mecanismos externos. No exige interfaces de lenguaje para todas las clases. Su valor depende de si el contrato protege una variación significativa y conserva las obligaciones al cambiar una implementación.

Boundaries y acceso deliberado

boundaries pregunta dónde cambia responsabilidad o autoridad. Una interface permite cruzar un límite de forma acordada. No establece por sí sola enforcement: otros accesos pueden seguir abiertos, y una operación pública puede exponer internals.

Orders que solicita una autorización respeta la autoridad de Payments si esa operación concentra las reglas correspondientes. Orders que actualiza directamente un estado privado la evade. Disponer de ambos caminos vuelve insuficiente la interface como evidencia de protección del límite.

También hay interfaces internas y externas con consumidores distintos. Una operación administrativa puede requerir autoridad diferente de la operación comercial. Documentar quién puede usar cada superficie ayuda a comprender el límite sin convertir este documento en un tutorial de seguridad.

Commerce: realizaciones y cambios

En un deployment común, Orders puede usar una operación local de Payments y conservar los límites del módulo. En otra variante, una petición HTTP representa la solicitud. Una tercera publica un comando y recibe el resultado después. Las responsabilidades pueden ser comparables; sus contratos temporales y mecanismos de recuperación requieren análisis propio.

El proveedor contractual obligatorio constituye una constraint para Payments, no una razón para exponer cada decisión privada del proveedor a Orders. Payments puede definir una superficie adecuada a Commerce mientras mantiene esa dependencia externa.

Si el proveedor nuevo no soporta autorización separada de captura, el cambio no es solamente de connector. Puede afectar la capacidad prometida y requerir una decisión comercial. Una interface ayuda a localizar la incompatibilidad, pero no hace equivalentes capacidades distintas.

Estabilidad, evolución y costo

parallel-change ofrece una transición explícita entre formas de contrato sin exigir actualizar a todos los usuarios simultáneamente. branch-by-abstraction utiliza una abstracción para sustituir implementación; esa superficie debe conservar las obligaciones pertinentes, no esconder incompatibilidades semánticas. El contrato puede necesitar evolución aunque la selección de proveedor quede localizada.

Interfaces estables pueden contribuir a modifiability al limitar propagación de cambios. deployability permite evaluar entrega compatible de participantes que cambian por separado. evolvability observa adaptación sostenida, que exige revisar si los compromisos siguen siendo adecuados.

Estabilidad no significa congelación indefinida. Mantener compatibilidad consume esfuerzo, reduce ciertas libertades y puede requerir versionado, transición y deprecation. Romper un contrato también tiene costo para consumidores; la elección necesita un horizonte y evidencia. sunsetting distingue retirar un contrato de sustituir su implementación: una traducción de v1 sobre v2 puede conservar las obligaciones públicas aunque desaparezca el código anterior.

Agregar campos compatibles sintácticamente puede cambiar interpretación, defaults o resultados. Una revisión útil ensaya consumidores reales y escenarios de error, además de comparar schemas. Preservar formas sin preservar significado deja una incompatibilidad escondida.

backend-for-frontend ofrece otro ejemplo: cliente–BFF y BFF–capacidad exponen contratos distintos. Adaptar un resumen para checkout no transfiere al BFF autoridad sobre pagos. Revisar cambios, errores y respuestas parciales en ambas superficies evita que una API aparentemente estable esconda incompatibilidades con la experiencia o con la capacidad que representa.

Preguntas para revisar una interface

Precisar qué expone, a quién, qué oculta y qué obligaciones permiten usarla correctamente. Revisar resultados inciertos, acceso a internals y consumidores que requieren conocimientos adicionales.

Después comparar un cambio concreto de Payments con las expectativas de Orders. El objetivo es una colaboración comprensible y sostenible, donde la superficie revele compromisos útiles sin multiplicar abstracciones que no protegen ninguna decisión relevante.