[디자인 모델] 책임 체인

8021 단어 디자인 모드
책임 체인 디자인 모델
일반 원칙:
요청 이 책임 체인 의 한 대상 에 의 해 처리 되면 후속 호출 을 중단 합 니 다.그렇지 않 으 면 요청 을 계속 전달 할 것 이다.
변형:
요청 은 책임 체인 의 특정한 대상 에 의 해 처리 되 거나 각 대상 에 의 해 각각 처리 된다.
 
Sample1:
로그 기록 을 예 로 들 면, 작업 은 순서대로 모든 대상 에 전달 되 며, 처리 여 부 는 구체 적 인 대상 에 의 해 결정 된다.
DEBUGE 등급 의 콘 솔 에 만 출력 합 니 다.
NOTICE 등급 의 콘 솔 에 출력 하고 메 일 을 보 냅 니 다.
ERROR 등급 의 경우 콘 솔 에 출력 하고 메 일 을 보 내 며 오 류 를 전문 파일 에 기록 합 니 다.
 
 
= = = 꼭대기 층 인터페이스
public interface ILogger {
	void log(String msg, int priority);
}

 
= = = 템 플 릿 방법, 체인 호출 을 실현 하려 면 다음 책임 대상 의 인용 을 가 져 야 합 니 다.
public abstract class Logger implements ILogger {
	public static final int ERR = 3;
	public static final int NOTICE = 5;
	public static final int DEBUGE = 7;
	
	protected int mask;
	
	//successor
	protected Logger nextLogger;
	
	//this can be done by use spring injection
	public void setNext(Logger logger) {
		this.nextLogger = logger;
	}
	
	//template method
	public void log(String msg, int priority) {
		if(priority <= mask)
			writeMessage(msg);
		
		//invoke next responsibility object
		if(nextLogger != null) {
			nextLogger.log(msg, priority);
		}
			
	}
	
	//how to log message all decided by subclass
	abstract protected void writeMessage(String msg);
}

 
= = = 책임 체인 의 대상 1: 콘 솔 에 로 그 를 출력 하 는 것 을 책임 집 니 다.
public class StdoutLogger extends Logger {
	
	public StdoutLogger(int mask) {
		this.mask = mask;
	}

	@Override
	protected void writeMessage(String msg) {
		System.out.println("Writing to stdout: " + msg);
	}

}

 
= = = 책임 체인 의 대상 2: 메 일 발송 담당
public class EmailLogger extends Logger {
	
	public EmailLogger(int mask) {
		this.mask = mask;
	}

	@Override
	protected void writeMessage(String msg) {
		System.out.println("Sending via e-mail: " + msg);
	}

}

 
= = = 책임 체인 의 대상 3: 오류 로그 기록 담당
public class StderrLogger extends Logger {
	
	public StderrLogger(int mask) {
		this.mask = mask;
	}

	@Override
	protected void writeMessage(String msg) {
		System.err.println("Sending to stderr: " + msg);
	}

}

 
= = = "책임 체인 에서 요청 한 대상 관 계 를 유지 하고 통 일 된 외부 접근 을 제공 합 니 다.
public class LogFacade {
	
	private static ILogger logger;
	
	static {
		initChain();
	}
	
	private static void initChain() {
		StdoutLogger first  = new StdoutLogger(Logger.DEBUGE);
		EmailLogger  second = new EmailLogger(Logger.NOTICE);
		StderrLogger last   = new StderrLogger(Logger.ERR);
		
		first.setNext(second);
		second.setNext(last);
		
		logger = first;
	}
	
	public void log(String msg, int priority) {
		logger.log(msg, priority);
	}
	
}

 
= = = 테스트
public class TestChain {
	public static void main(String[] args) {
		
		LogFacade handler = new LogFacade();
		
		handler.log("Handled by StdoutLogger (level = 7)", Logger.DEBUGE);
		
		handler.log("Handled by StdoutLogger and EmailLogger (level = 5)", Logger.NOTICE);
		
		handler.log("Handled by all three loggers (level = 3)", Logger.ERR);
	}
}

 
= = = 출력:
Writing to stdout: Handled by StdoutLogger (level = 7)
Writing to stdout: Handled by StdoutLogger and EmailLogger (level = 5)Sending via e-mail: Handled by StdoutLogger and EmailLogger (level = 5)
Writing to stdout: Handled by all three loggers (level = 3)Sending via e-mail: Handled by all three loggers (level = 3)Sending to stderr: Handled by all three loggers (level = 3)
 
======================================================================
 
Sample2:
심사 비준 을 청구 하고, 서로 다른 등급 의 사람 이 심사 할 수 있 는 금액 의 크기 가 다르다.
Manager -> Vice President -> President
 
= = = > 패키지 요청
public class PurchaseRequest {
	public long seqNo;
	public double amount;
	public String purpose;
	
	public PurchaseRequest(long seqNo, double amonut, String purpose) {
		super();
		this.seqNo = seqNo;
		this.amount = amonut;
		this.purpose = purpose;
	}
	
	
}

 
= = = 인터페이스 에서 최상 위 방법 설명
public interface Power {
	void processRequest(PurchaseRequest request);
}

 
= = = 추상 클래스 에서 템 플 릿 방법 정의 
public abstract class AbstractPower implements Power {
	
	protected static final double BASE = 1000;
	
	protected double allowable = 1 * BASE;
	
	protected Power successor;
	
	public void setNext(AbstractPower successor) {
		this.successor = successor;
	}
	
	public void processRequest(PurchaseRequest request) {
		if(request.amount < allowable)
			approve(request);
		else if(successor != null)
			successor.processRequest(request);
		else
			System.out.println("Your request for $" + request.amount + " needs a board meeting!");
	}

	protected abstract void approve(PurchaseRequest request);
}

 
= = = 매니저 급
public class ManagerPower extends AbstractPower {
	
	public ManagerPower(Power next){
		this.allowable = 2 * BASE;
		this.successor = next;
	}

	@Override
	public void approve(PurchaseRequest request) {
		System.out.println("Manager's allowable is :" + this.allowable + ". Approve $" + request.amount);
	}

}

 
= = = 부 총 급
public class VicePresidentPower extends AbstractPower {
	
	public VicePresidentPower(Power successor) {
		this.allowable = 5 * BASE;
		this.successor = successor;
	}

	@Override
	protected void approve(PurchaseRequest request) {
		System.out.println("VicePresident's allowable is :" + this.allowable + ". Approve $" + request.amount);
	}

}

 
= = = > 사장 급 
public class PresidentPower extends AbstractPower {

	public PresidentPower(Power successor) {
		this.allowable = 10 * BASE;
		this.successor = successor;
	}
	
	@Override
	protected void approve(PurchaseRequest request) {
		System.out.println("President's allowable is :" + this.allowable + ". Approve $" + request.amount);
	}

}

 
= = = > 책임 사슬 구축, 레벨 최소 부터 승인 제출 
public class CheckAuthority {
	public static void main(String[] args) {
		//      
		Power president = new PresidentPower(null);
		Power vicePresident = new VicePresidentPower(president);
		Power manager = new ManagerPower(vicePresident);
		
		try {
			while(true) {
				System.out.println("Enter the amount to check who should approve your expenditure.");
				System.out.print(">");
				double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine());
				manager.processRequest(new PurchaseRequest(0, d, "General"));
			}
		} catch(Exception exc) {
			System.exit(1);
		}
	}
}

 
 
 
 

좋은 웹페이지 즐겨찾기