Explicación de 23 patrones de diseño en JAVA

Los 23 patrones de diseño de JAVA se explican a continuación:

 

 

1. Definición de patrón Singleton
: asegúrese de que una clase tenga solo una instancia y proporcione un punto de acceso global a ella.
Código genérico: (es seguro para subprocesos)

public class Singleton {
 private static final Singleton singleton = new Singleton();
//限制产生多个对象
 private Singleton(){
 }
 //通过该方法获得实例对象
 public static Singleton getSingleton(){
 return singleton;
 } 
 //类中其他方法,尽量是 static
 public static void doSomething(){
 } }

Escenarios de uso:
● Un entorno que requiere la generación de un número de serie único
● Se requiere un punto de acceso compartido o datos compartidos en todo el proyecto, como un contador en una página web, por lo que no necesita registrar cada actualización en la base de datos y use el modo singleton Mantenga el valor del contador y garantice la seguridad de subprocesos ●
Cree un objeto que consuma demasiados recursos, como acceder a recursos como IO y base de datos ●
Necesidad de definir una gran cantidad de constantes estáticas y métodos estáticos (como clases de herramientas) en el entorno, se puede adoptar el modo Singleton (por supuesto, también se puede declarar directamente como estático).

Ejemplo de hilo inseguro:

public class Singleton {
 private static Singleton singleton = null;
 //限制产生多个对象
 private Singleton(){
 } 
 //通过该方法获得实例对象
 public static Singleton getSingleton(){
 if(singleton == null){
 singleton = new Singleton();
 }
 return singleton;
 } }

Solución:
agregue la palabra clave sincronizada antes del método getSingleton, o agregue sincronizado en el método getSingleton para lograrlo. El enfoque óptimo es escribirlo como código genérico.

2. Modo de fábrica
Definición: defina una interfaz para crear un objeto, pero deje que las subclases decidan qué clase instanciar. El método de fábrica permite que una clase difiera la instanciación a las subclases.
Una clase. El método de fábrica retrasa la instanciación de una clase a sus subclases).
Product es responsable de definir la comunidad de productos para clases de productos abstractas y realiza la definición más abstracta de las cosas;
Creator crea clases para la abstracción, es decir, fábricas abstractas. La creación de clases de productos se realiza mediante la fábrica de implementación concreta ConcreteCreator.
Código de clase de fábrica específico:

public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c){
 Product product=null;
 try {
 product =
(Product)Class.forName(c.getName()).newInstance();
 } catch (Exception e) {
 //异常处理
 }
 return (T)product; 
 } }

Modo de fábrica simple:
un módulo solo necesita una clase de fábrica, no es necesario generarla, use métodos estáticos Clases de fábrica múltiples:
cada raza (clase de producto específica) corresponde a un creador, y cada creador es responsable de forma independiente Crear el objeto de producto correspondiente , que es muy consistente con el principio de responsabilidad única en lugar del patrón singleton: el
requisito principal del patrón singleton es que solo hay un objeto en la memoria, y solo se puede producir un objeto en la memoria a través del modo de método de fábrica Inicialización
diferida:
ProductFactory es responsable del trabajo de creación de objetos de clase de producto y genera un caché a través de la variable prMap, que está reservada para objetos que necesitan ser reutilizados nuevamente
Escenarios de uso: jdbc se conecta a la base de datos, acceso al hardware, reduce la generación y destrucción de objetos

3. Definición de patrón de fábrica abstracta
: proporciona una interfaz para crear familias de objetos relacionados o dependientes
sin especificar sus clases concretas (proporciona una interfaz para crear un grupo de objetos relacionados o interdependientes sin especificar su tipo específico).

Código de clase de fábrica abstracta:


public abstract class AbstractCreator {
 //创建 A 产品家族
 public abstract AbstractProductA createProductA();
 //创建 B 产品家族
 public abstract AbstractProductB createProductB();
}

Escenario de uso:
una familia de objetos (o un grupo de objetos sin ninguna relación) tienen las mismas restricciones.
Cuando se trata de diferentes sistemas operativos, puede considerar usar el patrón de fábrica abstracto.

4. Definición de patrón del método de plantilla
: defina el esqueleto de un algoritmo en una operación, aplazando algunos pasos a las subclases. El método de plantilla permite que las subclases redefinan ciertos pasos de un
algoritmo sin cambiar la estructura del algoritmo. El marco del algoritmo y algunos pasos se retrasan a la subclase. Para que la subclase pueda redefinir
algunos pasos específicos del algoritmo sin cambiar la estructura del algoritmo.)
AbstractClass se llama una plantilla abstracta, y sus métodos se dividen en dos categorías:
● Métodos básicos
Métodos básicos, también llamados básicos operaciones, son métodos implementados por subclases y llamados en métodos de plantilla.
● Método plantilla
Puede haber uno o varios métodos, generalmente es un método específico, es decir un framework, que implementa la programación de métodos básicos y completa la lógica fija.
Nota: Para evitar operaciones maliciosas, los métodos de plantilla generales se agregan con la palabra clave final y no se pueden sobrescribir.
Plantillas concretas: ConcreteClass1 y ConcreteClass2 pertenecen a plantillas concretas, que implementan uno o más métodos abstractos definidos por la clase principal, es decir, los métodos básicos definidos por la clase principal se pueden implementar en subclases Escenarios: ● Varias subclases tienen métodos públicos
,
y Cuando la lógica es básicamente la misma.
● Para algoritmos importantes y complejos, el algoritmo central se puede diseñar como un método de plantilla, y cada subclase puede realizar las funciones detalladas relevantes a su alrededor.
● Al refactorizar, el patrón del método de plantilla es un patrón de uso frecuente, que extrae el mismo código en la clase principal y luego restringe su comportamiento a través de la función de enlace (consulte "Extensión del patrón del método de plantilla").

