1. Antecedentes
Nos sites de hoje existem cada vez mais canais de acesso e a tecnologia está cada vez mais avançada, como WAP, SMS, EMAIL, Web tradicional, Socket, etc. portanto, o espaço que precisa ser ampliado no design deve ser muito bom para garantir que ao adicionar novos canais não sejam necessárias mais modificações de código ou mesmo alterações de código. Mas é possível? Não creio que seja possível, mas existe alguma forma de resolver melhor a perfeição deste quadro de acesso multicanal
2. Arquitetura
?[Figura 1]
Conforme mostrado na Figura 1, quando todos os acessos existentes foram utilizados, os designers ficam deslumbrados. Se for para reunir pessoas, então esses programas podem ser escritos de qualquer forma e com certeza funcionarão. , mas será mais doloroso manter. Voltemos à questão: como podemos conseguir uma implementação mais perfeita?
[Figura 2]
A Figura 2 se parece com um polvo com oito garras. As pernas do polvo estão conectadas a todos os canais de acesso, respectivamente. O núcleo da conexão de todos esses canais é o XMLRouter, a cabeça do polvo. comunique-se com todos os canais e perceba Os benefícios do roteamento de dados e da melhoria da escalabilidade e flexibilidade da arquitetura do sistema serão muitos. É chamado de XMLRouter porque se o XML, uma linguagem flexível e padronizada, não for usado como meio de transmissão de dados, a carga de trabalho do roteador também aumentará exponencialmente. A definição da especificação XML trará muitos benefícios.
3. Ideias e Padrões
A ideia original do XMLRouter veio da placa-mãe do computador e <
>No Builder Pattern, o slot PCI da placa-mãe do computador define a especificação PCI. Contanto que a placa que você produz atenda ao padrão PCI, ela pode funcionar quando você a insere na placa-mãe. O Builder Pattern propõe separar a construção complexa e implementá-la passo a passo. O XMLRouter separa esses canais complexos e os executa um por um
. o canal, aqui é chamado de Serviços. Contanto que o programa esteja em conformidade com a especificação de Serviços, ele pode acessar o Roteador e os dados de rota
produzidos pelo Roteador no
modo Composto
.RouterFactory, ele será colocado na fila quando for colocado em uso. Os dados de transmissão, recebimento de dados e dados de retorno são todos chamados do roteador correspondente da fila, e o modo Composto é
aplicado
. para Roteador O uso é dividido em duas partes. A primeira é a configuração do Roteador, como:
Aqui está uma citação: <?xml versão="1.0" ?> <serviços> <!-- serviço de banco de dados --> <service name="database" type="database" class="com.web.service.DBService"> <conector driver="com.microsoft.jdbc.sqlserver.SQLServerDriver" url="jdbc:microsoft:sqlserver://192.168.0.179:1433" usuário="teste" senha = "teste" /> </serviço> <!-- Serviço Web--> <nome do serviço="web" type="web" class="com.web.service.WebService" > <conector /> </serviço> … </services> |
Este é o arquivo de configuração do roteador. O nó de serviço representa o canal que precisa ser acessado. O nó de serviço contém o subnó do conector. A configuração do subnó é diferenciada por tipo. um banco de dados, contém atributos como url, usuário, passwd, driver e assim por diante, se for um soquete, contém atributos como porta e maxthread. Os valores dos atributos podem ser configurados de acordo com sua própria definição. .
Outro tipo de arquivo XML é o arquivo de dados de transação XML, que é usado para transferir dados em todos os serviços. Cada serviço contém o seu próprio. O arquivo XML correspondente, como webtrans.xml, tem o seguinte formato:
Aqui está uma citação: <?xml versão="1.0" ?> <transação> <trans name="addDoc" service="database" method="insert"> <property name="createtime" type="timestamp"/> <property name="creatorid" type="long"/> <nome da propriedade="doctypeid" type="int"/> <nome da propriedade="docstatusid" type="int"/> </trans> </transaction> |
O formato dbtrans.xml correspondente é o seguinte
Aqui está uma citação: <trans name="addDoc" tabela="TDOC_DOCS" método="inserir"> <nome da chave primária = "docid" /> <conjunto> <property name="createtime" type="timestamp"/> <property name="creatorid" type="long"/> <nome da propriedade="doctypeid" type="int"/> <nome da propriedade="docstatusid" type="int"/> </conjunto> </trans> |
O restante do XML pode ser personalizado de acordo com essas regras
. 5. Implementação técnica
do RouterFactory.
Aqui está uma citação: pacote com.web.router; importar com.web.platform.Exception.RouterException; import java.util.java/util/Hashtable.java.html" target="_blank">Hashtable; |
O seguinte é um fragmento de referência: /** * Classes geradas e limpas pelo roteador */ classe pública RouterFactory { /** * Frente de árvore armazenada pelo roteador */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null; /** * Árvore armazenada pelo roteador */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null; /** * Árvore armazenada pelo roteador */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueueRouter = null; /** *XMLRouter retornado */ instância XMLRouter estática pública = null; /** *Definição de Roteador */ public static RouterDefine routerdefine = null; /** * Número de identificação do roteador */ público estático longo routeIndex = 0; /** *@roseuid3F169C21027C */ fábrica de roteador público() { } /** * Inicialize Hashtable e Vector */ public static void initFactory() lança 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 configurações de rota * */ private static void initRouteDefine() lança java/lang/Exception.java.html" target="_blank">Exception { if(routerdefine == null) roteadordefine = new RouterDefine(); roteadordefine.loadRouterDef(); } /** * Instância de retorno * @return com.web.router.XMLRouter */ public static XMLRouter getInstance (índice longo) lança RouterException { return (XMLRouter)QueueRouter.get(new java/lang/Long.java.html" target="_blank">Long(index)); } /** * Gere uma instância de XMLRouter * @return com.web.router.XMLRouter *@roseuid3F1618A103BC */ public static XMLRouter popInstance() lança RouterException { rotaIndex++; instância = novo XMLRouter(routeIndex); setDefine(instância); QueueRouter.put(new java/lang/Long.java.html" target="_blank">Long(routeIndex), instância); instância de retorno; } /** * Limpar tabela hash, vetor, etc. * @roseuid 3F1618B203C1 */ private static void freeResource() lança java/lang/Exception.java.html" target="_blank">Exception { QueuePairFront.clear(); QueuePairBack.clear(); QueueRouter.clear(); QueuePairFront = QueuePairBack = QueueRouter = null; } /** * Limpar instância * @param instanceID * @throwsException */ public static void removeInstance (instância XMLRouter) lança java/lang/Exception.java.html" target="_blank">Exception { instância.claro(); QueueRouter.remove(new java/lang/Long.java.html" target="_blank">Long(instance.getIndex() ) ) ; } /** * O método éNull. * @return booleano */ público estático booleano isNull() { … retornar falso; } } |
Aqui está uma citação: pacote 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">Construtor; /** * @autor keli *@versão 0.0.1 * A chave da plataforma, a classe de roteamento, cada roteador irá ler no RouterFactory * A árvore frontal, traseira e routeIndex armazenada pelo Router é para fins de roteamento * Os objetos aplicados podem ser apagados posteriormente. * O roteador pode implementar funções síncronas e assíncronas. */ classe pública XMLRouter { /** * Frente de árvore armazenada pelo roteador */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairFront = null; /** * Árvore armazenada pelo roteador */ private static java/util/Hashtable.java.html" target="_blank">Hashtable QueuePairBack = null; /** * O número de índice deste roteador */ rota longa privadaIndex = 0; /** * Configurações do roteador */ private RouterDefine define = nulo; /** * Usado para determinar o ponto de partida da rota */ private java/lang/String.java.html" target="_blank">String action = ""; /** *Esta variável é usada apenas para solicitar uma nova classe no método routeto */ private java/lang/String.java.html" target="_blank">String classname = ""; /** */ XMLRouter público (índice longo) { routeIndex = índice; } /** * Roteamento * Exceção @throws *@roseuid3F1616BD0186 */ roteamento público void (Env env) lança RouterException, java/lang/Exception.java.html" target="_blank">Exception { /*Se for o ponto de partida*/ if(action.equalsIgnoreCase(RouterConstant.CFG_FUNC_ROUTETO)) { … } /*Se for um ponto de retorno*/ senão if(action.equalsIgnoreCase(RouterConstant.CFG_FUNC_ROUTEBACK)) { … } /*Caso contrário é um erro*/ outro throw new RouterException("Definir erro de ação do roteador."); } /** * Leia o número de ID deste roteador. * @return longo */ público longo getIndex() { retornar índice de rota; } /** * Limpe todos os objetos. * @throws RouterException */ public void clear() lança 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)); /*Reciclagem do sistema*/ java/lang/System.java.html" target="_blank">System.runFinalization(); } /** * Defina as configurações deste roteador. * @param def * @throws RouterException */ public void setDefine (RouterDefine def) lança RouterException { definir = definir; } /** * Defina o valor da ação * @param actionName * @throws RouterException */ public void setAction( java/lang/String.java.html" target="_blank">String actionName ) { ação = nomedaação; } } |
Classe de serviço
Aqui está uma citação: pacote com.web.common; importar com.web.platform.Exception.RouterException; /** * A classe pai de Service, abstrata */ classe abstrata pública RouteService { /** */ publicRouteService() { } /** * O método routeTo é o ponto de partida da transação. * @param ambiente * @throws RouterException */ público abstrato void routeto (Env env) lança RouterException; /** *routeBack, o ponto final da transação, * @param ambiente * @throws RouterException */ público abstrato void routeback (Env env) lança RouterException; /** * O método routeaccept é o ponto de recebimento da transação e a função de recebimento do routeto. * routeaccept é a principal função de processamento de objetos de transação passiva * @param env * @throws RouterException */ público abstrato void routeaccept (Env env) lança RouterException; /** * O método de roteamento é a função de interface externa do Serviço * @throws RouterException */ public abstract void routing() lança RouterException |
Em seguida, você precisa implementar todas as classes de serviços, que não serão apresentadas aqui.
6. Explique que
este roteador só pode implementar transações síncronas e não suporta transações assíncronas por enquanto
.Porém, como o Roteador é projetado usando o modelo Composto, a implementação de transações assíncronas também pode ser expandida, portanto, uma análise detalhada não será feita aqui.