ISP — qué es, el principio de segregación de interfaces en el desarrollo

Autor: IT Sectr Publicado: 2026-05-12 Tiempo de lectura: 9 min

ISP (Interface Segregation Principle) es el cuarto principio SOLID, que establece: los clientes no deben depender de métodos que no utilizan. El principio fue formulado por Robert Martin en el contexto del diseño de interfaces para sistemas orientados a objetos. Como se describe en el libro Clean Architecture (2017), el principio de segregación de interfaces exige crear interfaces estrechamente especializadas en lugar de una única universal, lo que reduce el acoplamiento y simplifica la realización de cambios.

Puntos clave

  • ISP — principio de segregación de interfaces, el cuarto en SOLID
  • Los clientes no deben depender de métodos que no invocan
  • Interfaces gruesas (Fat Interfaces) contienen métodos irrelevantes para algunos clientes
  • Dividir interfaces reduce el acoplamiento y mejora la reutilización del código
  • ISP está estrechamente relacionado con SRP y Responsabilidad Única a nivel de interfaces

¿Qué es ISP (Interface Segregation Principle)?

ISP (Interface Segregation Principle) es el principio de segregación de interfaces que prohíbe crear interfaces “gordas” con métodos que no utilizan todos los clientes. En lugar de una interfaz con una docena de métodos, se diseñan varias interfaces pequeñas, cada una para su grupo de clientes.

El principio fue introducido por Robert Martin como solución al problema de la “contaminación de interfaces”, cuando una clase se ve obligada a implementar métodos que no necesita solo porque están declarados en una interfaz común. En lenguajes tipados estáticamente, esto resulta en implementaciones vacías o lanzamiento de excepciones, un signo directo de violación de ISP.

ISP y SRP se complementan: SRP trata sobre la responsabilidad de la clase, ISP sobre los contratos de interfaces. SRP dice “una clase — una razón para cambiar”, ISP dice “una interfaz — un escenario de cliente”. Juntos forman una arquitectura modular donde cada elemento del sistema tiene límites claros.

Interfaces gruesas y sus consecuencias

Fat Interface — una interfaz que contiene más métodos de los que necesita un cliente específico. Por ejemplo, una interfaz Worker con métodos work, eat, sleep. Un robot trabajador no debería implementar eat y sleep, pero se ve obligado. La solución es dividir en Workable, Eatable, Sleepable. Cada cliente obtiene exactamente lo que necesita.

En el desarrollo móvil, las interfaces gruesas se encuentran en protocolos delegados y DataSource. Un protocolo puede contener métodos para dos escenarios diferentes (edición + visualización), aunque una pantalla específica use solo uno de ellos.

Cómo funciona el principio de segregación de interfaces

Implementar ISP comienza con analizar los clientes de cada interfaz. Si dos clientes usan diferentes conjuntos de métodos de una misma interfaz, la interfaz debe dividirse. Cada nueva interfaz agrupa métodos que se invocan juntos dentro de un mismo escenario.

El mecanismo de división: la interfaz original se divide en varias estrechas, cada una heredando la parte común (si la hay). Los clientes cambian a depender de la interfaz estrecha necesaria en lugar de la general. Las clases que implementan la interfaz original ahora implementan solo aquellas interfaces estrechas que realmente necesitan.

Una aclaración importante: el grado de división lo determina la cantidad de clientes y sus escenarios. ISP no exige la máxima división (micro-interfaces con un método cada una). Esto llevaría a una complejidad excesiva. El objetivo es eliminar la dependencia de los clientes de métodos innecesarios, no minimizar el tamaño de cada interfaz.

Señales de violación de ISP

Las principales señales de violación de ISP incluyen: clases que implementan una interfaz con métodos vacíos (implementación ficticia), lanzamiento de UnsupportedOperationException en implementaciones, una gran cantidad de parámetros o tipos de retorno que algunos clientes no usan, y cambios frecuentes en la interfaz que afectan solo a algunos clientes.

