terça-feira, 9 de novembro de 2010

Chain-of-responsibility Pattern




Definição

O Chain-of-responsibility permite que mais de um objeto lide com um  pedido, sem o conhecimento mútuo. Evitamos o acoplamento entre o remetente do pedido e os receptores possíveis, ao dar a mais de um objeto a oportunidade de tratar a solicitação.

Quando usar

• Quando mais de um objeto pode tratar uma solicitação e o manipulador não é
conhecido.
• Quando você quiser emitir um pedido a um dos vários objetos sem
especificar o receptor de forma explícita.
• Quando o conjunto de objetos que podem lidar com um pedido deve ser especificado dinamicamente.

Benefícios

• Reduz o acoplamento.
• Aumenta a flexibilidade de lidar com um pedido.

Desvantagens / consequências

A recepção não é garantida pois o pedido não tem receptor explícito, e não há garantia de que vai ser tratado (o pedido  pode sair pelo final da cadeia sem ter sido tratada) a menos que a cadeia esteja configurada corretamente.





Exemplo

No exemplo a seguir  do ChainDemo ele é responsável pela criação de  uma cadeia de instâncias Handler, e passa três pedidos a eles. Os manipuladores, de forma aleatória decidem se e quando algum deles irá lidar com o pedido.


public class Handler {
private static java.util.Random s_rn = new java.util.Random();
private static int s_next = 1;
private int m_id = s_next++;
private Handler m_next;

public void add(Handler next) {
if (m_next == null)
m_next = next;
else
m_next.add(next);
}

public void wrap_around(Handler root) {
if (m_next == null)
m_next = root;
else
m_next.wrap_around(root);
}

public void handle(int num) {
if (s_rn.nextInt(4) != 0) {
System.out.print(m_id + "-busy ");
m_next.handle(num);
} else
System.out.println(m_id + "-handled-" + num);
}
}

public class ChainDemo {
public static void main(String[] args) {
Handler chain_root = new Handler();
chain_root.add(new Handler());
chain_root.add(new Handler());
chain_root.add(new Handler());
chain_root.wrap_around(chain_root);
for (int i = 1; i <= 3; i++)
chain_root.handle(i);
}
}

Quando ChainDemo for executada o resultado é:
1-busy 2-busy 3-handled-1
1-busy 2-busy 3-busy 4-busy 1-busy 2-busy 3-busy 4-busy 1-
busy 2-handled-2
1-handled-3

Exemplo de uso

Um bom exemplo é a criação de um sistema de registro de erros. Com a criação de diferentes manipuladores de erro, com a diferenciação das responsabilidades e de liga-los em uma cadeia. Podemos, então, passar, todos os erros possíveis que queremos de log

Nenhum comentário:

Postar um comentário