1. Antecedentes
En los sitios web actuales, cada vez existen más canales de acceso y la tecnología es cada vez más avanzada, como WAP, SMS, EMAIL, Web tradicional, Socket, etc. Si incluso se incluyen bases de datos y LDAP, el acceso Si por lo tanto, el espacio que se debe ampliar en el diseño debe ser muy bueno para garantizar que al agregar nuevos canales, no se requieran más modificaciones de código o incluso cambios de código. Pero, ¿es posible? No creo que sea posible, pero ¿hay alguna forma de resolver mejor la perfección de este marco de acceso multicanal
2. Arquitectura
?[Figura 1]
Como se muestra en la Figura 1, cuando se han utilizado todos los accesos existentes, los diseñadores quedan deslumbrados. Si se trata de reunir personas, entonces estos programas se pueden escribir de cualquier manera y definitivamente funcionarán. , pero será más doloroso de mantener. Volvamos a la pregunta, ¿cómo podemos lograr una implementación más perfecta como se muestra en la Figura 2?
[Figura 2]
La Figura 2 parece un pulpo con ocho garras. Las patas del pulpo están conectadas a todos los canales de acceso respectivamente. El núcleo para conectar todos estos canales es el XMLRouter, la cabeza del pulpo. comunicarse con todos los canales y darse cuenta Los beneficios del enrutamiento de datos y la mejora de la escalabilidad y flexibilidad de la arquitectura del sistema serán muchos. Se llama XMLRouter porque si XML, un lenguaje flexible y estandarizado, no se utiliza como medio de transmisión de datos, la carga de trabajo del enrutador también aumentará exponencialmente. La definición de la especificación XML traerá muchos beneficios.
3. Ideas y patrones
La idea original de XMLRouter surgió de la placa base de la computadora y <
>En Builder Pattern, la ranura PCI de la placa base de la computadora define la especificación PCI. Siempre que la tarjeta que produzca cumpla con el estándar PCI, puede funcionar cuando la inserte en la placa base. El patrón Builder propone separar la construcción compleja e implementarla paso a paso. XMLRouter separa estos canales complejos y los realiza uno por uno.
Idea de servicios: para comunicarse con el enrutador, se debe definir una interfaz unificada al acceder. El canal, aquí se llama Servicios. Siempre que el programa cumpla con las especificaciones de Servicios, puede acceder al enrutador y los datos de ruta
en modo de fábrica y
XMLRouter en modo compuesto se generará utilizando el modo de fábrica en el diseño real. RouterFactory, se colocará en la cola cuando se ponga en uso. Los datos de transmisión, los datos de recepción y los datos de retorno se llaman desde el enrutador correspondiente desde la cola y se aplica el modo compuesto.
4. Archivo de configuración XML
. para Router El uso se divide en dos partes. La primera es la configuración del Router, como por ejemplo:
Aquí hay una cita: <?xml versión="1.0" ?> <servicios> <!-- Servicio de base de datos --> <nombre del servicio="base de datos" tipo="base de datos" clase="com.web.service.DBService"> <conector controlador="com.microsoft.jdbc.sqlserver.SQLServerDriver" url="jdbc:microsoft:sqlserver://192.168.0.179:1433" usuario="prueba" contraseña="prueba" /> </servicio> <!-- Servicio web--> <nombre del servicio="web" tipo="web" class="com.web.service.WebService" > <conector/> </servicio> … </services> |
Este es el archivo de configuración del enrutador. El nodo de servicio representa el canal al que se debe acceder. El nodo de servicio contiene el subnodo del conector. La configuración del subnodo se distingue por tipo. una base de datos, contiene atributos como URL, usuario, contraseña, controlador, etc. Si es un socket, contiene atributos como puerto y maxthread. Los valores de los atributos se pueden configurar de acuerdo con su propia definición.
Otrotipo
de archivo XML es el archivo de datos de transacciones XML, que se utiliza para transferir datos en todos los servicios. Cada Servicio contiene su propio archivo XML correspondiente, como webtrans.xml, que tiene el siguiente formato:
Aquí hay una cita: <?xml versión="1.0" ?> <transacción> <trans nombre="addDoc" servicio="base de datos" método="insertar"> <nombre de propiedad="createtime" tipo="marca de tiempo"/> <nombre de propiedad="idcreador" tipo="largo"/> <nombre de propiedad="doctypeid" tipo="int"/> <nombre de propiedad="docstatusid" tipo="int"/> </trans> </transaction> |
El formato dbtrans.xml correspondiente es el siguiente
Aquí hay una cita: <trans nombre="addDoc" tabla="TDOC_DOCS" método="insertar"> <nombre de clave primaria="docid" /> <conjunto> <nombre de propiedad="createtime" tipo="marca de tiempo"/> <nombre de propiedad="idcreador" tipo="largo"/> <nombre de propiedad="doctypeid" tipo="int"/> <nombre de propiedad="docstatusid" tipo="int"/> </conjunto> </trans> |
El resto del XML se puede personalizar según dichas reglas
. 5. Implementación técnica
de RouterFactory.
Aquí hay una cita: paquete com.web.router; importar com.web.platform.Exception.RouterException; import java.util.java/util/Hashtable.java.html" target="_blank">Hashtable; |
El siguiente es un fragmento de referencia: /** * Clases generadas y borradas por el enrutador. */ RouterFactory de clase pública { /** * Frente del árbol almacenado por el enrutador */ privado estático java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null; /** * Árbol almacenado nuevamente por el enrutador */ privado estático java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null; /** * Árbol almacenado por enrutador */ privado estático java/util/Hashtable.java.html" target="_blank">Hashtable QueueRouter = null; /** * Enrutador XML devuelto */ instancia pública de XMLRouter estática = nula; /** *Definición de enrutador */ RouterDefine estático público routerdefine = nulo; /** * Número de identificación del enrutador */ routeIndex largo estático público = 0; /** * @roseuid 3F169C21027C */ fábrica de enrutadores pública() { } /** * Inicializar Hashtable y Vector */ public static void initFactory() lanza java/lang/Exception.java.html" target="_blank">Exception { QueuePairFront = new java/util/Hashtable.java.html" target="_blank">Hashtable(); QueuePairBack = new java/util/Hashtable.java.html" target="_blank">Hashtable(); QueueRouter = new java/util/Hashtable.java.html" target="_blank">Hashtable(); initRouteDefine(); } /** * Inicializar configuración de ruta * */ initRouteDefine() vacío estático privado lanza java/lang/Exception.java.html" target="_blank">Exception { si (definición del enrutador == nulo) enrutadordefine = nuevo enrutadorDefine(); enrutadordefine.loadRouterDef(); } /** * Instancia de devolución * @return com.web.router.XMLRouter */ XMLRouter estático público getInstance (índice largo) lanza RouterException { return (XMLRouter)QueueRouter.get(new java/lang/Long.java.html" target="_blank">Long(index)); } /** * Generar una instancia de XMLRouter * @return com.web.router.XMLRouter * @roseuid 3F1618A103BC */ XMLRouter estático público popInstance() lanza RouterException { índice de ruta++; instancia = nuevo XMLRouter(routeIndex); setDefine(instancia); QueueRouter.put(new java/lang/Long.java.html" target="_blank">Long(routeIndex), instancia); instancia de devolución; } /** * Borrar tabla hash, vector, etc. * @roseuid 3F1618B203C1 */ freeResource vacío estático privado() lanza java/lang/Exception.java.html" target="_blank">Exception { QueuePairFront.clear(); QueuePairBack.clear(); QueueRouter.clear(); QueuePairFront = QueuePairBack = QueueRouter = nulo; } /** * Borrar instancia * @param ID de instancia * @throwsException */ removeInstance public static void (instancia XMLRouter) lanza java/lang/Exception.java.html" target="_blank">Exception { instancia.clear(); QueueRouter.remove( new java/lang/Long.java.html" target="_blank">Long(instance.getIndex() ) ); } /** * El método es nulo. * @return booleano */ público estático booleano isNull() { … devolver falso; } } |
Aquí hay una cita: paquete com.web.router; importar com.web.platform.Exception.RouterException; importar com.web.common.*; importar java.util.*; importar java.lang.reflect.java/lang/reflect/Method.java.html" target="_blank">Método; importar java.lang.reflect.java/lang/reflect/Constructor.java.html" target="_blank">Constructor; /** * @autor keli * @versión 0.0.1 * La clave de la plataforma, la clase de enrutamiento, cada enrutador la leerá de RouterFactory * El árbol frontal, posterior y routeIndex almacenado por el enrutador tiene el propósito de enrutar * Los objetos aplicados se pueden borrar más tarde. * El enrutador puede implementar funciones sincrónicas y asincrónicas. */ enrutador XML de clase pública { /** * Frente del árbol almacenado por el enrutador */ privado estático java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null; /** * Árbol almacenado nuevamente por el enrutador */ privado estático java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null; /** * El número de índice de este enrutador */ índice de ruta largo privado = 0; /** * Configuración del enrutador */ RouterDefine privado define = nulo; /** *Se utiliza para determinar el punto de inicio de la ruta*/ privado java/lang/String.java.html" target="_blank">String action = ""; /** *Esta variable solo se usa para solicitar una nueva clase en el método routeto */ java privado/lang/String.java.html" target="_blank">String classname = ""; /** */ XMLRouter público (índice largo) { índice de ruta = índice; } /** * Enrutamiento * @throws Excepción * @roseuid 3F1616BD0186 */ el enrutamiento público vacío (Env env) lanza RouterException, java/lang/Exception.java.html" target="_blank">Exception { /*Si es el punto de partida*/ si (action.equalsIgnoreCase (RouterConstant.CFG_FUNC_ROUTETO)) { … } /*Si es un punto de retorno*/ de lo contrario si (action.equalsIgnoreCase (RouterConstant.CFG_FUNC_ROUTEBACK)) { … } /*De lo contrario es un error*/ demás throw new RouterException("Establecer error de acción del enrutador."); } /** * Leer el número de identificación de este enrutador. * @retorno largo */ getIndex público largo() { índice de ruta de retorno; } /** * Limpiar todos los objetos. * @throws RouterException */ public void clear() lanza RouterException { QueuePairFront.remove(new java/lang/Long.java.html" target="_blank">Long(routeIndex)); QueuePairBack.remove(new java/lang/Long.java.html" target="_blank">Long(routeIndex)); /*Reciclaje del sistema*/ java/lang/System.java.html" target="_blank">System.runFinalization(); } /** * Establecer la configuración de este enrutador. * @param def * @throws RouterException */ public void setDefine (RouterDefine def) lanza RouterException { definir = definir; } /** * Establecer el valor de la acción * @param actionName * @throws RouterException */ setAction public void( java/lang/String.java.html" target="_blank">String actionName ) { acción = nombre de acción; } } |
Clase de servicio
Aquí hay una cita: paquete com.web.common; importar com.web.platform.Exception.RouterException; /** * La clase padre de Servicio, resumen */ clase abstracta pública RouteService { /** */ servicio de ruta pública() { } /** * El método routeTo es el punto de partida de la transacción. * @param entorno * @throws RouterException */ ruta vacía abstracta pública a (Env env) lanza RouterException; /** *routeBack, el punto final de la transacción, * @param entorno * @throws RouterException */ ruta de retorno vacía abstracta pública (Env env) lanza RouterException; /** * El método routeaccept es el punto de recepción de la transacción y la función de recepción de routeto. * routeaccept es la función de procesamiento principal de los objetos de transacción pasiva * @param env * @throws RouterException */ ruta vacía abstracta pública aceptar (Env env) lanza RouterException; /** * El método de enrutamiento es la función de interfaz externa del Servicio * @throws RouterException */ public abstract void route() lanza RouterException |
A continuación, debe implementar todas las clases de Servicios, que no se presentarán aquí.
6. Explique que
este enrutador solo puede implementar transacciones sincrónicas hasta ahora y no admite transacciones asincrónicas por el momento
.Sin embargo, dado que el enrutador está diseñado utilizando el modelo compuesto, la implementación de transacciones asincrónicas también se puede ampliar, por lo que no se realizará un análisis detallado aquí.