Sunday, October 18, 2009

Design Pattern in Brief (9)

Chain of Responsibility

Pattern ini mirip dengan model layering dalam arsitektur software. Pattern ini menjelaskan bahwa antara object pengirim request dan object-object yang menangani request sebaiknya terpisah bahkan benar-benar tidak saling terkait (loosely coupling).

Jika ada lebih dari satu object yang bertugas menangani request, maka prosesnya dilakukan secara berurutan. Urutan tersebut membentuk sebuah rantai di mana setiap object mempunyai pointer yang merujuk ke chain selanjutnya.

Object pertama yang menerima request bisa memutuskan apakah akan menghandle request atau meneruskannya ke object selanjutnya. Request tersebut berjalan terus sampai dihandle oleh salah satu object atau request sampai di ujung rantai tanpa ada yang menghandlenya. Dengan kata lain, setelah melewati serangkaian rantai tersebut, request bisa saja tidak ada yang menghandlenya.

Berikut adalah karakteristik dari Chain of Responsibility :

- Sekumpulan request handler, dan urut-urutannya sehingga membentuk sebuah rantai dapat dilakukan secara dinamis saat runtime oleh klien.
- Klien bisa memiliki rantai request handler yang berbeda-beda tergantung jenis requestnya.
- Baik klien maupun masing-masing object request handler tidak perlu tahu object handler mana yang akhirnya menghandle request.
- Setelah melalui rantai request handler, request bisa saja tidak ada yang menghandlenya.

Untuk aplikasinya perhatikan contoh berikut :

Misal kita mempunyai sebuah purchase request.



Agar purchase request ini bisa dikirim maka harus melewati serangkaian pemeriksaan batas pembelian oleh 4 manajerial level.





Perhatikan diagram dan kode berikut :



Kita memiliki PRHandler sebagai parent dari keempat manajerial class request handler di atas. Berikut adalah codenya

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public abstract class RequestHandler {

protected RequestHandler nextHandler;

public abstract boolean authorize(PurchaseRequest request);

public RequestHandler getNextHandler() {
return nextHandler;
}

public void setNextHandler(RequestHandler nextHandler) {
this.nextHandler = nextHandler;
}
}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class BranchManager extends RequestHandler {

private static final int LIMIT = 25000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by branch manager...");
return true;
} else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class PresidentCOO extends RequestHandler {

private static final int LIMIT = 400000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by president coo...");
return true;
} else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class RegionalDirector extends RequestHandler {

private static final int LIMIT = 100000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by regional director...");
return true;
} else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.chain;

import edu.mat.pattern.request.PurchaseRequest;

public class VicePresident extends RequestHandler {

private static final int LIMIT = 200000;

@Override
public boolean authorize(PurchaseRequest request) {
// do authorization
if(request.getAmount() <= LIMIT) {
System.out.println("Authorized by vice president...");
return true;
}else
return nextHandler.authorize(request);
}

}

package edu.mat.pattern.request;

public class PurchaseRequest {

private String id;
private String description;
private double amount;

public PurchaseRequest(String id, String description, double amount) {
super();
this.id = id;
this.description = description;
this.amount = amount;
}

public String getId() {
return id;
}

public String getDescription() {
return description;
}

public double getAmount() {
return amount;
}

}

package edu.mat.pattern.main;

import edu.mat.pattern.chain.BranchManager;
import edu.mat.pattern.chain.PresidentCOO;
import edu.mat.pattern.chain.RegionalDirector;
import edu.mat.pattern.chain.VicePresident;
import edu.mat.pattern.request.PurchaseRequest;

public class Main {

public static void main(String args[]) {
BranchManager branchManager = new BranchManager();
PresidentCOO presidentCOO = new PresidentCOO();
RegionalDirector regionalDirector = new RegionalDirector();
VicePresident vicePresident = new VicePresident();

branchManager.setNextHandler(regionalDirector);
regionalDirector.setNextHandler(vicePresident);
vicePresident.setNextHandler(presidentCOO);
presidentCOO.setNextHandler(null);

PurchaseRequest request = new PurchaseRequest("one", "request one", 300000);
branchManager.authorize(request);
}
}

Jika dijalankan :

Authorized by president coo...

0 comments:

 

©2009 Stay the Same | by TNB