Principios de programación SOLID

43

Con el tiempo pude entender dos partes de SOLID : la "S" y la "O".

"O" - Aprendí el Principio Abierto Cerrado con la ayuda del Patrón de Herencia y Estrategia.

“S”: aprendí el principio de responsabilidad única mientras aprendía ORM (la lógica de persistencia se elimina de los objetos de dominio).

De manera similar, ¿cuáles son las mejores regiones / tareas para aprender otras partes de SOLID (la "L", "I" y "D")?

Referencias

  1. msdn - Peligros de violar los principios de SOLID en C #
  2. channel9 - Aplicación de principios SOLID en .NET / C #
  3. Principios de OOPS (Principios SÓLIDOS)
LCJ
fuente
25
tome nota de que todas estas ideas son buenas ideas, y juntas son muy buenas. pero si los aplica dogmáticamente , causarán más fracaso que éxito.
3
Los OR-Mappers son buenos para la separación de preocupaciones, no para el principio de responsabilidad única. Vea esta publicación programmers.stackexchange.com/questions/155628/… para una discusión de las diferencias.
Doc Brown
Ejemplos del mundo real blog.gauffin.org/2012/05/…
LCJ
1
@JarrodRoberson Sí, es por eso que se los conoce cuidadosamente como pautas . Tampoco olvide el resto de los principios: adamjamesnaylor.com/2012/11/12/… (11 en total)
Adam Naylor
2
El enlace de @AdamNaylor ahora es 404ing, se ha movido a adamjamesnaylor.com/post/…
mattumotu

Respuestas:

54

Estuve en tu lugar hace un par de meses hasta que encontré un artículo muy útil.

Cada principio se explica muy bien con situaciones del mundo real que cada desarrollador de software puede enfrentar en sus proyectos. Estoy cortando aquí y señalando la referencia: Desarrollo de software SOLIDO, un paso a la vez .

Como se señaló en los comentarios, hay otra muy buena lectura en pdf: el desarrollo de software SOLID de Pablo .

Además, hay algunos buenos libros que describen los principios de SOLID con más detalles: Good Book on SOLID Software Development .

Edición y comentarios de un breve resumen de cada principio:

  • "S" - El Principio de Responsabilidad Única es impulsado por las necesidades del negocio para permitir el cambio. "Una sola razón para cambiar" le ayuda a comprender qué conceptos lógicamente separados deben agruparse considerando el concepto y el contexto del negocio, en lugar del concepto técnico solo. In another words, aprendí que cada clase debería tener una única responsabilidad. La responsabilidad es solo cumplir con la tarea asignada

  • “O” - Aprendí el Principio Abierto Cerrado y comencé a "preferir la composición sobre la herencia" y, como tal, preferir las clases que no tienen métodos virtuales y posiblemente están selladas, pero dependen de abstracciones para su extensión.

  • “L”: aprendí el Principio de sustitución de Liskov con la ayuda del patrón de repositorio para administrar el acceso a datos.

  • “I”: aprendí sobre el Principio de segregación de interfaces al aprender que los clientes no deberían verse obligados a implementar interfaces que no usan (como en Membership Provider en ASP.NET 2.0). Entonces la interfaz no debe tener "muchas responsabilidades"
  • "D" - Aprendí sobre el Principio de Inversión de Dependencia y comencé a codificar que es fácil de cambiar . Más fácil de cambiar significa un menor costo total de propiedad y una mayor capacidad de mantenimiento.

Como se mencionó en los comentarios un recurso útil de CodePlex, se incluye una referencia a SOLID por ejemplo

ingrese la descripción de la imagen aquí

EL Yusubov
fuente
3
La siguiente colección de artículos me pareció muy útil: lostechies.com/wp-content/uploads/2011/03/…
Scroog1
Leí todo el artículo y no me venden en patrones o en SOLID. El ejemplo es demasiado simplista, pero cuando se vuelve complejo, esa complejidad es artificial. Todavía tengo que encontrar la OOP SÓLIDA del mundo real sin mejores alternativas.
Trabajo
3
desde que se mencionaron los artículos de lostechies aquí también está este solidexamples.codeplex.com (basado en lostechies)
dark fader
2
Fui uno de los contribuyentes de Pablos eBook. Me alegra que la gente todavía lo encuentre útil. :)
Sean Chambers
1
+1000000 si pudiera para su resumen del principio de Open-Closed - todo el mundo se equivoca y piensa que se trata de herencia
AlexFoxGill
11

(I) La segregación de la superficie y (D) la Inversión de la dependencia se pueden aprender mediante pruebas unitarias y burlas. Si las clases crean sus propias dependencias, no puede crear buenas pruebas unitarias. Si dependen de una interfaz demasiado amplia (o ninguna interfaz), no es muy obvio qué se debe burlar para realizar las pruebas de su unidad.

StriplingWarrior
fuente
2
+1 esto es muy cierto. Ni siquiera tiene que cumplir con la regla (imo) a veces demasiado estricta de 'una prueba de unidad solo debe probar una cosa': si no puede encontrar un conjunto de pruebas decente para una clase en un par de minutos, viola I y D y probablemente el resto del alfabet también
stijn
8

El Principio de sustitución de Liskov básicamente no le permite usar en exceso la herencia de implementación: ¡nunca debe usar la herencia solo para la reutilización de código (hay composición para esto)! Al adherirse a LSP, puede estar bastante seguro de que realmente existe una "relación es-es" entre su superclase y su subclase.

Lo que dice es que sus subclases deben implementar todos los métodos de la subclase de manera similar a la implementación de los métodos en la subclase. Nunca debe anular un método con la implementación de NOP o devolver nulo cuando el supertipo arroja una excepción; indicado en los términos de Diseño por Contrato, debe respetar el contrato del método de la superclase al anular un método. Una forma de defenderse contra la ruptura de este principio es nunca anular un método implementado; en su lugar, extraiga una interfaz e implemente esa interfaz en ambas clases.

Principio de segregación de interfaz , Principio de responsabilidad única y Principio de alta cohesión de GRASP están de alguna manera relacionados; se refieren al hecho de que una entidad debe ser responsable de una sola cosa para que haya una sola razón para el cambio y que el cambio se realice con mucha facilidad.

En realidad dice que si una clase implementa una interfaz, entonces debe implementar y usar todos los métodos de esa interfaz. Si hay métodos que no son necesarios en esa clase en particular, entonces la interfaz no es buena y debe dividirse en dos interfaces, una que solo tenga los métodos necesarios para la clase original. Se puede considerar desde un POV, que se relaciona con el principio anterior por el hecho de que no le permite crear interfaces grandes para que su implementación pueda romper el LSP.

Puede ver la Inversión de dependencias en el Patrón de fábrica; aquí, tanto el componente de alto nivel (el cliente) como el componente de bajo nivel (instancia individual que se creará) dependen de la abstracción(La interfaz). Una forma de aplicarlo en una arquitectura en capas: no debe definir una interfaz para una capa en la capa que se implementa sino en el módulo que se llama. Por ejemplo, la API de la capa de origen de datos no debe escribirse en la capa de origen de datos sino en la capa de lógica de negocios, donde es necesario llamarla. De esta manera, la capa de origen de datos hereda / depende del comportamiento definido en la lógica de negocios (por lo tanto, la inversión) y no al revés (como sería de una manera normal). Esto proporciona flexibilidad en el diseño, permitiendo que la lógica de negocios funcione sin ningún cambio de código, con otra fuente de datos completamente diferente.

m3th0dman
fuente
1
Gran explicación sobre Liskov. :)
John Korsnes