En el desarrollo Android, un ejemplo típico de violación de ISP es la interfaz OnItemClickListener, que incluye métodos para clic, clic prolongado y deslizamiento. Si una pantalla específica solo usa clic, los métodos restantes quedan vacíos. La solución es dividir en OnItemClickListener, OnItemLongClickListener, OnItemSwipeListener.

En el desarrollo iOS, la violación de ISP se manifiesta en los delegados de UIKit: un protocolo contiene métodos para diferentes estados del componente. UITableViewDelegate incluye métodos para visualización, selección, edición y acción de deslizamiento. Los desarrolladores a menudo implementan el protocolo completo con una docena de métodos vacíos. Dividir en varios protocolos por grupos de responsabilidad resuelve el problema.

Dependencia de métodos no utilizados

El problema no es solo estético. Cuando una interfaz cambia (se añade un nuevo método), todas las clases que la implementan deben actualizarse, incluso aquellas que no necesitan el nuevo método. En el desarrollo móvil con docenas de pantallas, esto provoca cambios en cascada. ISP aísla a cada cliente de cambios que no le conciernen.

La violación implícita de ISP ocurre a través de parámetros de configuración. Si un método acepta un objeto con muchos campos y el cliente usa solo 2 o 3 de ellos, es una señal para dividir. Alternativa: varios métodos especializados con un conjunto mínimo de parámetros.

En el desarrollo Android, ISP se viola al usar un único SharedPreferencesManager para leer y escribir toda la configuración de la aplicación. Un Fragment que solo necesita leer el tema obtiene una dependencia de un gestor global con una docena de métodos para diferentes tipos de datos. Dividir en ThemePreferenceProvider, AuthPreferenceProvider, FeatureFlagProvider es aplicar ISP a nivel de servicios de configuración. Cada proveedor contiene exactamente los métodos que necesitan sus clientes.

Ejemplos de ISP en aplicaciones móviles

Consideremos un ejemplo en Android con una interfaz para trabajar con datos. Violación de ISP: una interfaz para todas las operaciones CRUD, aunque no todos los clientes necesitan todas las operaciones.

kotlin
// Violación de ISP: interfaz gruesa
interface UserRepository {
    fun getAll(): List<User>
    fun getById(id: Int): User
    fun save(user: User)
    fun delete(id: Int)
}

// Después de aplicar ISP: interfaces estrechas
interface UserReader {
    fun getAll(): List<User>
    fun getById(id: Int): User
}

interface UserWriter {
    fun save(user: User)
    fun delete(id: Int)
}

// ReadOnlyViewModel no depende de métodos de escritura
class ReadOnlyViewModel(
    private val reader: UserReader
)

Un ejemplo en iOS con separación de protocolos para trabajar con medios:

swift
// Violación de ISP: un protocolo para todo el trabajo con medios
protocol MediaService {
    func play(url: URL)
    func pause()
    func stop()
    func upload(data: Data) async -> URL
    func download(url: URL) async -> Data
}

// Después de ISP: separación en protocolos por responsabilidad
protocol MediaPlayer {
    func play(url: URL)
    func pause()
    func stop()
}

protocol MediaTransfer {
    func upload(data: Data) async -> URL
    func download(url: URL) async -> Data
}

// PlayerViewModel no depende de métodos de descarga
class PlayerViewModel {
    private let player: MediaPlayer
}

Conclusión práctica: ISP protege a los clientes de cambios en partes no relacionadas de la interfaz. Dividir UserRepository en UserReader y UserWriter significa que los cambios en save no afectan a ReadOnlyViewModel, y viceversa. Cada cliente está aislado de la funcionalidad que no usa y no requiere cambios cuando se modifican otras partes del sistema.

ISP y SRP — un par natural. SRP define que una clase debe tener una única razón para cambiar. ISP aplica la misma lógica a las interfaces: una interfaz debe servir a un escenario de cliente. Una clase puede implementar varias interfaces estrechas (cada una correspondiente a una responsabilidad), lo que es más limpio que una interfaz gruesa con múltiples responsabilidades.

