Red de conocimiento informático - Conocimiento informático - ¿Qué principios se deben seguir para completar un buen diseño de software?

¿Qué principios se deben seguir para completar un buen diseño de software?

En concreto, no puedo terminar de escribir varios artículos, pero sí hablar desde mi experiencia. Por supuesto que es lo que personalmente creo que es lo más importante.

En primer lugar, muchos comentarios (por supuesto, excepto cuando el código es extremadamente simple y se ha indicado el significado)

En segundo lugar, se requiere una buena experiencia del cliente.

Lo siguiente está tomado de Internet: (Espero que pueda ayudarlo)

Principios generales de los patrones de diseño:

1. Principio de apertura y cierre, OCP. ): una entidad de software Se deben desarrollar extensiones y cerrar modificaciones. Es decir, al diseñar otro módulo, se debería poder ampliar ese módulo sin modificaciones. En otras palabras, debería ser posible cambiar el comportamiento del módulo sin modificar el código fuente y expandir el sistema manteniendo cierta estabilidad del sistema. Esta es la piedra angular y el principio más importante del diseño orientado a objetos (OOD).

2. Principio de sustitución de Liskov (a menudo abreviado como LSP).

(1), propuesta por Barbar Liskov, es la piedra angular de la herencia y la reutilización.

(2) Expresión estricta: Si cada objeto o1 de tipo T1 tiene un objeto o2 de tipo T2, de modo que el comportamiento de todos los programas P definidos por T1 no cambia cuando todos los objetos o1 son reemplazados por o2 cambia, entonces el tipo T2 es un subtipo del tipo T1.

En otras palabras, si una entidad de software utiliza una clase base, debe ser adecuada para sus subclases y no puede detectar la diferencia entre los objetos de la clase base y los objetos de la subclase en absoluto. Solo cuando la clase derivada pueda reemplazar a la clase base, las funciones de la unidad de software no se verán afectadas, la clase base se podrá reutilizar verdaderamente y la clase derivada podrá agregar nuevas funciones a la clase base.

(3). No se establece sustitución inversa.

(4).ltMozi. "Xiaoqu" dice: "Un caballo blanco es un caballo; un caballo blanco es un caballo; un caballo negro es un caballo; un chacal es un caballo; un chacal es un caballo".

(5) Famoso dicho occidental La rutina es: ¿Es el cuadrado una subclase del rectángulo (la respuesta es "no"). Asimismo, existe la relación entre elipses y círculos.

(6). Deberíamos heredar de clases abstractas tanto como sea posible en lugar de heredar de clases concretas. En términos generales, si hay dos clases concretas A y B que tienen una relación de herencia, entonces la solución de modificación más simple es crear una clase abstracta C y luego hacer de la clase A y la clase B una subclase de la clase abstracta C, es decir, si si hay una estructura de registro formada por relaciones de herencia, entonces todos los nodos de hoja en el diagrama de árbol jerárquico deben ser clases concretas y todos los nodos de rama deben ser clases o interfaces abstractas;

(7) La tecnología "Shrinkage Design (DBC para abreviar)" respalda el principio de sustitución de Liskov. Bertrand Meyer Bertrand describe esta técnica en detalle:

Utilizando DBC, el autor de una clase especifica explícitamente el contrato de la clase. Los contratos dan a los redactores de código de cliente una idea del comportamiento en el que pueden confiar. El contrato se especifica mediante las condiciones previas y posteriores declaradas para cada método. Para ejecutar un método, una condición previa debe ser verdadera. Después de la ejecución, este método debería garantizar que la poscondición sea verdadera. Es decir, cuando redeclaras una rutina en una clase derivada, solo puedes reemplazar la condición previa original con una condición previa igual o más débil, y solo puedes reemplazar la condición posterior original con una condición posterior igual o más fuerte.

3. El principio de inversión de dependencia requiere que el cliente dependa del acoplamiento abstracto.

(1) Declaración: No confíe en los detalles para la abstracción, confíe en la abstracción para los detalles. (Programar la interfaz, en lugar de implementar la acción)

(2) Expresión 2: Programar la interfaz significa que la declaración de tipo de variable, la declaración de tipo de parámetro, la declaración de tipo de retorno de método, la conversión de tipo de datos, etc. Debe utilizar la interfaz y las clases abstractas. Programar para implementación significa que no se deben usar clases concretas para declaraciones de tipos de variables, declaraciones de tipos de parámetros, declaraciones de tipos de retorno de métodos, conversiones de tipos de datos, etc.

Para garantizar esto, las clases concretas solo deben implementar los métodos declarados en interfaces y clases abstractas, y no deben proporcionar métodos redundantes.

Siempre que haya un tipo abstracto en el objeto referenciado, se utilizará siempre que se haga referencia al objeto, incluida la declaración de tipo de parámetros, la declaración de tipo de retorno del método y la declaración de tipo de variables de atributo. , etc.

(3) La diferencia entre interfaz y abstracción es que las clases abstractas pueden proporcionar una implementación parcial de algunos métodos, pero las interfaces no. Esta es probablemente la única ventaja de las clases abstractas. Si agrega un nuevo método concreto a una clase abstracta, todos los subtipos obtendrán inmediatamente el nuevo método concreto, pero las interfaces no pueden hacer esto. Si agrega un nuevo método a una interfaz, todas las clases que implementan la interfaz no se compilarán porque