5. Definición de Patrón Constructor
: Separar la construcción de un objeto complejo de su representación para que el mismo proceso de construcción pueda crear diferentes representaciones (Separar la construcción de un objeto complejo de su representación para que el mismo proceso de construcción Se puedan crear diferentes representaciones .)
● Producto La clase de producto
generalmente implementa el patrón de método de plantilla, es decir, hay métodos de plantilla y métodos básicos. BenzModel y BMWModel en el ejemplo pertenecen a la clase de producto.
● Constructor Constructor abstracto
La construcción de productos estandarizados generalmente se realiza mediante subclases. El CarBuilder del ejemplo pertenece al constructor abstracto.
● ConcreteBuilder
implementa todos los métodos definidos por la clase abstracta y devuelve un objeto construido. BenzBuilder y BMWBuilder en el ejemplo pertenecen a constructores de hormigón.
● Director La clase director
es responsable de organizar el orden de los módulos existentes y luego le indica al constructor que comience la construcción.Use
escenarios:
● Cuando se genera el mismo método, un orden de ejecución diferente y resultados de eventos diferentes, se puede usar el modo constructor. .
● Se pueden ensamblar múltiples componentes o partes en un solo objeto, pero los resultados de ejecución producidos son diferentes, entonces se puede usar este modo.
● La clase de producto es muy compleja o la secuencia de invocación en la clase de producto produce efectos diferentes, y es muy apropiado usar el patrón de construcción en este momento.
La diferencia entre el patrón de constructor y el patrón de fábrica:
La función principal del patrón constructor es la disposición de la secuencia de llamadas de los métodos básicos. Estos métodos básicos se han implementado, y los
objetos generados en diferentes órdenes también son diferentes;
el método de fábrica se centra en la creación, y la creación de piezas es su función principal. responsabilidad, y la secuencia de montaje no lo es.

6. Definición de patrón proxy
: proporciona un sustituto o marcador de posición para otro objeto para controlar el acceso a él
. ● RealSubject Rol de sujeto concreto También se le llama rol delegado y rol delegado. Es de quien se aprovecha y es el ejecutor específico de la lógica empresarial. ● Proxy Función de tema de proxy También se denomina clase de delegado y clase de proxy. Es responsable de la aplicación del rol real, confía la implementación de todas las restricciones de método definidas por la clase de tema abstracto al rol de tema real y realiza el trabajo de preprocesamiento y posprocesamiento antes y después de que se procese el rol de tema real . Proxy ordinario y proxy obligatorio: Proxy normal significa que necesitamos saber la existencia del proxy, es decir, la existencia de la clase GamePlayerProxy similar, antes de que podamos acceder a él; proxy obligatorio significa que la persona que llama llama directamente al personaje real sin importarle si el proxy existe, su proxy La generación de está determinada por caracteres reales. Proxy ordinario: en este modo, la persona que llama solo conoce el proxy y no necesita saber quién es el rol real, lo que protege el impacto del cambio del rol real en los módulos de alto nivel y puede modificar el rol del tema real como él quiere No hay impacto, siempre que implemente el método correspondiente a la interfaz, este modo es muy adecuado para ocasiones que requieren alta escalabilidad. Forzar proxy:













El concepto de hacer cumplir el proxy es buscar el rol de proxy del rol real, sin permitir el acceso directo al rol real. El módulo de alto nivel puede acceder a todos los métodos del rol real siempre que llame a getProxy. No necesita generar un proxy en absoluto, y la gestión del proxy ha sido completada por el propio rol real.
Proxy dinámico:
genera todos los métodos de acuerdo con la interfaz que se está representando, es decir, dada una interfaz, el proxy dinámico declarará "He implementado todos los métodos en esta interfaz".
Dos líneas de desarrollo independiente. El proxy dinámico se da cuenta de la responsabilidad del proxy, y el Sujeto de la lógica empresarial se da cuenta de las funciones lógicas relevantes, y no existe una relación de acoplamiento mutuo necesaria entre los dos. Notifique a Advice para que corte desde otro aspecto,
y finalmente acople en el módulo de alto nivel, es decir, Cliente, para completar la tarea de encapsulación de lógica.
Diagrama esquemático del proceso de llamada de proxy dinámico:
la intención del proxy dinámico: programación transversal, para mejorar o controlar el comportamiento del objeto sin cambiar la estructura de nuestro código existente.
Primera condición: la clase proxy debe implementar una interfaz.

7. Definición de patrón de prototipo
: especifique los tipos de objetos que se crearán utilizando una instancia de prototipo y cree nuevos objetos copiando este prototipo
. .)
Código general del modo de prototipo:


public class PrototypeClass implements Cloneable{
 //覆写父类 Object 方法
 @Override
 public PrototypeClass clone(){
 PrototypeClass prototypeClass = null;
 try {
 prototypeClass = (PrototypeClass)super.clone();
 } catch (CloneNotSupportedException e) {
 //异常处理
 }
 return prototypeClass;
 } }

El modo prototipo es en realidad para implementar la interfaz Cloneable y reescribir el método clone ().
Ventajas de usar el modo prototipo:
● Buen rendimiento
El modo prototipo es una copia del flujo binario de memoria, que es mucho mejor que crear directamente un objeto nuevo, especialmente cuando se va a generar una gran cantidad de objetos en un cuerpo de bucle, el prototipo modo puede reflejar mejor su ventaja.
● Evasión de la restricción del constructor
Esta es su ventaja y desventaja, copia directamente en la memoria, el constructor no se ejecutará (ver sección 13.4).
Escenarios de uso:
● Escenario de optimización de recursos
La inicialización de clases necesita consumir una gran cantidad de recursos, incluidos los recursos de datos y hardware.
● Escenarios con requisitos de rendimiento y seguridad
La creación de un objeto a través de nuevos requiere una preparación de datos o derechos de acceso muy engorrosos, por lo que se puede utilizar el modo prototipo.
● Escenarios en los que un objeto tiene varios modificadores
Cuando otros objetos necesitan acceder a un objeto, y es posible que cada autor de la llamada deba modificar su valor, puede considerar usar el modo prototipo para copiar varios objetos para que los use el autor de la llamada.
Copia superficial y copia profunda:
Copia superficial: el método clon proporcionado por la clase Object simplemente copia el objeto, y las matrices y los objetos de referencia dentro del objeto no se copian, pero aún apuntan a la dirección del elemento interno del objeto original. de copia se denomina copia superficial.Se copiarán otros tipos primitivos como int, long, char, string (como tipos primitivos), etc.
Nota: Al usar el modo prototipo, la variable miembro a la que se hace referencia debe cumplir dos condiciones antes de que se copie: una es la variable miembro de la clase, no la variable en el método; la otra es que debe ser un objeto de referencia mutable, no un tipo primitivo o un objeto inmutable.
Copia profunda: haga copias independientes de variables de clase privada
如:cosa.arrayList = (ArrayList)this.arrayList.clone();

