Diez patrones de diseño comunes, le permiten pasar la entrevista a la vez (proyecto gitbuh: AlgorithmPractice)

Introducción al proyecto

  • Este proyecto descompone las preguntas comunes de entrevistas escritas de las principales fábricas, rastrea la fuente hasta los principios de implementación subyacentes de las estructuras de datos y los algoritmos, y sabe cuáles son.
  • Establezca un sistema de estructura de conocimiento para una búsqueda fácil, dé la bienvenida a más amigos de ideas afines a unirse al proyecto AlgorithmPractice (los problemas y las solicitudes de extracción son bienvenidos).

Diez patrones de diseño comunes:

Inicio del texto

1. Modo singleton singleton

  • Implementación de código : Singleton
  • Ideas de diseño :
    • En algunos escenarios, necesitamos una clase para proporcionar solo un objeto de instanciación, por lo que hacemos que el constructor de la clase sea privado .
    • ¿Cómo obtenemos objetos de esta clase después de privados? Proporcionamos una función getInstance externamente para generar objetos privados.
    • Entonces, ¿de dónde vino este objeto privado? Si uno define el objeto al comienzo de la clase y luego lo devuelve a través de la función getInstance, lo llamamos modo hombre hambriento (porque tiene demasiada hambre, toda la comida / instancia debe ser nueva para esperarme). Si se define al principio, pero cuando se usa más tarde, nuevo en la función getInstance y return, se convierte en el modo perezoso.
    • ¿Por qué hay un modo de hombre hambriento y un modo de hombre perezoso? La diferencia entre el modo de hombre hambriento y el modo de hombre perezoso es cuando el nuevo objeto es nuevo. Sabemos que el nuevo objeto es un proceso que consume recursos y tiempo. Necesita CPU para programar y asignar memoria, especialmente para objetos grandes, objetos anidados, que a menudo se cargan. Es muy lento, y si lo cargamos cuando realmente lo usamos, ahorrará tiempo.
    • Entonces, ¿debería usar el modo de hombre perezoso? No, el modo de hombre perezoso no se usa bien, causará problemas de seguridad y aparecerán varios objetos, lo que viola la intención original del modo singleton y además causa problemas de seguridad de subprocesos.
    • Entonces, ¿cómo se puede utilizar para garantizar la seguridad? Está garantizado por bloqueo sincronizado, pero el bloqueo resultará en una pérdida de rendimiento ¿Qué pasa si esta pérdida se reduce y la operación es segura? Presentamos DCLSingletom, pero ¿DCLSingletom es necesariamente seguro? De hecho, no lo es. Debido al reordenamiento de las instrucciones, existe una cierta posibilidad de que ocurra un error al usar el objeto (el valor del atributo del objeto es nulo).
    • ¿Mejor sugerencia? Utilice la enumeración y la fatiga interna para implementar el modo singleton.
  • Nota :
    • Cuando utilice sincronizado, recuerde cooperar con volatile para prohibir el reordenamiento de instrucciones

2. Modo proxy

  • Implementación de código : Proxy
  • Ideas de diseño :
    • El surgimiento del modelo de agencia se basa principalmente en la herencia y reescritura de las características del lenguaje de desarrollo.
    • El modo proxy consiste en agregar algunas operaciones convencionales antes y después de la clase de ejecución real. Algunos métodos públicos que todos usarán. Las aplicaciones comunes, como el manejo unificado de excepciones, el registro unificado, el retorno de error unificado, etc., usan el modo proxy para hacer lo real. La clase de ejecución solo está relacionada con el negocio en sí, sin una consideración excesiva de otras situaciones.
    • Visualización de código:
  • La interfaz de proxy, la clase de proxy y la clase de proxy deben implementarla y anular sus métodos.
public interface ProxyInterface {
    
    
    void work();
}
  • Clase de proxy
public class Proxy implements ProxyInterface {
    
    
    ProxyInterface p;
    public Proxy(ProxyInterface r) {
    
    
        // TODO Auto-generated constructor stub
        p = r;
    }
    @Override
    public void work() {
    
    
        // TODO Auto-generated method stub
        System.out.println("i am Proxy, i am help real's work,work begin");
        p.work();
        System.out.println("i am Proxy, work end");
    }
}
  • Clase de ejecución real
public class Real implements ProxyInterface {
    
    

    @Override
    public void work() {
    
    
        // TODO Auto-generated method stub
        System.out.println("i am real, i am doing work");
    }
}
  • Lograr efecto
public class ProxyTest {
    
    

    @Test
    public void testProxy(){
    
    
        ProxyInterface r = new Real();
        ProxyInterface p = new Proxy(r);
        p.work();
    }
}
  • Nota :
    • En el diseño, la clase de proxy debe considerar más que la clase de proxy.

3. Modo estrategia estrategia

  • Implementación del código : estrategia
  • Ideas de diseño :
    • El modo de estrategia es en realidad similar al modo de agente en esencia, y se muestra después de empaquetar una capa.
    • Pero el agente usa la reescritura de la clase, y la estrategia realmente usa el empaque, jaja
    • La estrategia usa una clase como contenedor para empaquetar la clase real y usa un método uniforme para llamar a la clase envuelta.
    • El contenedor de políticas y la interfaz de políticas no tienen nada que ver con la clase de proxy y la interfaz de proxy
    • Código
  • Interfaz de políticas