ISP y OCP también están relacionados: las interfaces estrechas son más fáciles de extender. Añadir un nuevo método a una interfaz estrecha solo afecta a sus clientes. Añadir un método a una interfaz gruesa afecta a todos los clientes, violando potencialmente OCP si los clientes se ven obligados a cambiar su implementación.

ISP y DIP trabajan juntos: DIP exige dependencia de abstracciones. ISP hace que estas abstracciones sean estrechas y enfocadas. Depender de una interfaz amplia sigue siendo una dependencia de una abstracción, pero una abstracción “mala” desde la perspectiva de ISP. Cuatro principios (SRP, OCP, ISP, DIP) forman la “pirámide de modularidad”: SRP e ISP definen límites, OCP y DIP definen formas de extensión y acoplamiento.

Aplicación de ISP en la arquitectura de componentes

La arquitectura de componentes en proyectos móviles (módulos, funcionalidades, capas) se beneficia de ISP a nivel de APIs públicas. Cada módulo exporta interfaces estrechas para sus consumidores, en lugar de una única fachada común. Esto permite cambiar la implementación interna del módulo sin afectar a los consumidores que usan solo parte de su funcionalidad.

En proyectos Android con Clean Architecture, ISP se aplica a UseCases: cada UseCase es una interfaz separada con un único método invoke o execute. El cliente (ViewModel) depende solo del UseCase que necesita, en lugar de un repositorio completo. Esto hace que las dependencias sean transparentes y comprobables.

Preguntas frecuentes

¿ISP conduce a una cantidad excesiva de interfaces?

Sí, la división excesiva es posible. ISP no exige una interfaz por cada método. El criterio es: ¿hay un cliente que necesita solo una parte de los métodos de la interfaz? Si todos los clientes usan todos los métodos, la interfaz no necesita dividirse. El nivel óptimo de división se determina por escenarios de uso reales.

¿Cómo se aplica ISP a los parámetros de funciones?

ISP a nivel de parámetros significa: una función no debe aceptar objetos con una gran cantidad de campos si solo usa una parte de ellos. En su lugar, se deben pasar solo los datos necesarios o usar interfaces especializadas (por ejemplo, una interfaz Renderable en lugar de un User completo).

¿En qué se diferencia ISP de LSP?

LSP trata sobre la herencia correcta y la compatibilidad conductual de subtipos. ISP trata sobre el diseño de interfaces: los clientes no deben depender de métodos que no usan. LSP responde a la pregunta “¿se puede usar una subclase en lugar de la clase base?”, ISP responde “¿necesita el cliente la interfaz completa?”

¿Cómo simplifica ISP las pruebas?

Las interfaces estrechas simplifican la creación de objetos mock: la prueba crea un mock con uno o dos métodos, no con una docena. Cuantos menos métodos tenga una interfaz, más fácil será simular su comportamiento. Esto reduce la carga cognitiva del desarrollador de pruebas y disminuye la probabilidad de errores en la lógica mock.

¿Cuándo se puede prescindir de ISP?

Si la interfaz es estable y todos los clientes usan todos los métodos, la división es redundante. Un ejemplo típico: los protocolos de UIKit diseñados por Apple. Dividirlos es arriesgado porque UIKit espera la implementación completa del delegado. En tales casos, la violación de ISP se justifica por la estabilidad de la API.

Resumen

  • ISP (Interface Segregation Principle) — el principio de segregación de interfaces, el cuarto en SOLID
  • El cliente no debe depender de métodos que no usa
  • Las interfaces gruesas obligan a las clases a implementar métodos innecesarios como stubs o excepciones
  • La división de interfaces reduce el acoplamiento y aísla a los clientes de los cambios
  • ISP + SRP forman los límites de los módulos: una responsabilidad — un contrato estrecho
  • Las pruebas mock se simplifican: una interfaz estrecha requiere menos stubs
  • La división óptima se determina por escenarios reales de cliente, no por la máxima división

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también