8. Modo mediador
Definición: defina un objeto que encapsule cómo interactúa un conjunto de objetos. El mediador promueve el acoplamiento débil al evitar que los objetos se refieran entre sí
explícitamente, y le permite variar su interacción de forma independiente. (Use un objeto mediador para encapsular una serie de la interacción de objetos, el mediador hace que los objetos no necesiten interactuar entre sí explícitamente, por lo que el acoplamiento es suelto y la interacción entre ellos se puede cambiar de forma independiente.) ● Mediador rol de mediador abstracto El rol de mediador abstracto define una
interfaz
unificada , utilizando los roles de Comunicación entre colegas.
● Mediador concreto El rol de mediador concreto
realiza un comportamiento colaborativo mediante la coordinación de varios roles de compañeros de trabajo, por lo que debe depender del rol de cada compañero de trabajo.
● Rol de colega
Cada colega conoce el rol de mediador, y cuando se comunica con otros colegas, debe cooperar a través del rol de mediador. El comportamiento de cada clase colega se divide en dos tipos: uno es el comportamiento del colega mismo, como cambiar el estado del objeto mismo, manejar su propio comportamiento, etc. No hay dependencia, el segundo es el comportamiento que debe confiar en el intermediario para completar, llamado método dependiente (Dep-Method).
Código de mediador abstracto genérico:

public abstract class Mediator {
 //定义同事类
 protected ConcreteColleague1 c1;
 protected ConcreteColleague2 c2;
 //通过 getter/setter 方法把同事类注入进来
 public ConcreteColleague1 getC1() {
 return c1;
 }
 public void setC1(ConcreteColleague1 c1) {
 this.c1 = c1;
 }
 public ConcreteColleague2 getC2() {
 return c2;
}
 public void setC2(ConcreteColleague2 c2) {
 this.c2 = c2;
 }
 //中介者模式的业务逻辑
 public abstract void doSomething1();
 public abstract void doSomething2();
}

pd: La razón para usar la inyección de clase colega en lugar de la inyección abstracta es porque la clase abstracta no tiene los métodos que debe completar cada clase colega. Es decir, los métodos en cada clase colega son diferentes.
Pregunta: ¿Por qué la clase colega debería usar el constructor para inyectar el mediador, y el mediador usa el método getter/setter para inyectar la clase colega?
Esto se debe a que la clase colega debe tener un mediador, pero el mediador solo puede tener una parte de la clase colega.
Escenario de uso:
el patrón intermedio es adecuado para un acoplamiento estrecho entre varios objetos. El estándar de acoplamiento estrecho es: aparece una estructura de telaraña en el diagrama de clases, es decir, cada clase tiene una relación directa con otras clases.

9. Modo de comando
Definición: encapsule una solicitud como un objeto, lo que le permite parametrizar clientes con diferentes
solicitudes, poner en cola o registrar solicitudes y admitir operaciones que se pueden deshacer. La ● Recibir Rol de receptor Este rol es el rol de trabajo, y el comando debe ejecutarse cuando se pasa aquí, específicamente a nuestro anterior En el ejemplo, hay tres clases de implementación de Grupo (grupo de requisitos, grupo de arte, grupo de código) . ● Función de comando Aquí se declaran todos los comandos a ejecutar. ● Invocador Rol de invocador Recibe y ejecuta comandos. En el ejemplo, yo (el director del proyecto) estoy en este rol. Escenario de uso: el modo de comando se puede usar donde se considera que es un comando. Por ejemplo, en el desarrollo de GUI, el clic de un botón es un comando, y el modo de comando se puede usar; al simular un comando de DOS, por supuesto también se debe utilizar el modo de comando; manejo del mecanismo de disparo-retroalimentación, etc.








10. Definición del modo de cadena de responsabilidad
: Evite vincular al remitente de una solicitud con su receptor dando a más de un objeto la oportunidad de manejar la solicitud. Encadene los objetos receptores y pase
la solicitud a lo largo de la cadena hasta que un objeto la maneje. Los objetos tienen la oportunidad de procesar la solicitud, evitando así la relación de acoplamiento entre el remitente y el receptor de la solicitud. Conecte estos objetos en una cadena y pase la
solicitud a lo largo de esta cadena hasta que un objeto la maneje).
Código del controlador de abstracción:


public abstract class Handler {
 private Handler nextHandler;
 //每个处理者都必须对请求做出处理
 public final Response handleMessage(Request request){
 Response response = null; 
 //判断是否是自己的处理级别

if(this.getHandlerLevel().equals(request.getRequestLevel())){
 response = this.echo(request);
 }else{ //不属于自己的处理级别
 //判断是否有下一个处理者
 if(this.nextHandler != null){
 response =
this.nextHandler.handleMessage(request);
 }else{
 //没有适当的处理者,业务自行处理
 }
 }
 return response;
 }
 //设置下一个处理者是谁
 public void setNext(Handler _handler){
 this.nextHandler = _handler;
 }
 //每个处理者都有一个处理级别
 protected abstract Level getHandlerLevel();
 //每个处理者都必须实现处理任务
 protected abstract Response echo(Request request);
}

El procesador abstracto implementa tres responsabilidades:
una es definir un método de procesamiento de solicitudes handleMessage, el único método abierto al mundo exterior; la otra
es definir un método de disposición en cadena setNext para establecer el
próximo procesador; Hay dos formas de implementar: definir el nivel getHandlerLevel que puede manejar
y hacer eco de la tarea de procesamiento específica.
Nota:
La cantidad de nodos en la cadena debe controlarse para evitar la situación de cadenas súper largas. El método general es establecer una cantidad máxima de nodos en el controlador y juzgar si ha excedido su umbral en el método setNext. Si excede, no se permite que se establezca la cadena, para evitar interrumpir involuntariamente el rendimiento del sistema.

