1. Descripción general
En general, los patrones de diseño se dividen en tres categorías:
(1) Modo creativo , un total de cinco tipos: modo de método de fábrica, modo de fábrica abstracta, modo singleton, modo de constructor y modo prototipo.
(2) Modos estructurales , un total de siete tipos: modo adaptador, modo decorador, modo proxy, modo de apariencia, modo de puente, modo combinado y modo de disfrute.
(3) Modo de comportamiento , un total de once: modo de política, modo de método de plantilla, modo de observador, sub-modo iterativo, modo de cadena de responsabilidad, modo de comando, modo de memo, modo de estado, modo de visitante, modo intermediario y modo de intérprete.
2. Seis principios de modelo de diseño
1. Abra el principio cercano
El principio de apertura y cierre es abrirse a extensiones y cerca de modificaciones. Cuando el programa necesita ampliarse, no puede modificar el código original para lograr un efecto de enchufe caliente.
2. Principio de sustitución de Liskov
Su descripción oficial es relativamente abstracta y puede usarse para Baidu. De hecho, se puede entender de la siguiente manera: (1) La capacidad de una subclase debe ser mayor o igual a la clase principal, es decir, los métodos que la clase principal puede usar y la subclase puede usar. (2) Lo mismo es cierto para el valor de retorno. Supongamos que un método de clase principal devuelve una lista y una subclase devuelve una lista de matrices, que por supuesto se puede hacer. Si el método de clase principal devuelve una lista de matrices y la clase infantil devuelve una lista, no tiene sentido. Aquí la capacidad de las subclases para devolver los valores es menor que la de las clases de los padres. (3) También hay casos en los que se lanzan excepciones. Cualquier método de subclase puede declarar una subclase que arroja el método de la clase principal para declarar una excepción.
No puede declarar que la excepción que la clase principal no ha declarado es lanzada.
3. Principio de inversión de dependencia
Esta es la base del principio de apertura y cierre, y el contenido específico: programación orientada a la interfaz, dependiendo de la abstracción en lugar de concreto.
4. Principio de segregación de la interfaz
Este principio significa: usar múltiples interfaces aisladas es mejor que usar una sola interfaz. También significa reducir el grado de acoplamiento entre clases. Desde aquí podemos ver que el patrón de diseño es en realidad la idea de diseño de un software, que comienza desde una gran arquitectura de software, para la conveniencia de actualizar y mantenimiento. Por lo tanto, el artículo anterior ha aparecido muchas veces: reducir la dependencia y reducir el acoplamiento.
5. Principio de Demeter
¿Por qué es el principio del menor conocimiento? Es decir, una entidad debe interactuar con otras entidades lo menos posible, de modo que los módulos funcionales del sistema sean relativamente independientes.
6. Principio de reutilización compuesta
El principio es tratar de usar métodos de síntesis/agregación en lugar de herencia.
3. Modo de creación
Hay cinco tipos de modos de creación: modo de método de fábrica, modo de fábrica abstracta, modo singleton, modo de constructor y modo prototipo.
3.1. Modelo de método de fábrica
El modo de método de fábrica se divide en tres tipos: modo de fábrica ordinario, modo de método de fábrica múltiple y modo de método de fábrica estática.
3.1.1. Modelo de fábrica ordinaria
El modelo de fábrica ordinario es establecer una clase de fábrica y crear instancias de algunas clases que implementen la misma interfaz.
paquete com.mode.create; interfaz pública myInterface {public void print ();} paquete com.mode.create; Public Class MyClassone implementa MyInterface {@Override public void print () {System.out.println ("myClassone"); }} paquete com.mode.create; clase pública myclasstwo implementa myInterface {@Override public void print () {system.out.println ("myclasstwo"); }} paquete com.mode.create; public class myFactory {public myInterface Produce (String Type) {if ("One" .Equals (type)) {return new myClassone (); } else if ("dos" .equals (type)) {return new myClasStwo (); } else {System.out.println ("No se encuentra tipo"); regresar nulo; }}} paquete com.mode.create; Public Class FactoryTest {public static void main (string [] args) {myFactory factory = new myFactory (); MyInterface myi = factory.produce ("one"); myi.print (); }}Creo que los resultados de FactoryTest deberían ser obvios.
Entendamos esta oración nuevamente: el modelo de fábrica ordinario es establecer una clase de fábrica y crear instancias de algunas clases que implementen la misma interfaz.
3.1.2. Modos de método de fábrica múltiple
Los modos de método de fábrica múltiple son una mejora en el modo de método de fábrica ordinario. Los modos de métodos de fábrica múltiples deben proporcionar múltiples métodos de fábrica para crear objetos por separado.
Veamos el código directamente. Modificamos MyFactory y FactoryTest de la siguiente manera:
paquete com.mode.create; clase pública myFactory {public myInterface producace produce () {return new myClassone (); } public myInterface ProductETWo () {return new myClasStwo (); }} paquete com.mode.create; Public Class FactoryTest {public static void main (string [] args) {myFactory factory = new myFactory (); MyInterface myi = factory.produceone (); myi.print (); }}Los resultados de la operación también son muy obvios.
Entendamos esta oración nuevamente: los modos de método de fábrica múltiple son una mejora en el modo de método de fábrica ordinario. Los modos de métodos de fábrica múltiples deben proporcionar múltiples métodos de fábrica para crear objetos por separado.
3.1.3. Modo de método de fábrica estática
Modo de método de fábrica estática, establecer los métodos en los modos de método de fábrica múltiple anterior a Static, y no hay necesidad de crear una instancia, simplemente llamándolo directamente.
Veamos el código directamente. Modificamos MyFactory y FactoryTest de la siguiente manera:
paquete com.mode.create; clase pública myFactory {public static myInterface producace produce () {return new myClassone (); } public static myInterface ProductETWo () {return new myClasStwo (); }} paquete com.mode.create; Public Class FactoryTest {public static void main (string [] args) {myInterface myi = myFactory.produceOne (); myi.print (); }}Los resultados de la operación siguen siendo muy obvios.
Revise nuevamente: Modo de método de fábrica estática, establezca los métodos en los modos de método de fábrica múltiple anterior a Static, y no es necesario crear una instancia, simplemente llamándolo directamente.
3.2. Patrón de fábrica abstracta
Existe un problema con el modelo de método de fábrica de que la creación de clases depende de las clases de fábrica, es decir, si desea expandir el programa, debe modificar la clase de fábrica, que viola el principio de cierre.
Para resolver este problema, echemos un vistazo al patrón de fábrica abstracto: cree múltiples clases de fábrica, para que una vez que se necesiten nuevas funciones, puede agregar directamente nuevas clases de fábrica, sin modificar el código anterior.
Esto cumple con el principio de cierre.
Echemos un vistazo al código a continuación:
MyInterface, MyClassone, MyClasstwo permanece sin cambios.
Se agregan las siguientes interfaces y clases:
paquete com.mode.create; Proveedor de interfaz pública {public myInterface Produce (); } paquete com.mode.create; Public Class myFactoryOne implementa el proveedor {@Override public myInterface Produce () {return new myClassone (); }} paquete com.mode.create; public class myFactoryTwo implementa el proveedor {@Override public myInterface product () {return new myClasStwo (); }}Modifique la clase de prueba FactoryTest de la siguiente manera:
paquete com.mode.create; Public Class FactoryTest {public static void main (string [] args) {proveedor de proveedor = new myFactoryOnE (); MyInterface myi = proveedor.produce (); myi.print (); }}Los resultados de la operación siguen siendo obvios.
Revise nuevamente: El patrón de fábrica abstracto es crear múltiples clases de fábrica, de modo que una vez que se necesiten nuevas funciones, pueda agregar directamente nuevas clases de fábrica, sin modificar el código anterior.
3.3. Modo singleton
Patrón de singleton, sin necesidad de demasiada explicación.
Solo mira el código:
prueba de paquete; clase pública myObject {private static myObject myObject; Private myObject () {} public static myObject getInStance () {if (myObject! = null) {} else {myObject = new myObject (); } return myObject; }}Sin embargo, esto causará problemas de múltiples subprocesos. Para una explicación detallada, puede ver el Capítulo 6 en el libro "Tecnología central de la programación de Java Multi-Threading".
3.4. Modo de constructor
Patrón del constructor: es separar la construcción de un objeto complejo de su representación, para que el mismo proceso de construcción pueda crear diferentes representaciones.
Se ve muy abstracto literalmente, pero de hecho también es muy abstracto! ! ! !
El modo Builder generalmente incluye los siguientes caracteres:
(1) Constructor: proporcione una interfaz abstracta para estandarizar la construcción de varios componentes del objeto del producto. Esta interfaz especifica qué partes de objetos complejos se crean y no implica la creación de componentes de objetos específicos.
(2) ConcreteBuilder: implementa la interfaz del constructor y define la creación de varias partes de objetos complejos para diferentes lógicas comerciales. Después de completar el proceso de construcción, se proporciona un ejemplo del producto.
(3) Director: llama a constructores específicos para crear varias partes de objetos complejos. El instructor no implica información específica del producto, pero solo es responsable de garantizar que todas las partes del objeto se creen intactas o en un determinado orden.
(4) Producto: el objeto complejo que se creará.
Es común construir villanos en el desarrollo del juego, y el requisito es: los villanos deben incluir cabeza, cuerpo y pies.
Echemos un vistazo al siguiente código:
Producto (objeto complejo que se creará).:
paquete com.mode.create; Persona de clase pública {cabezal de cadena privada; cuerpo de cuerda privada; pie de cuerda privada; public String gethead () {return Head; } public void sethead (cabezal de cadena) {this.head = head; } public String getBody () {Body de retorno; } public void setBody (string body) {this.body = body; } public String getFoot () {return Foot; } public void setfoot (string foot) {this.foot = foot; }} Builder (ofrece una interfaz abstracta para estandarizar la construcción de varios componentes de un objeto de producto. Esta interfaz especifica qué partes de un objeto complejo se crean para ser implementados, y no implica la creación de componentes de objeto específicos).
paquete com.mode.create; Interfaz pública Personbuilder {void buildhead (); void buildBody (); void buildfoot (); Persona buildperson ();} ConcreteBuilder (implementa la interfaz del constructor, que incorpora la creación de varias partes de objetos complejos para diferentes lógicos comerciales. Después de completar el proceso de construcción, proporcione un ejemplo del producto).
paquete com.mode.create; ManBuilder de clase pública implementa PersonBuilder {persona persona; public ManBuilder () {Person = New Person (); } public void buildBody () {Person.setBody ("construir el cuerpo del hombre"); } public void buildFoot () {Person.setfoot ("construir los pies del hombre"); } public void buildhead () {persona.sethead ("construir la cabeza del hombre"); } Public Person BuildPerson () {Return Person; }} Director (llame al constructor específico para crear varias partes de objetos complejos. El instructor no involucra información específica del producto. Solo es responsable de garantizar que las partes del objeto se creen intactas o en cierto orden).
paquete com.mode.create; Pertondirector de clase pública {Public Person ConstructPerson (PersonBuilder PB) {PB.Buildhead (); pb.buildbody (); Pb.BuildFoot (); return pb.BuildPerson (); }} Clase de prueba:
paquete com.mode.create; Prueba de clase pública {public static void main (string [] args) {persedirector pd = new PERSONDIRECTOR (); Persona persona = pd.constructperson (nuevo manicador ()); System.out.println (persona.getbody ()); System.out.println (persona.getfoot ()); System.out.println (persona.gethead ()); }}Resultados de ejecución:
Revisión: Patrón del constructor: es separar la construcción de un objeto complejo de su representación, para que el mismo proceso de construcción pueda crear diferentes representaciones.
3.5. Modo prototipo
La idea de este patrón es usar un objeto como prototipo, copiarlo y clonarlo, y producir un nuevo objeto similar al objeto original.
Hablando de copiar objetos, hablaré de ello en combinación con copia superficial y copia profunda de objetos. En primer lugar, debe comprender el concepto de copia profunda y superficial de los objetos:
Copia superficial: después de copiar un objeto, se recrearán las variables del tipo de datos básicos, mientras que el tipo de referencia apunta al objeto original.
Copia profunda: después de copiar un objeto, se recrean tanto el tipo de datos básicos como el tipo de referencia. En pocas palabras, la copia profunda se copia por completo, mientras que la copia superficial no es exhaustiva.
Escribe un ejemplo de profundidad de copia:
paquete com.mode.create; import java.io.bytearrayInputStream; import java.io.bytearRaRandoutputStream; import java.io.ioException; import java.io.objectInputStream; import java.io.objectOutputStream; import java.io.serializable; El prototipo de clase pública implementa clonable, serializable {privado estático final Long SerialVersionUid = 1L; base privada int; entero privado obj; /* Copia Shallow*/ public Object clone () lanza ClonenOtsupportedException {// Debido a que la interfaz clonable es una interfaz vacía, puede definir el nombre del método de la clase de implementación en will // como clonea o cloneB, porque el enfoque aquí es la oración super.clone () // super.clone () llama a objeto clone () método // en la clase de objeto, clone (método) (método natal (método) (método natal) (método natal (método natal) es una clase natal (método natal) (método natal). Prototipo proto = (prototipo) super.clone (); regreso proto; } /* Copia profunda* / Public Object DeepClone () lanza IOException, ClassNotFoundException { /* Escribe la transmisión binaria al objeto actual* / bytearRayOutputStream bos = new ByteArRaYoutPutStream (); ObjectOutputStream oos = new ObjectOutputStream (BOS); oos.writeObject (esto); /* Lea el nuevo objeto generado por la transmisión binaria*/ bytearrayInputStream bis = new ByteArrayInputStream (bos.tobytearray ()); ObjectInputStream OIS = new ObjectInputStream (BIS); return ois.readObject (); } public int getBase () {Base de retorno; } public void setBase (int base) {this.base = base; } public integer getObj () {return obj; } public void setobj (integer obj) {this.obj = obj; }} Clase de prueba:
paquete com.mode.create; import java.io.ioException; Prueba de clase pública {public static void main (String [] args) lanza ClonenotsupportedException, ClassNotFoundException, IOException {Prototype Prototype = new Prototype (); Prototype.setBase (1); Prototype.setObj (nuevo entero (2)); /* copia superficial*/ prototipo prototipo1 = (prototipo) prototype.clone (); /* Copia profunda*/ prototipo prototipo2 = (prototipo) prototype.deepclone (); System.out.println (prototype1.getObj () == Prototype1.getObj ()); System.out.println (prototype1.getObj () == prototype2.getobj ()); }}Resultados de ejecución:
Lo anterior se trata de este artículo, espero que sea útil para el aprendizaje de todos.