En una entrevista de trabajo reciente, no pude responder una pregunta sobre SOLID , más allá de proporcionar el significado básico de los diversos principios. Realmente me molesta. He hecho un par de días para investigar y aún tengo que presentar un resumen satisfactorio.
La pregunta de la entrevista fue:
Si mirara un proyecto .Net que le dije que seguía estrictamente los principios de SOLID, ¿qué esperaría ver en términos del proyecto y la estructura del código?
Me tambaleé un poco, realmente no respondí la pregunta, y luego bombardeé.
¿Cómo podría haber manejado mejor esta pregunta?
Respuestas:
S = Principio de responsabilidad única
Por lo tanto, esperaría ver una carpeta bien organizada / estructura de archivos y jerarquía de objetos. Cada clase / pieza de funcionalidad debe nombrarse de manera que su funcionalidad sea muy obvia, y solo debe contener lógica para realizar esa tarea.
Si viera grandes clases de gerentes con miles de líneas de código, eso sería una señal de que no se estaba siguiendo la responsabilidad individual.
O = Principio abierto / cerrado
Esta es básicamente la idea de que se debe agregar nueva funcionalidad a través de nuevas clases que tengan un mínimo impacto en / requieran la modificación de la funcionalidad existente.
Esperaría ver mucho uso de la herencia de objetos, subtipos, interfaces y clases abstractas para separar el diseño de una funcionalidad de la implementación real, permitiendo que otros vengan e implementen otras versiones sin afectar el original.
L = principio de sustitución de Liskov
Esto tiene que ver con la capacidad de tratar los subtipos como su tipo principal. Esto sale de la caja en C # si está implementando una jerarquía de objetos heredados adecuada.
Esperaría ver código que trate objetos comunes como su tipo base y métodos de llamada en las clases base / abstracta en lugar de instanciar y trabajar en los subtipos.
I = Principio de segregación de interfaz
Esto es similar a SRP. Básicamente, se definen subconjuntos más pequeños de la funcionalidad como interfaces y trabajar con aquellos a mantener su sistema desacoplado (por ejemplo, una
FileManager
podría tener el single A cargo de tratar con archivos de E / S, pero que podría poner en práctica unaIFileReader
yIFileWriter
que contenía las definiciones de métodos específicos para la lectura y redacción de archivos).D = Principio de inversión de dependencia.
Nuevamente, esto se relaciona con mantener un sistema desacoplado. Quizás serías en la búsqueda de la utilización de una biblioteca .NET Inyección de Dependencia, que se utilizó en la solución como
Unity
oNinject
o un sistema ServiceLocator comoAutoFacServiceLocator
.fuente
Muchas clases pequeñas e interfaces con inyección de dependencia por todas partes. Probablemente en un gran proyecto también usarías un marco de trabajo de IoC para ayudarte a construir y administrar las vidas de todos esos pequeños objetos. Ver https://stackoverflow.com/questions/21288/which-net-dependency-injection-frameworks-are-worth-looking-into
Tenga en cuenta que un gran proyecto .NET que sigue ESTRICTAMENTE principios SÓLIDOS no significa necesariamente una buena base de código para trabajar con todos. Dependiendo de quién era el entrevistador, él / ella puede haber querido que usted demuestre que comprende lo que significa SÓLIDO y / o que compruebe cuán dogmáticamente sigue los principios de diseño.
Usted ve, para ser SÓLIDO, debe seguir:
S principio de responsabilidad ingle, por lo que tendrá muchas pequeñas clases de cada uno de ellos haciendo una sola cosa
O principio de pluma cerrada, que en .NET generalmente se implementa con inyección de dependencia, que también requiere la I y la D a continuación ...
El principio de sustitución de L iskov es probablemente imposible de explicar en C # con una línea. Afortunadamente, hay otras preguntas que lo abordan, por ejemplo, https://stackoverflow.com/questions/4428725/can-you-explain-liskov-substitution-principle-with-a-good-c-sharp-example
Me nterface Segregación Principio trabaja en conjunto con el principio de Abierto Cerrado. Si se sigue literalmente, significaría preferir una gran cantidad de interfaces muy pequeñas en lugar de pocas interfaces "grandes"
D ependency principio de inversión de las clases de alto nivel no deben depender de las clases de bajo nivel, tanto debería depender de abstracciones.
fuente
Algunas cosas básicas que esperaría ver en la base de código de una tienda que adoptaba SOLID en su trabajo diario:
Muchos patrones adaptadores y compuestos: esperaría el uso de muchos patrones adaptadores (una clase que implementa una interfaz al "pasar" a la funcionalidad de una interfaz diferente) para agilizar la conexión de una dependencia desarrollada para un propósito en un poco diferentes lugares donde también se necesita su funcionalidad. Las actualizaciones tan simples como reemplazar un registrador de consola con un registrador de archivos violarán LSP / ISP / DIP si la interfaz se actualiza para exponer un medio para especificar el nombre de archivo a utilizar; en cambio, la clase del registrador de archivos expondrá a los miembros adicionales, y luego un Adaptador hará que el registrador de archivos se vea como un registrador de consola al ocultar las cosas nuevas, por lo que solo el objeto que une todo esto debe saber la diferencia.
Del mismo modo, cuando una clase necesita agregar una dependencia de una interfaz similar a una existente, para evitar cambiar el objeto (OCP), la respuesta habitual es implementar un patrón Compuesto / Estrategia (una clase que implementa la interfaz de dependencia y consume varios otros implementaciones de esa interfaz, con cantidades variables de lógica que permiten a la clase pasar una llamada a una, algunas o todas las implementaciones).
fuente
Distraiga con la discusión de Jon Skeet de cómo la 'O' en SOLID es "inútil y poco entendida" y haga que hablen de la "variación protegida" de Alistair Cockburn y el "diseño de herencia de Josh Bloch, o prohíbala".
Breve resumen del artículo de Skeet (¡aunque no recomendaría dejar caer su nombre sin leer la publicación original del blog!):
El OP preguntó: "¿Cómo podría haber manejado mejor esta pregunta?" Como ingeniero senior que realiza una entrevista, estaría enormemente más interesado en un candidato que pueda hablar de manera inteligente sobre los pros y los contras de los diferentes estilos de diseño de código que alguien que pueda recitar una lista de viñetas.
Otra buena respuesta sería: "Bueno, eso depende de qué tan bien lo hayan entendido. Si todo lo que saben es las palabras de moda SÓLIDAS, esperaría abuso de herencia, uso excesivo de marcos de inyección de dependencia, un millón de interfaces pequeñas, ninguna de las cuales reflejar el vocabulario de dominio utilizado para comunicarse con la gestión de productos ... "
fuente
Probablemente hay varias maneras de responder a esto con diferentes cantidades de tiempo. Sin embargo, creo que esto es más parecido a "¿Sabes lo que significa SÓLIDO?" Por lo tanto, responder a esta pregunta probablemente solo se reduce a acertar y explicarlo en términos de un proyecto.
Entonces, espera ver lo siguiente:
fuente
Esta es una excelente pregunta, aunque creo que es una pregunta difícil para la entrevista.
Los principios SOLID realmente gobiernan las clases y las interfaces y cómo se relacionan entre sí.
Esta pregunta es realmente una que tiene más que ver con archivos y no necesariamente con clases.
Una breve observación o respuesta que daría es que generalmente verá archivos que contienen solo una interfaz, y a menudo la convención es que comienzan con una I mayúscula. Más allá de eso, mencionaría que los archivos no tendrían código duplicado (especialmente dentro de un módulo, aplicación o biblioteca), y ese código se compartiría cuidadosamente a través de ciertos límites entre módulos, aplicaciones o bibliotecas.
Robert Martin analiza este tema en el ámbito de C ++ al diseñar aplicaciones de C ++ orientadas a objetos utilizando el método Booch (consulte las secciones sobre Cohesión, cierre y reutilización) y en Código limpio .
fuente