11. Definición de patrón de decorador
: adjunte responsabilidades adicionales a un objeto manteniendo dinámicamente la misma interfaz. Los decoradores brindan una alternativa flexible a las subclases para
ampliar la funcionalidad. (Agregue dinámicamente algunas responsabilidades adicionales a un objeto. En términos de agregar funcionalidad, el modo de decoración es más flexible que generar subclases.)
● Componente componente abstracto
Componente es una interfaz o una clase abstracta, que define nuestro objeto central, es decir, el objeto más primitivo, como la transcripción anterior.
Nota: En el modo de decoración, debe haber una interfaz o clase abstracta más básica, central y original como
componente abstracto de Component.
● ConcreteComponent El componente concreto
ConcreteComponent es el núcleo, el más original, la implementación más básica de la interfaz o clase abstracta, y es lo que desea decorar.
● Decorador Decorador
es generalmente una clase abstracta, ¿para qué se utiliza? Para implementar una interfaz o un método abstracto, puede que no haya necesariamente un método abstracto en él, y debe haber una variable privada que apunte al componente abstracto Componente en sus propiedades.
● Los roles de decoración específicos
ConcreteDecoratorA y ConcreteDecoratorB son dos clases de decoración específicas. Necesitas decorar tus cosas principales, más primitivas y básicas en otras cosas. El ejemplo anterior es para decorar una boleta de calificaciones mediocre como un padre. Transcripciones reconocidas
.
Escenarios de uso:
● Necesidad de ampliar la función de una clase o agregar funciones adicionales a una clase.
● Es necesario agregar dinámicamente funciones a un objeto, y estas funciones se pueden revocar dinámicamente.
● Es necesario modificar o agregar funciones para un lote de hermanos, por supuesto, es la primera opción para el modo de decoración.

12. Definición de patrón de estrategia : defina una familia de algoritmos, encapsule cada
uno y hágalos
intercambiables (defina un conjunto de algoritmos, encapsule cada algoritmo y hágalos intercambiables) . actúa como enlace entre el encapsulado anterior y el siguiente, protegiendo a los módulos de alto nivel del acceso directo a políticas y algoritmos, y encapsulando posibles cambios. ● Rol de la estrategia abstracta de estrategia La abstracción de estrategias y familias de algoritmos, generalmente una interfaz, define los métodos y atributos que debe tener cada estrategia o algoritmo. Los lectores pueden preguntar cuál es el significado de AlgorithmInterface en el diagrama de clase, oye, algoritmo significa "algoritmo", y el significado se entenderá cuando se combinen. ● ConcreteStrategy Los roles de estrategia concreta (múltiples) implementan las operaciones en la estrategia abstracta, y esta clase contiene algoritmos específicos. Escenarios de uso: ● Escenarios en los que varias clases difieren solo ligeramente en el algoritmo o el comportamiento. ● La escena en la que el algoritmo debe cambiarse libremente. ● Escenarios en los que es necesario proteger las reglas algorítmicas. Nota: si el número de estrategias específicas supera las 4, debe considerar usar el modo mixto Extensión del modo de estrategia: enumeración de estrategias













public enum Calculator {
 //加法运算
 ADD("+"){
 public int exec(int a,int b){
 return a+b;
 }
 },
 //减法运算
 SUB("-"){
 public int exec(int a,int b){
 return a - b;
 }
 };
 String value = "";
 //定义成员值类型
 private Calculator(String _value){
 this.value = _value;
 }
 //获得枚举成员的值
 public String getValue(){
 return this.value;
 }
 //声明一个抽象函数
 public abstract int exec(int a,int b);
}

Definiciones:
● Es una enumeración.
● Es una enumeración condensada de patrones de estrategia.
Nota:
Restringido por el tipo de enumeración, cada elemento de enumeración es público, final y estático, y la escalabilidad está sujeta a ciertas restricciones. Por lo tanto, en el desarrollo de sistemas, la enumeración de estrategias generalmente juega un papel que no cambia con frecuencia.
Defecto fatal: todas las estrategias deben exponerse, y depende del cliente decidir qué estrategia usar.

13. Definición de patrón de adaptador
: Convierta la interfaz de una clase en otra interfaz que los clientes esperan. El adaptador permite que las clases trabajen juntas que de otro modo no podrían debido a
interfaces incompatibles. (Transforme la interfaz de una clase en lo que el cliente espera. Otra interfaz para habilitar dos clases para trabajar juntas que de otro modo no funcionarían juntas debido a interfaces no coincidentes).
Adaptador de clase:
● Destino Rol de destino
Este rol define a qué interfaz se convierten otras clases, que es lo que esperamos interfaz, la interfaz IUserInfo en el ejemplo es el destino role.
● Rol de origen del adaptador ¿
A quién desea convertir en el rol de destino? Este "quién" es el rol de origen, es una clase u objeto existente que funciona bien y, después de ser empaquetado por el rol de adaptador, se convertirá en un nuevo y hermoso papel.
● Función de adaptador
La función principal del patrón de adaptador. Las otras dos funciones son funciones existentes y la función de adaptador debe crearse nuevamente. Su responsabilidad es muy simple: ¿cómo convertir la función de origen en la función de destino? Por herencia o
asociación de clases.
Escenario de uso:
cuando está motivado para modificar una interfaz que ya está en producción, el patrón de adaptador puede ser el patrón más adecuado para usted. Por ejemplo, cuando se amplía el sistema, es necesario utilizar una clase existente o recién creada, pero esta clase no se ajusta a la interfaz del sistema, ¿qué debo hacer? Utilice el patrón de adaptador, que también se menciona en nuestro ejemplo.
Nota:
No considere usar el modo de adaptador en la etapa de diseño detallado y use el escenario principal para aplicaciones extendidas.
Adaptador de objetos:
La diferencia entre un adaptador de objeto y un adaptador de clase:
un adaptador de clase es herencia entre clases, y un adaptador de objeto es una relación compuesta de objetos, que también se puede decir que es una relación de asociación de clases. Esta es la diferencia fundamental entre el dos. (Hay relativamente muchas escenas utilizadas por adaptadores de objetos en proyectos reales).

