Chain of Responsibility (padrón de deseño): Diferenzas entre revisións

Contido eliminado Contido engadido
Sen resumo de edición
arranxiños ortográficos
Liña 1:
O'''Chain of Responsability''' (en [[Patrón_de_deseño|patrón delingua deseñoinglesa|inglés]] '''"Cadea de Responsabilidade'''responsabilidade") é un [[patrón de comportamentodeseño]] que permite xestionar unha petición a máis de un obxecto mediante o encadeamento de receptores, que se pasan a petición ó longo da cadea ata que un dos obxectos manipula dita petición.
 
Un patrón de cadea de responsabilidade é a miúdo utilizado no contexto de interfaces gráficas de usuario onde un obxecto pode conter varios outros obxectos. Segundo o ambiente de ventanasventás xera eventos, os obxectos ou os manexan ou los pasan.
O [[Patrón_de_deseño|patrón de deseño]] '''Cadea de Responsabilidade''' é un patrón de comportamento que permite xestionar unha petición a máis de un obxecto mediante o encadeamento de receptores, que se pasan a petición ó longo da cadea ata que un dos obxectos manipula dita petición.
Un patrón de cadea de responsabilidade é a miúdo utilizado no contexto de interfaces gráficas de usuario onde un obxecto pode conter varios outros obxectos. Segundo o ambiente de ventanas xera eventos, os obxectos ou os manexan ou los pasan.
 
== Motivación ==
* Supoñamos un servizo de axuda sensible ó contexto para unha interface gráfica de usuario. O usuario pode obter información de axuda en calquera parte da mesma simplemente pulsando co rato sobre ela. A axuda proporcionada depende da parte da interface que se selecciona así como do seu contexto. Se non existe información de axuda específica para esa parte da interface o sistema de axuda debería mostrar un mensaxe de axuda más xeral sobre o contexto inmediato.
* Se o obxecto "actual" seleccionado da cadea ten información específica debe presentala e manexar a petición; en caso contrario, debe enviar a petición (mensaxe) ó seu sucesor na cadea de responsabilidade.
* O problema é que o obxecto que en última instancia proporciona a axuda non coñece explicitamente o obxecto que inicializainicia a petición de axuda. Necesitamos un modo de desacoplar o botón que da lugar á petición de axuda dos obxectos que poderían proporcionar dita información. O patrón Cadea de Responsabilidade define como facer isto: a idea é desacoplar ós emisores e ós receptores dándolle a varios obxectos a posibilidade de tratar unha petición. Esta petición pasará a través da cadea de obxectos ata que sexa procesada por un deles.
 
[[Ficheiro:Motivacion2GL.png|center|500px|]]
 
SupoñamosSe que oun usuario solicita axuda sobre un botón denominado "Imprimir". O botón encóntrase nunha instancia de DialogoDeImpresion. O seguinte diagrama de interacción mostra como a petición de axuda se reenvía a través da cadea.
 
[[Ficheiro:Motivacion3GL.jpg|center|500px|]]
 
NesteNese caso a petición non é procesada nin por unBotonDeImpresion nin por unDialogoDeImpresion; detense en unhaAplicacion, quen pode procesala ou ignorala. O cliente que deu orixe á petición non ten ningunha referencia directa ó obxecto que finalmente a satisfacesatisfai.
 
Para reenviar a petición ó longo da cadea e para garantir que os receptores permanecen implícitos, cada obxecto da cadea comparte unha interface común para procesar peticións e para acceder ó seu sucesor na cadea. Por exemplo, neste sistema de axuda podería definirse unha clase ManexadorDeAxuda.
 
[[Ficheiro:Motivacion1GL.jpg|center|500px|]]
 
== Aplicabilidade ==
* Cando temoshai máis de un obxecto que pode manexar unha petición, pero non se sabe a priori cal deles o ten que facer.
* Se non se desexa identificar explicitamente quen é o receptor da petición.
* Cando os obxectos que poden manexar a petición varían dinamicamente.
 
== EstructuraEstrutura ==
[[Ficheiro:EstructuraGL.jpg|center|500px|Añadir una leyenda aquí]]
 
== Participantes ==
* '''Manexador''' : A interface que define o método usado para pasar unha menxasemensaxe ó seguinte handler. A mensaxe é normalmente unha chamada a un método. AdemáisAdemais, frecuentemente define tamén o enlace ó sucesor na cadea.
 
* '''Manexador concreto''' : Unha clase que implementa a interface Handler e mantén unha referencia ó seguinteHandler. Esta referencia pode ser asignada no constructorconstrutor da clase ou a través dun método setter. A implementación do método de manexo de mensaxes pode chamar a un método para manexar as peticións das que é responsable ou, en caso contrario, se non pode xestionar unha delas delega a petición no seu sucesor.
 
* '''Cliente''' : Envía unha petición a algún Manexador Concreto da cadea.
Liña 38 ⟶ 39:
 
== Consecuencias ==
* Reduce o acoplamento de obxectos: tanto o manexador como o cliente non coñecen a estructuraestrutura da cadea en si. AdemáisAdemais, coñécese unicamente como chegar ó primeiro "eslabón"elo da cadea, pero non se sabe a implementacion que hai de por medio.
* Flexibilidade engadida á hora de engadir responsabilidades a obxectos: por exemplo, no caso de ter un departamento de recepción de documentos que está moi ocupado atendendo a varios clientes á vez, pódese facer que a secretaría reciba algúns dos documentos e que o porteiro faga o mesmo.
* A Cadea de Responsabilidades ofrece unha gran flexibilidade no procesamento de eventos para unha aplicación, xa que domina o manexo de eventos complexos dividindo as responsabilidades a través dun número de elementos simples, permitindo a un grupo de clases comportarse como un todo.
* A recepción da petición non está garantizadagarantida: ó non haber un receptor explícito para as mensaxes, non se garantizagarante que esta chegue nin tampocotampouco se garantizagarante que cando chegechegue se procese de maneira adecuada. '''(Inconvinte)'''
 
 
== Implementación ==
Liña 48:
* Definir novos enlaces (normalmente no Manexador, pero tamén podería ser nos obxector ManexadorConcreto).
* Usar enlaces existentes (outras asociacións existentes). Por exemplo, no patrón Composición pode existir xa un enlace ó pai que pode utilizarse para definir a cadea de responsabilidade sen necesidade de engadir outra asociación.
* Conexión de sucesores. Se non hai referencias preexistentes para definir unha cadea, entoncesentón teremos que introducilas nosoutros mesmos. Neste caso, o Manexador define a interface e ademáisademais encárgase de manter o sucesor. EstoIsto permite que o Manexador proporcione unha implementación predeterminada de ManexarPetición que reenvíe a petición ó sucesor (se hai algún). Se unha subclase de ManexadorConcreto non está interesada en dita petición, non ten que redefinir a operación de reenvío.
 
Representación das peticións
* un método por cada petición. EstoIsto resulta convinteadecuado e seguro, pero sólo se pode reenviar o conxunto prefixado de peticións que define a clase Manexador.
* único método parametrizado para distinguir distintas peticións. EstoIsto permite un número arbitrario de peticións pero emisor e receptor deben poñerse de acordo sobre como codificar a petición.
 
== Patróns Relacionadosrelacionados ==
 
Este patrón pódese aplicar conxuntamente co patrón [[Composite (patrón de deseño)|ComposiciónComposite]]. Neste, os pais dos compoñentes poden actuar como sucesores.
== Patróns Relacionados ==
 
Este patrón pódese aplicar conxuntamente co patrón [[Composite (patrón de deseño)|Composición]]. Neste, os pais dos compoñentes poden actuar como sucesores.
 
== Exemplo de Implementación ==
 
[[Ficheiro:DClasesGL.jpg|center|500px|]]
 
 
 
<big><source lang="java">
Liña 70 ⟶ 65:
public static void main(String argv[]) {
Unidade smith = new Coronel("Smith", null);
Unidade truman = new Coronel("Truman", "Tomar posición enemigainimiga");
Unidade ryan = new Soldado("Ryan");
Unidade rambo = new Soldado("Rambo");
Liña 93 ⟶ 88:
public abstract class Unidade {
 
/* No constructorconstrutor, ademáisademais dun nome para a unidade, inicialízaseiníciase a referencia que implementa a cadea de responsabilidade (_mando): en principio no hai sucesor */
que implementa a cadea de responsabilidade (_mando): en principio no hai sucesor */
 
public Unidade(String nome) {
Liña 107 ⟶ 101:
public void establecerMando(Unidade mando) { _mando = mando; }
 
/* comportamento por defecto da cadea: delegar no mando directo ou, se se alcanza o final da cadea, utilizar unha resolución por defecto (sen orde) */
alcanza o final da cadena, utilizar unha resolución por defecto (sen orde) */
 
public String orde() {
Liña 129 ⟶ 122:
public class Coronel extends Unidade {
 
// inicializainicia a parte de unidade e inicializainicia o estado propio do Coronel (_orde)
 
public Coronel(String nome, String orde) {
Liña 150 ⟶ 143:
<source lang="java">
/**
* Esta clase é unha extensión instanciable da superclase Unidade que respetarespecta o
* comportamento por defecto da cadea de responsabilidade
*/
Liña 156 ⟶ 149:
public class Soldado extends Unidade {
 
// o constructorconstrutor só ten que inicializariniciar a parte correspondente á superclase
 
public Soldado(String nome) {
Liña 167 ⟶ 160:
 
</big>
 
 
 
[[Ficheiro:SecuenciaGL.jpg|center|600px|]]