scala - ¿Cómo se utilizan la co y la contra variación en el diseño de aplicaciones empresariales?
covariance contravariance (2)
Sé sobre el uso de co-
y contravariance
en la biblioteca estándar (por ejemplo, colecciones y Function
rasgo) Me pregunto cómo se usan la co-
y contravariance
en el diseño de aplicaciones empresariales del "mundo real".
El ejemplo clásico es funciones, tomando la interfaz de Scala para una función con un solo argumento:
trait Function1[-T1, +R]
Que es contravariante (la -
) para el argumento, y covariante (la +
) para el tipo de retorno.
¿Por qué?
Imagina que tienes estas clases:
class Timelord { ... }
class Doctor extends Timelord { ... }
class Enemy { ... }
class Dalek extends Enemy { ... }
Si tiene un método que toma, como parámetro, una función Doctor => Enemy
; entonces está bien proporcionar una instancia de TimeLord => Enemy
. Todavía aceptará casos de Doctor
.
Entonces, TimeLord => Enemy
es una subclase de Doctor => Enemy
porque TimeLord
es una superclase de Doctor
, es contravariante en ese parámetro.
Del mismo modo, una función que devuelve un Dalek
es válida cuando necesitas una función que devuelve algún Enemy
, porque un Dalek
es un Enemy
Así que Doctor => Dalek
es una subclase de Doctor => Enemy
porque Dalek
es una subclase de Enemy
, es covariante en ese parámetro.
Esencialmente, en cualquier lugar donde desee utilizar tanto el polimorfismo paramétrico (genéricos) como la herencia, probablemente terminará deseando la varianza del sitio de declaración ( +
/ -
) , use la varianza del sitio (comodines) , o más probablemente, ambos.
Los tipos polimórficos suelen ser abstracciones de alto nivel, por lo que mientras los objetos de su dominio no necesiten anotaciones de varianza, es probable que el código que escriba para manipular sus objetos de dominio tenga que usar anotaciones de varianza, al menos si los objetos de dominio son parte de la herencia. Las jerarquías, que parecen muy frecuentes.
Si analiza básicamente cualquier biblioteca o marco, encontrará un uso frecuente de las anotaciones de varianza. Si está abstrayendo su aplicación del "mundo real" correctamente, probablemente estará escribiendo muchas bibliotecas para respaldarla, con un pequeño núcleo de lógica de negocios crítica bien desconectada de toda la infraestructura de soporte. Toda esa infraestructura de soporte probablemente también hará uso frecuente de las anotaciones de varianza.