14. Definición de patrón de iterador
: proporciona una forma de acceder secuencialmente a los elementos de un objeto agregado sin exponer su representación subyacente (proporciona una forma de acceder a los elementos de un
objeto
sin exponer los detalles internos del objeto). iterador abstracto
El iterador abstracto es responsable de definir la interfaz para acceder y atravesar elementos, y básicamente tiene tres métodos fijos:
first() para obtener el primer elemento, next() para acceder al siguiente elemento, si isDone() ha visitado el fondo
(Java se llama método hasNext()).
● ConcreteIterator Iterador concreto
La función de iterador concreto debe implementar la interfaz de iterador para completar el recorrido de los elementos del contenedor.
● Contenedor abstracto agregado
El rol de contenedor es responsable de proporcionar una interfaz para crear un rol de iterador específico y debe proporcionar un
método como createIterator(), que generalmente es un método iterator() en Java.
● Agregado concreto Contenedor concreto El contenedor concreto
implementa el método definido por la interfaz del contenedor y crea un objeto que contiene el iterador.
pd: El modo iterador ha sido eliminado, y los iteradores han sido aplicados a varias clases de colección (colecciones) en java.Usar el iterador que viene con java ya ha satisfecho nuestras necesidades.

15. Patrón compuesto (Composite Pattern)
definición: Componga objetos en estructuras de árbol para representar jerarquías de parte-todo. Composite permite a los clientes tratar objetos individuales y
composiciones de objetos de manera uniforme. "estructura jerárquica, para que los usuarios tengan consistencia en el uso de objetos individuales y objetos compuestos).
● Componente El rol de componente abstracto
define los métodos y atributos comunes de los objetos compuestos y puede definir algunos comportamientos o atributos predeterminados, como getInfo en nuestro ejemplo. Está encapsulado en una clase abstracta.
● Leaf componente de hoja
Objeto hoja, no hay otras ramas debajo de él, que es la unidad de recorrido más pequeña.
● Componente de rama compuesta
Objeto de rama, su función es combinar nodos de rama y nodos de hoja para formar una estructura de árbol.
El código general del componente de rama:
public class Composite extends Component { //contenedor de componente private ArrayList componentArrayList = new ArrayList(); //agregar un componente de hoja o componente de rama public void add(componente componente){ this.componentArrayList.add( componente);






}
//Eliminar un componente de hoja o componente de rama
public void remove(componente componente){ this.componentArrayList.remove(component); } //Obtenga todos los componentes de hoja y componentes de rama bajo la rama public ArrayList getChildren(){ return this.componentArrayList ; } } Escenarios de uso: ● Mantenga y muestre escenarios de relación parte-todo, como menú de árbol, administración de archivos y carpetas. ● Escenarios en los que algunos módulos o funciones pueden aislarse de un todo. Nota: siempre que sea una estructura de árbol, considere usar el modo compuesto.










16. Definición de patrón de observador
: defina una dependencia de uno a muchos entre objetos para que cuando un objeto cambie de estado, todas sus dependencias se notifiquen y actualicen automáticamente (defina una dependencia de
uno a muchos entre objetos, de modo que cuando un objeto cambia de estado, todos los objetos que dependen de él serán notificados y actualizados automáticamente.)
● Sujeto Observador
Define las responsabilidades que debe implementar el observador, y debe poder agregar y cancelar observadores dinámicamente. Generalmente es una clase abstracta o una clase de implementación, y solo cumple con los deberes que debe realizar como observado: administrar al observador y notificar al observador
.
● Observer Observer
Después de recibir el mensaje, el observador realizará la operación de actualización (método de actualización) para procesar la información recibida.
● ConcreteSubject El observador específico
define la lógica empresarial del objeto observado y define qué eventos se notifican.
● ConcreteObserver Observadores específicos
Cada observador reacciona de manera diferente después de recibir un mensaje, y cada observador tiene su propia lógica de procesamiento.
Código general del observador:


public abstract class Subject {
 //定义一个观察者数组
 private Vector<Observer> obsVector = new Vector<Observer>();
 //增加一个观察者
 public void addObserver(Observer o){
 this.obsVector.add(o);
 }
 //删除一个观察者
 public void delObserver(Observer o){
 this.obsVector.remove(o);
 }
 //通知所有观察者
 public void notifyObservers(){
 for(Observer o:this.obsVector){
 o.update();
}
 } }

Escenarios de uso:
● Escenarios de comportamiento asociados. Es importante señalar que los comportamientos de asociación son relaciones divisibles, no "compuestas".
● Escenarios de activación multinivel de eventos.
● Escenarios de intercambio de mensajes entre sistemas, como el mecanismo de procesamiento de las colas de mensajes.
Nota:
● Problemas con la cadena de transmisión
En un patrón de observador, como máximo un objeto es tanto el observador como el observado, es decir, el mensaje se reenvía una vez (se pasa dos veces) como máximo.
● Problemas de procesamiento asíncrono
Hay muchos observadores y el tiempo de procesamiento es relativamente largo.El procesamiento asíncrono se usa para considerar los problemas de seguridad de subprocesos y colas.

17. Definición de patrón de fachada
: proporciona una interfaz unificada a un conjunto de interfaces en un subsistema. Facade define una interfaz de nivel superior que hace que el subsistema sea más fácil de usar. (Requiere que la comunicación entre el exterior de
un subsistema un objeto unificado El modo de fachada proporciona una interfaz de alto nivel, lo que hace que el subsistema sea más fácil de usar.)
● Rol de fachada
El cliente puede llamar al método de este rol. Este rol es consciente de todas las funciones y responsabilidades del subsistema. En circunstancias normales, este rol delegará todas las solicitudes enviadas desde el cliente al subsistema correspondiente, es decir, este rol no tiene una lógica comercial real, sino que es solo una clase de delegación.
● subsistema Rol del subsistema
Puede haber uno o más subsistemas al mismo tiempo. Cada subsistema no es una sola clase, sino una colección de clases. El subsistema desconoce la existencia de la fachada. Para el subsistema, la fachada es un cliente más.
Escenarios de uso:
● Proporcionar un módulo o subsistema complejo con una interfaz para el acceso externo
● Los subsistemas son relativamente independientes: el acceso externo al subsistema solo necesita operarse en una caja negra
● Evitar la propagación de riesgos provocados por personal de bajo nivel
Nota :
● Un subsistema puede tener múltiples fachadas
Las fachadas no participan en la lógica de negocios dentro del subsistema

