Esta es una pregunta más filosófica, que aborda la plataforma .NET, pero tal vez sea útil también para otros idiomas. Estoy haciendo muchas pruebas unitarias y especialmente cuando uso componentes de terceros con los que a menudo me cuesta. En .NET hay una gran demanda de diseño de componentes (er) para elegir qué método debe ser virtual o no. Por un lado, es el uso de componentes (lo que tiene sentido ser virtual), por otro, es la simulación de componentes . Puede usar cuñas para simular componentes de terceros, pero esto a menudo conduce a un mal diseño y complejidad. Como puedo recordar, la discusión sobre cómo hacer que todos los métodos sean virtuales (JAVA lo tiene desde el principio) en .NET fue sobre el rendimiento. ¿Pero sigue siendo el problema? ¿Por qué no todos los métodos en .NET son virtuales o por qué cada clase no tiene al menos una interfaz?
fuente
Respuestas:
Como dice Anders , se trata en parte del rendimiento y en parte del bloqueo de diseños mal pensados para reducir el alcance de los problemas causados posteriormente por personas que heredan ciegamente cosas que no fueron diseñadas para ser heredadas.
El rendimiento parece obvio: si bien la mayoría de los métodos no se notarán en el hardware moderno, un captador virtual podría causar un golpe bastante notable, incluso en el hardware moderno que se basa cada vez más en instrucciones fácilmente predichas en la tubería de la CPU.
Ahora, la razón para hacer que todo sea virtual de manera predeterminada parece estar impulsada por una sola cosa: los marcos de prueba de unidad. Me parece que esta es una razón pobre, en la que estamos cambiando el código para adaptarlo al marco en lugar de diseñarlo correctamente.
Quizás el problema sea con los marcos utilizados aquí, deberían mejorar para permitir el reemplazo de funciones en tiempo de ejecución con cuñas inyectadas en lugar de crear código que lo haga (con todos los trucos para obtener métodos privados y no virtuales, no mencionar funciones estáticas y de terceros)
Entonces, la razón por la cual los métodos no son virtuales por defecto es como dijo Anders, y cualquier deseo de hacerlos virtuales para que se adapten a alguna herramienta de prueba de unidad es poner el carro delante del caballo, el diseño adecuado supera las limitaciones artificiales.
Ahora puede mitigar todo esto mediante el uso de interfaces o reelaborando toda su base de código para usar componentes (o microservicios) que se comunican mediante el paso de mensajes en lugar de llamadas a métodos directamente cableados. Si amplía la superficie de una unidad para probar que es un componente, y ese componente es completamente autónomo, realmente no necesita atornillarlo para probarlo.
fuente
Hay dos elementos en su pregunta, así que intentaré abordarlos a su vez:
¿Por qué los métodos .NET no son virtuales por defecto?
La herencia, en la práctica, tiene muchos problemas . Entonces, si se va a usar como parte de un diseño, entonces se debe considerar cuidadosamente. Al hacer que los métodos no sean virtuales por defecto, la teoría es que alienta al desarrollador a pensar en la herencia al diseñar una clase. Si eso funciona en la práctica es otra cuestión de rutina.
¿Por qué no todas las clases implementan una interfaz?
Mal diseño es la respuesta simple. A pesar de ser comúnmente reconocido como buenas prácticas durante mucho tiempo, lamentablemente mucha gente todavía no diseña sus sistemas con DI y TDD en mente.
La combinación de clases que no son completamente heredables y que no se burlan fácilmente crea una "tormenta perfecta" de código difícil de probar. Sin embargo, hasta que lleguemos al día en que todos usen DI y el principio de diseño de interfaz, no se puede hacer mucho para aliviar el dolor.
fuente
interface
solo porque. ¿Qué valor tiene tenerinterface
para lo que es esencialmente una tupla glorificada? (Aunque tal vez usar un POJO / POCO en sí mismo sea un defecto de diseño)As soon as you use classes as types, you are no longer doing OO
- Las clases son tipos. ¿¿Qué?? La herencia de clase normal es OO, no importa lo que digas. Ya no puedes decidir que ya no es OO solo porque DI está de moda ahora.