Wzorce projektowe: Chain of Responsibility (Łańcuch zobowiązań)

Wzorzec projektowy Chains of Responsibility (Łańcuch zobowiązań) prowadzi do utworzenia łańcucha obiektów, które analizując żadanie zapewniają obsługę lub przekazują je dalej. Odpowiedzialność za przetworzenie żądania spada na obiekt, który jest do tego zadania najlepiej przygotowany.

Abstrakcyjna klasa Handler

<pre>package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public abstract class Handler implements Chainable{
	private Handler succesor;

	public void setSuccesor(Handler succesor) {
		this.succesor = succesor;
	}

	public Handler getSuccesor() {
		return succesor;
	}

	protected void forward(Request request){
		if(this.succesor != null){
			this.getSuccesor().handle(request);
		}
	}

	abstract void handle(Request request);
}

 

package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public interface Chainable {
	public void setSuccesor(Handler succesor);

	public Handler getSuccesor();
}

Handler

package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public class Mod2Handler extends Handler {

	@Override
	void handle(Request request) {
		if (request.getValue() % 2 == 0) {
			System.out.println("Podzielne przez 2");
		} else {
			forward(request);
		}
	}
}

Kolejny Handler

package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public class Mod5Handler extends Handler {

	@Override
	void handle(Request request) {
		if (request.getValue() % 5 == 0) {
			System.out.println("Podzielne przez 5");
		} else {
			forward(request);
		}
	}
}

Kolejny Handler

package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public class Mod7Handler extends Handler {

	@Override
	void handle(Request request) {
		if (request.getValue() % 7 == 0) {
			System.out.println("Podzielne przez 7");
		} else {
			forward(request);
		}
	}
}

Obiekt żądania

package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public class Request {

	private String name;
	private int value;

	public Request(String name, int value) {
		super();
		this.name = name;
		this.value = value;
	}

	public String getName() {
		return name;
	}

	public int getValue() {
		return value;
	}

}

Klient

package pl.roboczenotatki.designpatterns.chainOfResponsibility;

public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Design pattern: Chain of Responsibility" );

        Handler chainBegin = new StartHandler();
        Handler chain1 = new Mod2Handler();
        Handler chain2 = new Mod5Handler();
        Handler chain3 = new Mod7Handler();
        Handler chainEnd = new EndHandler();

        chainBegin.setSuccesor(chain1);
        chain1.setSuccesor(chain2);
        chain2.setSuccesor(chain3);
        chain3.setSuccesor(chainEnd);

        chainBegin.handle(new Request("Test 25", 25));
    }
}

Struktura tego wzorca jest bardzo prosta: obiekty typu Handler są powiązane ze sobą w postaci jednokierunkowej kolejki (albo łańcucha).

Zalety:

  • klient, przekazując żądanie, nie wie, który z obiektów Handler będzie je w rzeczywistości obsługiwał
  • możliwość elastycznego przydziału odpowiedzialności do obiektów Handle

Wady:

  • brak gwarancji obsługi żądania: kolejne ogniwa mogą zrezygnować z zajęcia się nim

Przykłady zastosowania:

  • wszelkiego rodzaju filtry

Diagram wzorca:

 

Reklamy

Wzorce projektowe

Katalog wzorców projektowych Gang of Four (Gamma,Johnson, Helm, Vlissides) obejmuje 23 wzorce:

– kreacyjne: Abstract Factory, Builder, Factory Method, Prototype, Singleton
– strukturalne: Adapter, Bridge, Composite, Decorator,Composite, Facade, Proxy, Flyweight
– behawioralne: Chain of Responsibility, Command,Interpreter, Mediator, Iterator, Memento, Observer,