18. Definición de Patrón Memento
: Sin violar la encapsulación, capturar y externalizar el estado interno de un objeto para que el objeto pueda ser restaurado a este estado más tarde
. Y guardar este estado fuera del objeto. De esta manera, el objeto puede ser restaurado a su estado original guardado. estado más adelante.)
● La función Originador
registra el estado interno en el momento actual, es responsable de definir qué estados pertenecen al rango de copia de seguridad y es responsable de crear y restaurar los
datos de la nota.
● El rol Memento (javabean simple)
es responsable de almacenar el estado interno del objeto Creador y proporcionar el estado interno requerido por el creador cuando sea necesario
.
● La función de administrador de mementos Caretaker (un Javabean simple)
administra, guarda y proporciona memos.
Escenarios de uso:
● Escenarios de estado relevantes que necesitan guardar y restaurar datos.
● Proporcionar una operación de reversión.
● En el escenario de réplica que necesita ser monitoreado.
● La gestión de transacciones de la conexión de la base de datos es utilizar el modo de memoria.
Nota:
●Vida útil de la nota
●Rendimiento de la nota
No utilice el modo de nota en escenarios en los que se crean copias de seguridad con frecuencia (como en un bucle for).
Nota del modo de clonación:
● El rol de iniciador combina el rol de iniciador y el rol de memo, y tiene funciones duales
Modo de memo de estado múltiple
● Se agrega una clase BeanUtils, en la que backupProp convierte todos los valores de atributos del iniciador en HashMap, lo cual es conveniente para memo almacenamiento de roles. El método restoreProp es devolver el valor en HashMap al rol de iniciador.
Código de clase de herramienta BeanUtil:

public class BeanUtils {
 //把 bean 的所有属性及数值放入到 Hashmap 中
 public static HashMap<String,Object> backupProp(Object bean){
 HashMap<String,Object> result = new
HashMap<String,Object>();
 try {
 //获得 Bean 描述
 BeanInfo
beanInfo=Introspector.getBeanInfo(bean.getClass());
 //获得属性描述
 PropertyDescriptor[]
descriptors=beanInfo.getPropertyDescriptors();
 //遍历所有属性
 for(PropertyDescriptor des:descriptors){
 //属性名称
 String fieldName = des.getName();
 //读取属性的方法
 Method getter = des.getReadMethod();
 //读取属性值
 Object fieldValue=getter.invoke(bean,new
Object[]{});
 if(!fieldName.equalsIgnoreCase("class")){
 result.put(fieldName, fieldValue);
 }
 }
 } catch (Exception e) {
 //异常处理
 }
 return result;
 }
 //把 HashMap 的值返回到 bean 中
 public static void restoreProp(Object bean,HashMap<String,Object>
propMap){
try {
 //获得 Bean 描述
 BeanInfo beanInfo =
Introspector.getBeanInfo(bean.getClass());
 //获得属性描述
 PropertyDescriptor[] descriptors =
beanInfo.getPropertyDescriptors();
 //遍历所有属性
 for(PropertyDescriptor des:descriptors){
 //属性名称
 String fieldName = des.getName();
 //如果有这个属性
 if(propMap.containsKey(fieldName)){
 //写属性的方法
 Method setter = des.getWriteMethod();
 setter.invoke(bean, new
Object[]{propMap.get(fieldName)});
 }
 }
 } catch (Exception e) {
 //异常处理
 System.out.println("shit");
 e.printStackTrace();
 }
 } }

Memo con múltiples copias de seguridad: Ligeramente mejor encapsulado: asegúrese de que solo pueda ser leído por el creador.
Cree
una interfaz vacía. una clase) Memento implementa la interfaz IMemento y también implementa su propia lógica empresarial.

19. Definición de patrón Visitor
: Representa una operación a realizar sobre los elementos de una estructura de objeto. Visitor permite definir una nueva operación sin cambiar las clases de los
elementos sobre los que opera. Puede definir nuevas operaciones sobre estos elementos sin cambiar la estructura de datos.) ● Visitante: clase o
interfaz abstracta de visitante abstracto
, que declara qué elementos puede visitar el visitante Específicamente, en el programa, los parámetros del método de visita definen a qué objetos se puede acceder.
● ConcreteVisitor: visitante específico
Afecta lo que un visitante debe hacer y lo que debe hacer después de visitar una clase.
● Elemento:
interfaz de elemento abstracto o clase abstracta, que declara qué tipo de visitantes aceptar y se define mediante programación a través de los parámetros en el método de aceptación.
● ConcreteElement: el elemento concreto
implementa el método de aceptación, generalmente visitante.visita(esto), y básicamente forma un patrón.
● ObjectStruture——
Objeto de estructura El generador de elementos generalmente se aloja en múltiples contenedores de diferentes clases e interfaces, como List, Set, Map, etc. En los proyectos, esta función rara vez se abstrae.
Escenas a utilizar:
● Una estructura de objeto contiene muchos objetos de clase con diferentes interfaces y desea implementar algunas operaciones en estos objetos que dependen de sus clases específicas, es decir, la situación en la que el modo iterador ya no es suficiente.
● Es necesario realizar muchas operaciones diferentes y no relacionadas en los objetos de una estructura de objetos y desea evitar que estas operaciones "contaminen" las clases de estos objetos.

20. Definición de modo de estado (complejo)
: permite que un objeto altere su comportamiento cuando cambia su estado interno. El objeto parecerá cambiar su clase. Su clase.) ●
Estado——rol de estado abstracto
Interfaz o clase abstracta, responsable del objeto definición de estado y función de entorno de encapsulación para realizar el cambio de estado.
● ConcreteState—función de estado concreto
Cada estado concreto debe cumplir con dos responsabilidades: gestión del comportamiento del estado y procesamiento del estado de tendencia.
● Contexto: rol ambiental
Define la interfaz requerida por el cliente y es responsable del cambio de estados específicos.
Escenarios de uso:
● Escenarios en los que el comportamiento cambia con los cambios de estado
Este es también el punto de partida fundamental del patrón de estado, como el diseño de permisos. Las personas en diferentes estados tendrán resultados diferentes incluso si realizan el mismo comportamiento. En este caso, usted debe considerar el uso del patrón de estado.
● Un sustituto de las sentencias de juicio condicional y de ramificación
Nota:
El patrón de estado es aplicable cuando un objeto cambia su estado, su comportamiento también cambia mucho, es decir, cuando el comportamiento está restringido por el estado Puede usar el patrón de estado, y a la hora de usarlo,
lo mejor es no tener más de 5 estados del objeto.

