Inversión de confianza de los siete principios de diseño de java, el principio de sustitución de Liskov (combinación de código de texto para comprender)

Inversión de confianza de los siete principios de diseño de Java, el principio de sustitución de Richter y la combinación de código de texto para comprender

Lucha por si quieres, aprecia si lo consigues y olvídate si fallas. Puede que la vida no sea perfecta, pero debido a la imperfección, debemos seguir trabajando duro para crear y luchar. El tiempo es vida, por lo que debemos apreciar nuestras preciosas vidas y esperar con perseverancia cada encrucijada de nuestras vidas.

¿Cuáles son los siete principios de diseño?

  • Principio de responsabilidad única
  • Principio de aislamiento de interfaz
  • Principio de inversión de la dependencia (inversión)
  • Principio de sustitución de Richter
  • Principio de apertura y cierre
  • Ley de Dimit
  • Principio de reutilización sintético

Por lo general, todos comprenden los primeros seis y no existe un principio de reutilización sintético.

¿Por qué utilizar los siete principios de diseño?

  • Reutilización de código (no es necesario escribir el mismo código varias veces);
  • Legibilidad (estandarización de la programación, fácil de leer y comprender para otros programadores);
  • Extensibilidad (cuando es necesario agregar nuevas funciones, es muy conveniente, también llamado mantenibilidad);
  • Fiabilidad (cuando agregamos nuevas funciones, no afectará las funciones originales);
  • Hacer que el programa presente las características de alta cohesión y bajo acoplamiento

Principio de inversión de dependencia

Definición del principio de inversión de dependencia:

  • Los módulos de alto nivel no deben depender de módulos de bajo nivel, ambos deben depender de sus abstracciones
  • La idea central de confiar en el principio de inversión es la programación orientada a la interfaz.
  • El propósito de usar interfaces o clases abstractas es formular una buena especificación sin involucrar operaciones específicas, y delegar las tareas detalladas a la clase de implementación para completar

El principio de inversión de la confianza se basa en el concepto de diseño: comparado con los detalles, lo abstracto es mucho más estable. Un marco basado en la abstracción es mucho más estable que un marco basado en detalles . En Java, la abstracción se refiere a la interfaz o clase abstracta, y los detalles son la clase de implementación específica

Código ordinario:

//输出消息
public class QQNews {
    
    
    public  void  run(){
    
    
        Log.i("Inversion","我是 QQ 发送的消息 ");
    }
}
//接收消息
public class Information {
    
    
    public void showInfo(QQNews qqNews){
    
    
        qqNews.run();
    }
}

//使用代码:
Information information = new Information();
information.showInfo(new QQNews());

problema:

  • Interactúa directamente con la clase y el mensaje de transmisión es relativamente fijo.
  • Si quiero recibir mensajes de WeChat ahora, él no puede recibirlos, porque el código se ha corregido y ahora solo acepta mensajes de QQ. Si necesito recibir mensajes de WeChat, necesito reescribir el método para recibir mensajes de WeChat en el Clase de información.
  • No hay una 'capa de búfer', el método showInfo () interactúa directamente con la clase QQNews y la 'elasticidad' es demasiado baja
  • Si no se cumple con el principio de inversión de dependencia, la idea central del principio de inversión de dependencia es la programación orientada a la interfaz.

Siga el código del principio de inversión de dependencia:

    ///接收的消息
public interface Iinversion {
    
    
    void run();
}
//QQ发送消息
public class QQNews implements Iinversion {
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion", "我是 QQ 发送的消息");
    }
}
//微信发送消息
public class WeChatNews  implements Iinversion{
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion","我是 微信 发送的消息");
    }
}

Uso de código:

InversionBean inversionBean = new InversionBean();
inversionBean.run(new QQNews());
inversionBean.run(new WeChatNews());

ventaja:

  • El cliente (InversionBean) solo interactúa con Iinversion (interfaz), el acoplamiento se reduce y el principio de programación orientada a interfaz en inversión de dependencia se observa estrictamente.
  • El código no se arreglará como el anterior y no hay necesidad de juzgar ninguna condición. Recibiré mensajes QQ cuando pase QQ, y recibiré mensajes WeChat cuando pase WeChat. En comparación con los detalles, cosas abstractas son mucho más estables. Detalles Clase de implementación concreta

Tres formas de confiar en el principio de inversión:

método uno:

Complete la transferencia de la interfaz a través de la clase de implementación (QQNews) de la interfaz de transferencia (Iinversion)

public interface Iinversion {
    
    
    ///接收的消息
    void run();
}
public class QQNews implements Iinversion {
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion", "我是 QQ 发送的消息");
    }
}

Information information = new Information();
information.showInfo(new QQNews());

Camino dos:

Completar la transferencia de la interfaz mediante el método de construcción parametrizado

public interface Iinversion {
    
    
    ///接收的消息
    void run();
}

public class Information {
    
    

   Iinversion mIinversion;
   
    public Information(Iinversion iinversion) {
    
    
        mIinversion = iinversion;
    }
    public void showInfo(){
    
    
        mIinversion.run();
    }
}
//使用代码
Information information = new Information(new QQNews());
information.showInfo();

