Algunas preguntas sobre el patrón de diseño JAVA
prototipo (prototipo)
En JavaScript, el objeto prototipo es un mecanismo importante para realizar la orientación a objetos.
Cada función es un objeto (Función). El objeto de función tiene un objeto prototipo de subobjeto y la clase se define en forma de función. Prototipo representa el prototipo de la función y también representa una colección de miembros de una clase.
Al crear un objeto de instancia de una clase mediante new, los miembros del objeto prototipo se convierten en miembros del objeto instanciado.
1. La clase hace referencia al objeto y solo se puede hacer referencia a objetos de función.
2. Después de crear una instancia de new, se crean instancias de sus miembros y el objeto de instancia puede ser; llamado.
Al mismo tiempo, una función es un objeto. Si el objeto de función declara miembros directamente, se puede llamar sin necesidad de crear una instancia
Abstract Factory Abstract Factory
¿Por qué usarlo?
El modo de fábrica es nuestro modo más utilizado. El famoso foro Jive utiliza ampliamente el modo de fábrica. se utiliza en programas Java. Se puede decir que el sistema se encuentra en todas partes.
¿Por qué se usa tan comúnmente el patrón de fábrica? Debido a que el patrón de fábrica es equivalente a nuevo para crear objetos de instancia, a menudo necesitamos generar objetos de instancia basados en la clase Clase, como A a = new A (). El patrón de fábrica también se usa para crear objetos de instancia, por lo que en el. En el futuro, debemos tener cuidado al hacer cosas nuevas. ¿Puede considerar el modelo práctico de fábrica? Aunque hacerlo puede requerir más trabajo, brindará mayor escalabilidad a su sistema y requerirá la menor cantidad de modificaciones posible.
Tomemos la clase Sample como ejemplo. Si queremos crear un objeto de instancia de Sample:
Sample sample=new Sample()
Sin embargo, la situación real es que, por lo general, tenemos que realizar algún trabajo de inicialización al crear una instancia de muestra, como asignar valores para consultar la base de datos, etc.
En primer lugar, lo que pensamos es que podemos usar el constructor de Sample, de modo que la instancia generada se escriba como:
Sample sample=new Sample(parameter);
Sin embargo, si el trabajo de inicialización realizado al crear la instancia de muestra no es tan simple como una asignación, puede ser un fragmento de código largo. Si también está escrito en el constructor, su código será feo (. será necesaria una refactorización).
¿Por qué el código es feo? Es posible que los principiantes no se sientan así. Nuestro análisis es el siguiente. Si el trabajo de inicialización es un código largo, significa que hay mucho trabajo por hacer. Poner mucho trabajo en un método es equivalente a poner muchos huevos en una canasta, lo cual es muy peligroso. Esto también es contrario a los principios orientados a objetos de Java (encapsulación) y envío (delegación). "cortar" asignaciones de código largas tanto como sea posible " en cada párrafo y luego "encapsular" cada párrafo (para reducir el acoplamiento entre párrafos). De esta manera, el riesgo se dispersará. Si necesita modificarlo en En el futuro, solo necesitarás cambiar cada párrafo y no habrá más cambios.
En este ejemplo, en primer lugar, debemos separar el trabajo de crear una instancia del trabajo de usar una instancia, es decir, separar la gran cantidad de trabajo de inicialización requerido para crear una instancia del Constructor de muestra.
En este momento necesitamos el patrón Factory para generar objetos y ya no podemos usar el nuevo y simple Ejemplo (parámetro) anterior.
Además, si Sample tiene una herencia como MySample, de acuerdo con la programación orientada a interfaz, necesitamos abstraer Sample en una interfaz. Ahora Sample es una interfaz y tiene dos subclases, MySample y HisSample, cuando queremos crear una instancia de ellas. de la siguiente manera:
Sample mysample=new MySample();
Sample hissample=new HisSample()
A medida que avanza el proyecto, Sample puede "dar a luz" to many sons", entonces tenemos que crear instancias de estos hijos uno por uno. Lo que es peor, es posible que tengamos que modificar el código anterior: agregar instancias de hijos que nacerán más tarde. Esto es inevitable en los programas tradicionales.
Pero si utiliza conscientemente el patrón de fábrica desde el principio, estos problemas desaparecerán
Método de fábrica
Establecerá una fábrica dedicada a producir instancias de muestra:
public class Factory{
public static Creador de muestras (int cual){
//getClass genera muestra Generalmente, la carga dinámica de clases se puede utilizar para cargar la clase.
if (cuál==1)
devuelve nueva muestraA();
else if (cuál==2)
devuelve new SampleB();
}
}
Luego, en su programa, si desea crear una instancia de Sample, use
Sample sampleA. =Factory.creator(1);
De esta manera, la subclase específica de Sample no participa en todo el proceso, lo que logra el efecto de encapsulación y reduce la posibilidad de modificaciones incorrectas. muy popularmente para usar una analogía: cuanto más específicas se hacen, más fácil es cometer errores. Todo el que ha realizado un trabajo específico lo sabe bien. Por el contrario, cuanto más alto es el nivel oficial, más abstractas y generales son las palabras. Dijo, y cuanto más probable es cometer errores, menos sexo Parece que también podemos entender los principios de la vida a partir de la programación.
¿Hay varios roles a los que prestar atención al usar? Método de fábrica. Primero, debe definir la interfaz del producto, como el Ejemplo anterior, producto. Debajo de la interfaz, hay una clase de implementación de la interfaz de Ejemplo, como MuestraA. En segundo lugar, hay una clase de fábrica para generar el producto Muestra. como se muestra a continuación. El extremo derecho es el objeto de producción Muestra:
Es un poco más complicado, es decir, expande la clase de fábrica, y la clase de fábrica también hereda su clase de implementación concreteFactory.
Fábrica Abstracta
El patrón de fábrica incluye: Método Factory y Fábrica Abstracta
La diferencia entre estos dos patrones es que necesitan crear objetos de nivel de complejidad. .
Si nuestro método de creación de objetos se vuelve complicado, por ejemplo, en el método de fábrica anterior, se crea un objeto Muestra, y si también tenemos una nueva interfaz de producto Muestra2
Aquí está la suposición: Muestra tiene dos. clases concretas SampleA y SampleB, y Sample2 también tiene dos clases concretas Sample2A y SampleB2
Luego, convertiremos Factory en el ejemplo anterior en una clase abstracta, encapsularemos las mismas partes en la clase abstracta y usaremos subclases para diferentes partes Para implementar, lo siguiente es extender Factory en el ejemplo anterior a una fábrica abstracta:
public abstract class Factory{
public abstract Sample Creator(); /p>
creador de muestra2 abstracto público (nombre de cadena);
}
clase pública SimpleFactory extiende Factory{
creador de muestra pública(){
.. .......
devolver nuevo SampleA
}
creador público de Sample2 (nombre de cadena){ p>
... ......
devolver nuevo Sample2A
}
}
clase pública BombFactory extiende Factory{
public Sample creador(){
...
devuelve nuevo SampleB
}
creador público de Sample2 (nombre de cadena){
...
devolver nuevo Sample2B
}
}
De lo anterior, podemos ver que cada una de las dos fábricas produce un conjunto de Muestra y Muestra2. Tal vez se pregunte, ¿por qué no puedo usar dos métodos de fábrica para producir Muestra y Muestra2 respectivamente? Hay otra fábrica abstracta. El punto clave es que existe una cierta conexión entre los métodos para producir Sample y Sample2 en SimpleFactory, por lo que estos dos métodos deben agruparse en una clase. Esta clase de fábrica tiene sus propias características. el proceso de fabricación está unificado. Por ejemplo: el proceso de fabricación es relativamente simple, por eso el nombre es SimpleFactory.
En aplicaciones reales, los métodos de fábrica se utilizan con más frecuencia y se combinan con cargadores de clases dinámicos.
Por ejemplo
Tomemos ForumFactory de Jive como un. Ejemplo Hemos discutido este ejemplo en el modo Singleton anterior. Ahora discutiremos su modo de fábrica:
public abstract class ForumFactory {
private static Object initLock = new Object();
cadena estática privada className = "com.jivesoftware.forum.database.DbForumFactory";
fábrica de ForumFactory estática privada = null
getInstance de ForumFactory estática pública ( Autorización autorización) {
// Si no se pasó ninguna autorización válida, devuelve nulo
if (autorización == nulo) {
devuelve nulo ; p>
}
// Lo siguiente usa el modo monomórfico Singleton
if (factory == null) {
sincronizado( initLock) { p>
if (factory == null) {
......
try {
//Clase de reimpresión dinámica
Clase c = Class.forName(className);
factory = (ForumFactory)c.newInstance()
}
catch (Exception); e) {
devolver nulo
}
}
}
}
//Ahora, devuelve el proxy. Se utiliza para restringir el acceso autorizado al foro
return new ForumFactoryProxy(autorización, fábrica,
factory.getPermissions(autorización)
}
// El método real de creación de un foro se completa con subclases que heredan forumfactory
public abstract Forum createForum(nombre de cadena, descripción de cadena)
lanza UnauthorizedException, ForumAlreadyExistsException;
....
}
Porque el Jive actual almacena publicaciones del foro a través del sistema de base de datos. Cambie los datos de contenido que se implementarán a través del sistema de archivos. Este método de fábrica ForumFactory proporciona una interfaz dinámica:
cadena estática privada className = "com.jivesoftware.forum.da
tabase.DbForumFactory";
Puede utilizar el método que desarrolló para crear un foro en lugar de com.jivesoftware.forum.database.DbForumFactory.
En el código anterior, * ** Se utilizan tres modos Además del modo de fábrica, también existe el modo Singleton y el modo proxy. El modo proxy se utiliza principalmente para autorizar a los usuarios a acceder al foro, porque hay dos tipos de personas que acceden al foro: uno es un registrado. usuario y el otro es Invitado, entonces los permisos correspondientes son diferentes y este permiso se ejecuta en todo el sistema, por lo que establecer un proxy, similar al concepto de puerta de enlace, puede lograr este efecto muy bien. un vistazo a Java Pets CatalogDAOFactory en la tienda:
public class CatalogDAOFactory {
/**
* Este método desarrolla una subclase especial para implementar el patrón DAO
* La definición de subclase específica está en el descriptor de implementación J2EE
*/
public static CatalogDAO getDAO() throws CatalogDAOSysException {
CatalogDAO catDao = null
prueba {
InicialContext ic = nuevo InicialContext()
// Carga dinámica CATALOG_DAO_CLASS
/ /Puedes definir tu propio CATALOG_DAO_CLASS para completar grandes cambios en el sistema sin cambiar demasiado código
String className =(String) ic.lookup( JNDINames.CATALOG_DAO_CLASS ); p>
catDao = (CatalogDAO) Class.forName(className).newInstance();
} catch (NamingException ne) {
throw new CatalogDAOSysException("
CatalogDAOFactory.getDAO: NamingException mientras
obtiene el tipo de DAO: \n" + ne.getMessage());
} catch (Exception se) {
throw new CatalogDAOSysException("
CatalogDAOFactory.getDAO: Excepción al obtener
tipo DAO: \n" + se.getMessage()
); }
return catDao;
}
}
CatalogDAOFactory es un método de fábrica típico, catDao es La subclase de implementación específica de CatalogDAOFactory es obtenido a través del cargador de clases dinámico className. Esta subclase de implementación se utiliza para operar la base de datos del catálogo en Java Pet Store. Los usuarios pueden personalizar su propia subclase de implementación específica de acuerdo con el tipo de base de datos y agregar sus propias subclases. Variable CATALOG_DAO_CLASS.
Se puede ver que el método de fábrica proporciona un mecanismo de expansión dinámica muy flexible y poderoso para la estructura del sistema. Siempre que cambiemos el método de fábrica específico, es posible ampliar las funciones del sistema sin ningún tipo de cambio. cambios en otras partes del sistema.
Para saber cómo aplicar patrones de diseño en proyectos específicos, consulte la "Guía práctica de desarrollo de sistemas Java".
La función principal del modo Singleton es garantizar que en las aplicaciones Java, solo una instancia de existe una clase.
En muchas operaciones, como establecer conexiones de directorio y base de datos, se requieren operaciones de un solo subproceso.
Además, un singleton puede tener estado; de esta manera, se pueden usar múltiples clases singleton como un almacén estatal para brindar servicios al mundo exterior. Por ejemplo, si desea un contador de publicaciones en un foro, cada una. tiempo que navega Es necesario contar una vez. ¿Puede la clase monomórfica mantener este recuento y sincronizarlo de forma segura y aumentarlo automáticamente en 1? Si desea guardar permanentemente este número en la base de datos, puede hacerlo fácilmente sin modificar la interfaz monomórfica. .
Por otro lado, Singleton también puede convertirse en apátrida. Al proporcionar funciones similares a herramientas,
El modo Singleton nos brinda la posibilidad de dicha implementación. La ventaja de utilizar Singleton es que puede ahorrar memoria porque limita el número de instancias y favorece la recolección de basura de Java.
A menudo vemos que el cargador de clases en el modo fábrica también se implementa en el modo Singleton, porque las clases cargadas son en realidad recursos.