public interface Strategy {
    
    
    void method();
}
  • Estrategia 1
public class strategy01 implements Strategy {
    
    
    @Override
    public void method() {
    
    
        // TODO Auto-generated method stub
        System.out.println("strategy01's method.");
    }
}
  • Estrategia 2
public class strategy02 implements Strategy {
    
    
    @Override
    public void method() {
    
    
        // TODO Auto-generated method stub
        System.out.println("strategy02's method.");
    }
}
  • Contenedor de estrategia
public class StrategyMethod {
    
    
    Strategy strategy;
    public StrategyMethod(Strategy strategy) {
    
    
        this.strategy = strategy;
    }
    public void opera() {
    
    
        strategy.method();
    }
}
  • efecto real
public class StrategyTest {
    
    
    @Test
    public void tetsStrategy(){
    
    
        Strategy s1 = new strategy01();
        Strategy s2 = new strategy02();
        StrategyMethod sm1 = new StrategyMethod(s1);
        sm1.opera();
        StrategyMethod sm2 = new StrategyMethod(s2);
        sm2.opera();
    }
}
  • Nota :

4. Modo de observador observador

  • Implementación del código : observador
  • Ideas de diseño :
    • El modo de observador es equivalente a los ojos en el juego. El observador inserta un ojo en el método de lo observado. Cuando se ejecuta el método de lo observado, el observador recibirá la información e iniciará el método de respuesta.
    • Por tanto, un modelo de observador completo incluye: el observado y el observador.
    • El observador debe tener un método específico para cargar al observador y otro método para notificar al observador
    • Por lo tanto, el observador también debe tener un método de devolución de llamada, que está esperando que el observador active
    • Código
  • Observador
public class ObserverDemo {
    
    
    String name;
    public ObserverDemo(String name) {
    
    
        this.name = name;
    }
    public void lister() {
    
    
        System.out.println(name + " --> 观察到异常,并采取行动");
    }
}
  • Observado
public class ObservableDemo {
    
    
    List<ObserverDemo> list = new ArrayList<>();
    public void attach(ObserverDemo observerDemo) {
    
    
        list.add(observerDemo);
    }
    public void normalaction() {
    
    
        System.out.println("ObservableDemo normalaction:普通方法不会引起观察 ");
    }
    public void action() {
    
    
        System.out.println("ObservableDemo action:特殊方法会引起观察");
        notification();
    }
    public void notification() {
    
    
        for (ObserverDemo o : list) {
    
    
            o.lister();
        }
    }
}
  • Lograr efecto
public class ObserverTest {
    
    
    @Test
    public void Testobserer(){
    
    

        //被观察者
        ObservableDemo observableDemo = new ObservableDemo();
        //观察者
        ObserverDemo observerDemo1 = new ObserverDemo("observerDemo1");
        ObserverDemo observerDemo2 = new ObserverDemo("observerDemo2");
        //被观察者将观察者加入自己的方法内
        observableDemo.attach(observerDemo1);
        observableDemo.attach(observerDemo2);
        //被观察者触发某个方法
        observableDemo.action();
        System.out.println("-----------------");
        observableDemo.normalaction();

    }
}
ObservableDemo action:特殊方法会引起观察
observerDemo1 --> 观察到异常,并采取行动
observerDemo2 --> 观察到异常,并采取行动
-----------------
ObservableDemo normalaction:普通方法不会引起观察 
  • Nota :

5. Modo visitante visitante

  • Implementación de código : visitante
  • Ideas de diseño :
  • Nota :

6, modo de fábrica de fábrica

  • Implementación de código : Fábrica
  • Ideas de diseño :
  • Nota :

7. Modo de delegación de delegados

  • Implementación de código :
  • Ideas de diseño :
  • Nota :

8. Modo prototipo de prototipo

  • Implementación de código :
  • Ideas de diseño :
  • Nota :

9, modo de plantilla de plantilla

  • Implementación de código : plantilla
  • Ideas de diseño :
    • La esencia del patrón de diseño de plantilla es un marco de algoritmo fijo
    • La clase principal tiene una plantilla fija, pero los pasos de implementación específicos de la plantilla abierta permiten que las subclases se reescriban
    • Código
  • padre
public abstract class TemplateDemo {
    
    
    public final void template() {
    
    
        method1();
        method2();
        method3();
    }
    public void method1() {
    
    
        System.out.println("father class first stop");
    }
    public void method2() {
    
    
        System.out.println("father class second stop");
    }
    public void method3() {
    
    
        System.out.println("father class third stop");
    }
}
  • Subclase
public class SubTemplate extends TemplateDemo {
    
    
    @Override
    public void method1() {
    
    
        System.out.println("sub class first step");
    }
}
  • lograr
public class TemplateTest {
    
    
    SubTemplate subTemplate = new SubTemplate();
    @Test
    public void testTemplate() {
    
    
        subTemplate.template();
    }
}
  • Nota :
    • El patrón de diseño de la plantilla general se implementará con programación en cadena.

10. Modo adaptador

  • Implementación de código : Adaptador
  • Ideas de diseño :
  • Nota :

Supongo que te gusta

Origin blog.csdn.net/ljfirst/article/details/105470727
Recomendado
Clasificación