21. Definición de patrón de intérprete
: Dado un idioma, defina una representación para su gramática junto con un intérprete que use la representación para interpretar oraciones en el idioma (
Dado un idioma, defina una gramática para su representación y defina un intérprete que use el representación para interpretar oraciones en el lenguaje.)
● AbstractExpression——intérprete abstracto
Cada clase de implementación completa las tareas de interpretación específicas, y los intérpretes específicos se componen respectivamente de TerminalExpression y
Non-terminalExpression Finish.
● TerminalExpression: la expresión terminal
implementa la operación de interpretación asociada con los elementos de la gramática. Por lo general, solo hay una expresión terminal en un modo de intérprete, pero hay varias instancias correspondientes a diferentes terminales. Específico de nuestro ejemplo es la clase VarExpression
, cada símbolo de terminal en la expresión genera un objeto VarExpression en la pila.
● NonterminalExpression——expresión de símbolo no terminal
Cada regla en la gramática corresponde a una expresión no terminal En nuestro ejemplo específico, las reglas de suma y resta corresponden a las dos clases AddExpression y SubExpression respectivamente. Las expresiones no terminales
aumentan según la complejidad de la lógica, en principio, cada regla gramatical corresponde a una expresión no terminal.
● Contexto: Rol ambiental
Específico de nuestro ejemplo es usar HashMap en su lugar.
Escenarios de uso:
● El modo intérprete se puede usar para problemas recurrentes
● Un escenario en el que se necesita explicar una sintaxis simple
Nota:
Trate de no usar el modo intérprete en módulos importantes, de lo contrario, el mantenimiento será un gran problema. En el proyecto, se pueden usar shell, JRuby, Groovy y otros lenguajes de secuencias de comandos en lugar del modo intérprete para compensar la deficiencia del lenguaje compilado de Java.