Camino tres:

Complete la transferencia de interfaz a través del método establecido:

public interface Iinversion {
    
    
    ///接收的消息
    void run();
}
//传递消息 
public class QQNews implements Iinversion {
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion", "我是 QQ 发送的消息");
    }
}

public class Information {
    
    

    private Iinversion mIinversion;

    public void showInfo(){
    
    
        mIinversion.run();
    }
    public void setIinversion(Iinversion iinversion) {
    
    
         mIinversion =iinversion;
    }
}

//使用代码:
Information information = new Information();
information.setIinversion(new QQNews());
information.showInfo();

Principio de sustitución de Richter

introducción básica:

  • El principio de sustitución de Richter fue propuesto por una mujer con el apellido del MIT en 1988

La definición del principio de sustitución de Richter:

  • Al heredar, siga el principio de sustitución de Richter y trate de no anular el método de la clase principal en la subclase
  • Todas las referencias a la clase base deben poder utilizar de forma transparente los objetos de sus subclases.
  • El principio de sustitución de Richter nos dice que la herencia en realidad mejora el acoplamiento de dos clases. En circunstancias apropiadas, los problemas pueden resolverse mediante agregación, composición y dependencia.
  • La clase padre en el programa puede ser reemplazada por la subclase

Incumplimiento del código del principio de sustitución de Richter:

public class ReplaceA {
    
    
    public int show(int a, int b){
    
    
        return  a+b;
    }
}

public class ReplaceB extends ReplaceA{
    
    
    @Override
    public int show(int a, int b){
    
    
        return  a-b;
    }
}

//使用代码:
 //里氏替换原则
ReplaceA replaceA = new ReplaceA();
ReplaceB replaceB = new ReplaceB();

Log.i("LiReplace","2 + 3 = "+replaceA.show(2,3)+"");
Log.i("LiReplace","2 + 3 = "+replaceB.show(2,3)+"");

Como puede verse:

  • La salida en la clase A es la suma de a + b
  • En la clase B, el método show () de la clase A se reescribe y la salida es ab

problema:

  • Debido a que la clase B hereda la clase A, todos los métodos de la clase A se pueden usar en la clase B, lo que conduce a un acoplamiento muy alto de la clase B
  • Y si se agregan algunos métodos nuevos a la clase A, y la clase B no se usa, también se mejorará el acoplamiento. Si no se usa la clase B, se puede llamar, ¿aumenta la invasividad de la clase B?
  • En este código, mi intención original de replaceB era llamar al método show () de la clase principal para sumar, ¡pero olvidé que reescribí el método show () de la clase principal para encontrar la diferencia!

Hipótesis 1:
Ahora olvido que la clase B ha anulado el método de la clase A. Utilizo show () en la clase B. El resultado que quiero es la suma . Pero, la clase B ha anulado el método de la clase A, dándome Calculado como diferencia , tal vez pueda encontrar el problema mirando el código, luego le daré un ejemplo.

Hipótesis 2: Ahora hay tres clases de BCD, todas heredadas de la Clase A

Si cambio mis requisitos ahora, quiero C para multiplicar y D para división, ¿cómo debería escribirlo? ¿Se juzga uno por uno? Y el acoplamiento es demasiado alto. Ahora A, B, C, D son cuatro Esta categoría se siente un poco confuso, esta es una forma, si hay ciento ochenta, no es directamente genial o (╥﹏╥) o

Echemos un vistazo a cómo seguir el principio de sustitución de Liskov:

Siga la redacción del principio de sustitución de Richter:

Solución:
deje que la clase A y la clase B hereden una clase principal más popular (BaseReplace)

public class BaseReplace {
    
    
}

public class ReplaceA extends BaseReplace{
    
    
    public int show(int a, int b){
    
    
        return  a+b;
    }
}

public class ReplaceB extends BaseReplace{
    
    
    public int show(int a, int b){
    
    
        return  a-b;
    }
}

UML图(2.1):

análisis:

  • La Clase A y la Clase B no tienen ninguna relación, son dos módulos completamente separados,
  • Sin acoplamiento en absoluto

Si usa los métodos de la clase A en la clase B:

A modo de combinación / agregación:

public class ReplaceB extends BaseReplace{
    
    
    ReplaceA replaceA = new ReplaceA();
    
    public int show(int a, int b){
    
    
        return  a-b;
    }

    public void useAshow(int a,int b ){
    
    
        replaceA.show(a,b);
    }
	public class ReplaceA extends BaseReplace{
    
    
	    public int show(int a, int b){
    
    
	        return  a+b;
	    }
	}
}
//使用代码
ReplaceB replaceB = new ReplaceB();
replaceB.useAshow(2,3)

Puede ver que el método de usar combinación en la clase B aún puede usar el método de la clase A

Este es el principio de sustitución de Richter

Principio de inversión de dependencia

Principio de sustitución de Richter

También te puede interesar:

Ir a la página del catálogo de patrones de diseño / principios de diseño

La originalidad no es fácil, recuerda que te gusta ~

Supongo que te gusta

Origin blog.csdn.net/weixin_44819566/article/details/112187562
Recomendado
Clasificación