10. 책임 체인 모드(Chain of Responsibility)

7400 단어 책임 체인 모델
자세히 보기
1. 정의:
여러 대상이 요청을 처리할 수 있는 기회를 주어 요청의 발송자와 수신자 간의 결합 관계를 피한다.이 대상들을 하나의 체인으로 연결하고, 대상이 그것을 처리할 때까지 이 체인을 따라 이 요청을 전달한다.책임 체인 모델은 일종의 대상의 행위 모델이다.
 
2. 범용 코드
이 모델은 매우 간단하다. 아마도 유니버설 코드를 보면 이해할 수 있을 것이다.
package _10ChainOfResponsibility;

public abstract class Handler {
	
	private Handler nextHandler;
	
	public final void service(String request)
	{
		//           ,    ,            
		if(this.canIService())
		{
			this.realService();
		}else{
			if(null != nextHandler)
			{
				//             
				nextHandler.service(request);
			}else{
				//       ,        ,        
			}
		}
	}

	public void setNextHandler(Handler nextHandler) {
		this.nextHandler = nextHandler;
	}
	
	//                
	protected abstract boolean canIService();
	//        
	protected abstract void realService();
}

 
3. 책임 체인 모델의 두 역할
4
  • 추상 처리자(Handler) 역할: 요청을 처리하는 인터페이스를 정의합니다.필요하면, 인터페이스에서 다음 인용을 설정하고 되돌려 주는 방법을 정의할 수 있습니다.이 역할은 보통 자바 추상 클래스나 자바 인터페이스로 이루어진다.Handler 클래스의 집합 관계는 구체적인 하위 클래스가 하위 클래스에 대한 인용을 제시하고 추상적인 방법 서비스 ()는 하위 클래스 처리 요청의 조작을 규범화시켰다

  • 4
  • 구체적인 처리자(ConcreteHandler) 역할: 구체적인 처리자가 요청을 받은 후 요청을 처리하거나 하가에 요청을 전달할 수 있다.구체적인 처리자는 하가에 대한 인용을 가지고 있기 때문에 필요하면 구체적인 처리자는 하가를 방문할 수 있다

  • 4. 장면 사용
    회식비 관리를 신청하는 기능을 고려한다.많은 회사들이 이런 혜택을 받는다. 바로 프로젝트팀이나 부서가 회사에 회식 비용을 신청하여 프로젝트팀 구성원이나 부서 구성원을 조직하여 회식 활동을 할 수 있다.회식 비용을 신청하는 대체적인 절차는 신청인이 먼저 신청서를 작성한 다음에 지도자에게 심사 비준을 맡긴다. 만약에 심사 비준을 신청하면 지도자는 신청인에게 심사 비준을 통과한다고 통지하고 신청인은 재무로 비용을 수령한다. 만약에 심사 비준을 받지 못하면 지도자는 신청인에게 심사 비준이 통과되지 않았다고 통지하고 이 일도 이것으로 끝난다.서로 다른 등급의 지도자는 심사 비준의 한도가 다르다. 예를 들어 프로젝트 매니저는 500위안 이내의 신청만 심사 비준할 수 있다.부서 매니저는 1000위안 이내의 신청을 심사 비준할 수 있다.사장은 임의의 액수의 신청을 심사할 수 있다.즉, 어떤 사람이 회식비 신청을 하면 이 청구는 프로젝트 매니저, 부서 매니저, 사장 중 한 명의 지도자를 거쳐 상응하는 처리를 하지만 신청을 한 사람은 최종적으로 누가 그의 청구를 처리할지 모른다. 일반적으로 청구인은 자신의 신청을 프로젝트 매니저에게 제출하고 마지막에는 사장이 그의 청구를 처리할 수도 있다.책임 체인 모델을 사용하여 상술한 기능을 실현할 수 있다. 어떤 사람이 회식 비용 신청을 하면 이 청구는 프로젝트 매니저-〉부서 매니저-〉 사장과 같은 리더십 처리 체인에서 전달된다. 청구를 한 사람은 누가 그의 청구를 처리할지 모른다. 각 지도자는 자신의 직책 범위에 따라 청구를 처리하는지 더 높은 등급의 지도자에게 맡기는지 판단한다.지도자가 처리하기만 하면 전달은 끝난다.각 지도자의 처리를 독립시켜 단독의 직책 처리 대상으로 실현한 다음에 그들에게 공공적이고 추상적인 부직책 대상을 제공해야 한다. 그러면 클라이언트가 직책 체인을 동태적으로 조합하여 서로 다른 기능 요구를 실현할 수 있다.
     
    다음은 책임 체인 모델로 이루어진 상술한 기능을 살펴보자.
     
    package _10ChainOfResponsibility;
    
    public abstract class FeeHandler {
    
    private FeeHandler nextHandler;
    	
    	public final boolean handleFeeRequest(int fee)
    	{
    		//            ,    ,          
    		if(this.canIService(fee))
    		{
    			this.realService(fee);
    		}else{
    			if(null != nextHandler)
    			{
    				//         
    				return nextHandler.handleFeeRequest(fee);
    			}
    		}
    		return false;
    	}
    
    	public void setNextHandler(FeeHandler nextHandler) {
    		this.nextHandler = nextHandler;
    	}
    	
    	//            
    	protected abstract boolean canIService(int fee);
    	
    	//        
    	protected abstract void realService(int fee);
    }
    
     
    package _10ChainOfResponsibility;
    //    
    public class ProjectManagerHandler extends FeeHandler {
    
    	@Override
    	protected boolean canIService(int fee) {
    		if(fee > 500)
    		{
    			System.out.println(fee+" ,         ");
    			return false;
    		}
    		return true;
    	}
    
    	@Override
    	protected void realService(int fee) {
    		System.out.println(fee+" ,      ");
    	}
    
    }
    
     
    package _10ChainOfResponsibility;
    //     
    public class DeptManagerHandler extends FeeHandler {
    
    	@Override
    	protected boolean canIService(int fee) {
    		if(fee > 1000)
    		{
    			System.out.println(fee+" ,         ");
    			return false;
    		}
    		return true;
    	}
    
    	@Override
    	protected void realService(int fee) {
    		System.out.println(fee+" ,      ");
    	}
    
    }
    
     
    package _10ChainOfResponsibility;
    //   
    public class GeneralManagerHandler extends FeeHandler {
    
    	@Override
    	protected boolean canIService(int fee) {
    		//       ,       
    		return true;
    	}
    
    	@Override
    	protected void realService(int fee) {
    		System.out.println(fee+" ,     ");
    	}
    
    }
    
     
    package _10ChainOfResponsibility;
    
    public class Client {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		ProjectManagerHandler pmh = new ProjectManagerHandler();
    		DeptManagerHandler dmh = new DeptManagerHandler();
    		GeneralManagerHandler gmh = new GeneralManagerHandler();
    		
    		pmh.setNextHandler(dmh);
    		dmh.setNextHandler(gmh);
    		
    		System.out.println("   PM    300");
    		pmh.handleFeeRequest(300);
    		System.out.println("   PM    600");
    		pmh.handleFeeRequest(600);
    		System.out.println("   PM    2000");
    		pmh.handleFeeRequest(2000);
    		
    	}
    
    }
    
     
    Client 출력:
    장삼은 PM을 찾아 식비 300을 결산했다
    300위안, 프로젝트 매니저가 비준했다
    장삼은 PM을 찾아 식비 600을 결산했다
    600위안, 프로젝트 매니저는 심사 비준할 권한이 없다
    600위안, 부서장이 비준했다
    장삼은 PM을 찾아 식비 2000을 결산했다
    2000위안, 프로젝트 매니저는 심사 비준할 권한이 없다
    2000위안, 부서장은 심사 비준할 권한이 없다
    2000위안, 사장님이 허가하셨습니다.
     
    5. 순수하고 불순한 책임 체인 모델
    하나의 순수한 책임 체인 모델은 구체적인 처리자 대상이 두 가지 행위 중 하나만 선택할 수 있도록 요구한다. 하나는 책임을 지는 것이 아니라 책임을 하가에 떠넘기는 것이다.어떤 구체적인 처리자 대상이 일부 책임을 지고 나서 책임을 아래로 전하는 경우는 허용되지 않는다.순수한 책임 체인 모델에서 하나의 요청은 반드시 어떤 처리자 대상에게 받아들여야 한다.불순한 책임 체인 모델에서 하나의 요청은 최종적으로 어떤 수신자 대상에게 접수되지 않을 수 있다.순수한 책임 체인 모델의 실제 예는 찾기 어렵다. 일반적으로 볼 수 있는 예는 모두 불순한 책임 체인 모델의 실현이다.어떤 사람들은 불순한 책임 체인이 책임 체인 모델이 아니라고 생각하는데, 이것은 아마도 일리가 있을 것이다.그러나 실제 시스템에서는 순수한 책임 체인을 찾기 어렵다.만약에 책임 체인이 순수하지 않으면 책임 체인 모델이 아니라고 주장한다면 책임 체인 모델은 큰 의미가 없을 것이다.
     
    6. 책임 체인 모델의 장점
    책임체인 모델의 현저한 장점은 요청과 처리를 분리하는 것이다.청구자는 누가 처리했는지 알 수 없고 처리자는 청구의 전모를 알 필요가 없으며 양자가 결합되어 시스템의 유연성을 높일 수 있다.
     
    7. 책임 체인 모델의 단점
    책임 체인 모델은 두 가지 현저한 단점이 있다.
    4
  • 하나는 성능 문제이다. 모든 요청은 체인 헤드에서 체인 꼬리까지 옮겨야 한다. 특히 체인이 비교적 길 때 성능은 매우 큰 문제이다

  • 4
  • 둘째, 디버깅이 불편하다. 특히 체인이 길고 고리가 많을 때 유사한 귀속 방식을 사용했기 때문에 디버깅을 할 때 논리가 비교적 복잡하다

  • 8. 책임 체인 모델의 주의사항
    책임 체인에서 노드의 수량을 제어해야 하기 때문에 초장기 체인이 발생하는 상황을 피해야 한다. 일반적인 방법은Handler에서 최대 노드의 수량을 설정하고 setNext 방법에서 밸브 값을 초과했는지 판단하고 초과하면 이 체인의 구축을 허락하지 않으며 무의식적으로 시스템 성능을 파괴하지 않도록 한다.
     
    9. 실제 사용 예
    Tomcat의 Filter는 웹 이외에 책임 체인 모드를 사용한 것으로 알려져 있습니다.xml 파일에서 상응하는 설정을 하는 것 외에javax를 실현해야 합니다.servlet.Filter 커넥터.
     
    public class TestFilter implements Filter{
    
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            
            chain.doFilter(request, response);
        }
    
        public void destroy() {
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
    }

    좋은 웹페이지 즐겨찾기