(4) La implementación de una clase abstracta solo puede estar dada por sus subclases, es decir, la implementación definido en la clase abstracta Hereda la estructura de registro. Sin embargo, dado que los lenguajes comunes restringen una clase a heredar como máximo una superclase, la eficacia de utilizar la abstracción como herramienta de definición de tipos se reduce considerablemente.

A su vez, si observa las interfaces, encontrará que cualquier clase que implemente los métodos especificados en la interfaz puede tener un tipo de esta interfaz, y una clase puede implementar cualquier número de interfaces.

(5) Desde la perspectiva de la refactorización de código, es fácil refactorizar una única clase concreta en una interfaz. Solo necesita declarar una interfaz, agregar métodos importantes a la declaración de la interfaz y luego agregar palabras reservadas a la declaración de definición de clase específica para heredar de la interfaz.

Como clase concreta existente, no es fácil agregar una clase abstracta como tipo abstracto, porque es posible que esta clase concreta ya tenga una superclase. De esta manera, la clase abstracta recién definida debe ascender y convertirse en la superclase de esta superclase, y así sucesivamente. Finalmente, esta nueva clase abstracta debe estar en la parte superior de la jerarquía de tipos general, de modo que todos los miembros de la estructura de registro se vean afectados.

(6) Las interfaces son una herramienta ideal para definir tipos mixtos, que son tipos secundarios distintos del tipo principal de una clase. La tipificación mixta significa que una clase no solo tiene el comportamiento del tipo principal, sino que también tiene otros comportamientos auxiliares.

(7) Uso conjunto de interfaces y clases abstractas:

Debido a que las clases abstractas tienen la ventaja de proporcionar implementaciones predeterminadas y las interfaces tienen todas las demás ventajas, es una buena idea Úselos juntos elija.

En primer lugar, la interfaz sigue siendo responsable de declarar el tipo, pero al mismo tiempo, se proporciona una clase abstracta para darle a la interfaz una implementación predeterminada. Otras clases concretas que pertenecen a este tipo abstracto pueden optar por implementar esta interfaz o heredar esta clase abstracta. Si una clase concreta implementa esta interfaz directamente, debe implementar todas las interfaces por sí misma. Por el contrario, si hereda de una clase abstracta, puede guardar algunos métodos innecesarios, porque puede obtener automáticamente la implementación predeterminada de estos métodos de la clase abstracta, si necesita agregar un nuevo método a la interfaz, solo necesita; para agregar este método abstracto al mismo tiempo. La clase agrega una implementación concreta de este método, porque todas las subclases que heredan esta clase abstracta obtendrán este método concreto de esta clase abstracta. En realidad, este es el modo de adaptador predeterminado.

(8)¿Qué es la estrategia de alto nivel? Es la abstracción detrás de la aplicación y es el principio que no cambia con los cambios en detalles específicos. Es una metáfora institucional dentro de la institución.

4. Principio de aislamiento de interfaz (ISP)

(1) La dependencia de una clase de otra clase se basa en la interfaz más pequeña.

(2) Es mejor utilizar múltiples interfaces dedicadas que una única interfaz principal. Es una práctica alentadora proporcionar diferentes servicios a diferentes clientes según sus diferentes necesidades. Es como "ordenar por la gente", dependiendo de quiénes sean los invitados, y luego ofrecer diferentes grados de comidas.

(3) Las interfaces gruesas conducirán a un acoplamiento anormal y dañino entre sus clientes. Cuando un cliente solicita un cambio en la interfaz gruesa, afecta a todos los demás clientes. Por lo tanto, los clientes sólo deben confiar en los métodos que realmente necesitan llamar.

5. Principio de Reutilización de Compuestos/Agregados (CARP).

Utilice algunos objetos existentes en un objeto nuevo para que formen parte del nuevo objeto; el nuevo objeto puede reutilizar la funcionalidad existente delegándola al objeto. También hay una breve declaración de este principio de diseño: intente utilizar composición/agregación y trate de no utilizar herencia.

6. La Ley de Demeter (Demeter LoD) también se llama Principio de Mínimo Conocimiento (LKP), lo que significa que un objeto debe saber lo menos posible sobre otros objetos.

La Ley de Dmitri fue propuesta originalmente como regla para el estilo de diseño de sistemas orientados a objetos por Ian Holland en el otoño de 1987 para el diseño de un proyecto llamado Dmitri en la Universidad Northeastern, por lo que se llama Ley de Demetri. ley [LIEB89][LIEB86]. Esta ley es en realidad el principio rector del diseño de muchos sistemas famosos, como el sistema de software para el aterrizaje en Marte y el sistema de software para el satélite orbitador Europa de Júpiter.

Ningún principio de diseño orientado a objetos tiene tantas expresiones como la Ley de Demeter, como sigue:

(1) Habla solo con tus amigos inmediatos.

(2) No hables con extraños.

(3) Cada unidad de software tiene un conocimiento mínimo de otras unidades y se limita a aquellas unidades de software que están estrechamente relacionadas con ella.

Es decir, si dos clases no tienen que comunicarse directamente entre sí, entonces las dos clases no deberían interactuar directamente. Si una clase necesita llamar a un método de otra clase, puede reenviar la llamada a través de un tercero.

7. Principio de Responsabilidad Única (Principio de Responsabilidad Simple)

En lo que respecta a una clase, solo debe haber una razón para su cambio. Si puedes pensar en más de una motivación para cambiar una clase, entonces la clase tiene más de una responsabilidad. Deberías separar más cargos y crear algunas clases para cumplir con cada responsabilidad.