22. Definición de patrón de peso ligero
: use el uso compartido para admitir una gran cantidad de objetos de granularidad fina de manera eficiente
(el uso de objetos compartidos puede admitir de manera efectiva una gran cantidad de objetos de granularidad fina)
. estado externo (extrínseco).
● Estado interno
El estado interno es la información que puede compartir el objeto, que se almacena dentro del objeto flyweight y no cambiará con el entorno.
● Estado externo
El estado externo es una marca de la que el objeto puede depender, es un estado que cambia con el entorno y no se puede compartir.
● Flyweight——Rol de Flyweight abstracto
Es simplemente una clase abstracta de un producto y, al mismo tiempo, define la interfaz o implementación del estado externo y el estado interno del objeto.
● ConcreteFlyweight: rol de peso ligero concreto
Una clase de producto específica que implementa el negocio definido por roles abstractos. Lo que debe tenerse en cuenta en este rol es que el procesamiento del estado interno no debe tener nada que ver con el entorno. Una operación no debe cambiar el estado interno mientras modifica el estado externo. Esto está absolutamente prohibido.
● unsharedConcreteFlyweight: rol de peso ligero no compartido
Un objeto que no tiene un estado externo o requisitos de seguridad (como la seguridad de subprocesos) que no puede usar la tecnología compartida generalmente no aparece en la fábrica de peso ligero.
● FlyweightFactory——fábrica de peso mosca
La responsabilidad es muy simple, es decir, construir un contenedor de piscina y proporcionar métodos para obtener objetos de la piscina.
El código de la fábrica de peso mosca:
public class FlyweightFactory {
//Definir un contenedor de grupo
private static HashMap pool= new
HashMap();
//Fábrica de Flyweight
public static Flyweight getFlyweight(String Extrinsic){ //El objeto que debe devolverse Flyweight flyweight = null; //No existe tal objeto en el grupo if (pool.containsKey(Extrinsic)){ flyweight = pool.get(Extrinsic); }else{ //Crea un objeto flyweight según el estado externo flyweight = new ConcreteFlyweight1(Extrinsic); //ponlo en el pool pool.put(Extrinsic, flyweight); } return flyweight; } } Escenarios de uso: ● Hay una gran cantidad de objetos similares en el sistema. ● Los objetos de grano fino tienen estados externos relativamente cercanos y los estados internos no tienen nada que ver con el entorno, es decir, los objetos no tienen una identidad específica. ● Escenarios que requieren un grupo de búfer. Nota: ● El modo Flyweight no es seguro para subprocesos, solo confíe en la experiencia, considere la seguridad de subprocesos cuando sea necesario y no es necesario considerarlo en la mayoría de los escenarios. Hay tantos objetos de peso mosca en el grupo de objetos como sea posible, hasta que se satisfagan suficientes.



















● Seguridad de rendimiento: es mejor marcar el estado externo con tipos básicos de java, como String e int, que pueden mejorar la eficiencia.

23. Definición de patrón de puente
: desvincular una abstracción de su implementación para que los dos puedan variar
.
de forma independiente ● Implementador——rol de implementación Es una interfaz o una clase abstracta que define los comportamientos y atributos necesarios de un rol. ● RefinedAbstraction——Función de abstracción refinada Se refiere a la función de realización para revisar la función de abstracción. ● ConcreteImplementor——Rol de implementación concreta Implementa los métodos y propiedades definidos por la interfaz o clase abstracta. Escenarios de uso: ● Escenarios donde la herencia no se espera o no se aplica ● Escenarios donde las interfaces o las clases abstractas son inestables ● Escenarios que requieren alta reutilización Nota: Cuando encuentre que hay N capas de herencia de clases, puede considerar usar el modo puente . El patrón de puente considera principalmente cómo dividir la abstracción y la implementación. Principios de diseño: Principio de responsabilidad única: Principio de responsabilidad única Cuáles son los beneficios del Principio de responsabilidad única:
















● Se reduce la complejidad de la clase y se definen claramente las responsabilidades;
● Se mejora la legibilidad y se reduce la complejidad, por lo que, por supuesto, se mejora la legibilidad;
● Se mejora la facilidad de mantenimiento y, por supuesto, se mejora la legibilidad es más fácil de mantener;
● El riesgo causado por el cambio se reduce, y el cambio es esencial. Si la única responsabilidad de la interfaz se hace bien, una modificación de la interfaz solo afectará a la clase de implementación correspondiente y no tendrá ningún efecto en otras interfaces. , lo que afectará la expansión del sistema. La sexualidad y la mantenibilidad son muy útiles.
pd: La interfaz debe tener una sola responsabilidad, y el diseño de la clase debe estar diseñado para que solo haya una razón para el cambio.
El principio de responsabilidad única propone un estándar para escribir programas, utilizando "responsabilidad" o "motivo del cambio" para medir si la interfaz o clase está bien diseñada, pero la "responsabilidad" y el "motivo del cambio" no son medibles y varían de un proyecto a otro. proyecto Varía según el entorno.
● Principio de sustitución de Liskov: Principio de sustitución de Liskov
Definición: Las funciones que usan punteros o referencias a clases base deben poder
usar objetos de clases derivadas sin saberlo
(todas las referencias a clases base deben poder usar objetos de sus subclases de forma transparente).
En términos simples, siempre que la clase principal pueda aparecer, la subclase puede aparecer, y reemplazarla con una subclase no causará ningún error ni excepción. Es posible que los usuarios no necesiten saber si es una clase principal o una subclase. Sin embargo, lo contrario no es posible, donde hay subclases, la clase principal puede no ser capaz de adaptarse.
Los cuatro significados contenidos en la definición:
1. La subclase debe implementar completamente el método de la clase principal
2. La subclase puede tener su propia personalidad
3. Los parámetros de entrada se pueden ampliar al anular o implementar el método de la clase principal
Si el tipo de parámetro de entrada de la clase principal es mayor que el tipo de parámetro de entrada de la subclase, habrá lugares donde exista la clase principal, pero es posible que la subclase no exista, porque una vez que la subclase se pasa como parámetro, la persona que llama es probable que entre en la categoría de método de la subclase.

  1. Al anular o implementar el método de la clase principal, el resultado de salida se puede reducir.El
    valor de retorno de un método de la clase principal es un tipo T, y el valor de retorno del mismo método (sobrecargado o anulado) de la subclase es S, entonces el principio de sustitución de Liskov Se requiere que S sea menor o igual que T, es decir, S y T
    son del mismo tipo, o S es una subclase de T.
    ● Principio de segregación de interfaces: Principio de segregación de interfaces
    Hay dos tipos de interfaces:
    Interfaz de objeto: una clase en Java también es una interfaz Interfaz
    de clase: el
    aislamiento de interfaz definido por la palabra clave Interface se usa a menudo en Java: para establecer una única interfaz, t crear una interfaz inflada y enorme; es decir, la interfaz debe ser lo más detallada posible y los métodos en la interfaz deben ser la menor cantidad posible.
    La diferencia entre el principio de aislamiento de interfaz y el principio de responsabilidad única: el principio de aislamiento de interfaz es diferente desde la perspectiva de responsabilidad única.La responsabilidad única requiere una clase única y responsabilidad de interfaz, centrándose en la responsabilidad, que es
    la división principio de segregación de interfaces requiere que los métodos de la interfaz sean los menos posibles.
    ● Principio de inversión de dependencia: Principio de inversión de dependencia
    Definición original:
    ① Los módulos de alto nivel no deben depender de los módulos de bajo nivel, ambos deben depender de sus abstracciones;
    ② Las abstracciones no deben depender de los detalles (clases de implementación);
    ③ Los detalles deben depender de las abstracciones .
    La encarnación del principio de inversión de dependencia en el lenguaje Java:
    ①Las dependencias entre módulos ocurren a través de la abstracción, y no hay dependencia directa entre las clases de implementación, y las dependencias se
    generan a través de interfaces o clases abstractas;
    ②Las interfaces o clases abstractas no dependen de Clase de implementación;
    ③ La clase de implementación depende de la interfaz o clase abstracta.
    Tres formas de escribir dependencias:
    ①El constructor transfiere objetos dependientes (inyección de constructor)
    ②El método Setter transfiere objetos dependientes (inyección de dependencia setter)
    ③La interfaz declara objetos dependientes (inyección de interfaz)
    Principio de uso:
    La esencia del principio de inversión de dependencia es usar abstracción (interfaz o Clase abstracta) hace que la implementación de cada clase o módulo sea independiente entre sí, no se afecta entre sí y realiza un acoplamiento flexible entre módulos. ¿Cómo usamos esta regla en el proyecto? Simplemente
    siga las siguientes reglas:
    ① Cada clase debe tener una interfaz o una clase abstracta tanto como sea posible, o tanto una clase abstracta como una interfaz ② El tipo de superficie de una variable debe
    ser una interfaz o una clase abstracta ④Trate de no sobrescribir el método de la clase base ⑤Úselo junto con el principio de sustitución de Liskov Principio abierto cerrado: definición del principio abierto cerrado : las entidades de software deben estar abierto al cierre de extensiones. Su implicación es que una entidad de software debe implementar cambios a través de extensiones, en lugar de modificar los códigos existentes. Entidades de software: módulos, abstracciones, clases y métodos que se dividen según ciertas reglas lógicas en un proyecto o producto de software. Tres tipos de cambios: ①Cambio de lógica Solo se cambia una lógica sin involucrar a otros módulos. Por ejemplo, el algoritmo original es b+c, y ahora debe cambiarse a b*c. Puede modificar el método en el original clase La premisa es que todas las clases dependientes o asociadas se procesan de acuerdo con la misma lógica. ② Cambios de submódulos












    Un cambio de módulo afectará a otros módulos, especialmente un cambio de módulo de bajo nivel inevitablemente causará un cambio de módulo de alto nivel, por lo que cuando el cambio se completa a través de la expansión, la modificación de módulo de alto nivel es inevitable.
    ③ Cambios en la vista visible Las vistas
    visibles son interfaces proporcionadas a los clientes, como programas JSP, interfaces Swing, etc. Los cambios en esta parte generalmente causan reacciones en cadena (especialmente en proyectos nacionales y, en general, no afectan
    demasiado ). Los cambios se pueden hacer a través de la expansión, dependiendo de si nuestro diseño original es flexible.

Supongo que te gusta

Origin blog.csdn.net/dreamer23/article/details/109356679
Recomendado
Clasificación