템플릿 방법 모드 응용 소기

4659 단어
템플릿 방법: 통용되는 프로세스를 추출하고 추상적인 방법을 정의하며 여러 개의 하위 클래스를 정의하여 서로 다른 실현을 얻는다.
원래 코드:
public void intercept(InterceptorChain chain) throws Throwable {
		boolean con = true;
		if(Context.isMe(chain, this)) {
			con = beforeInvoke(chain.getTarget(), chain.getMethod(), chain.getArgs());
			Context.meFinished();
		} else if(allowNesting) {
			log("allow", "before", chain);
			con = beforeInvoke(chain.getTarget(), chain.getMethod(), chain.getArgs());
		} else {
			log("prevent", "before", chain);
		}
			
		long s = System.nanoTime();
		try {
			if (con) {
				chain.doChain();
			}
		} catch (Exception e) {
			boolean throwEx = true;
			
			if(Context.isMe(chain, this)) {
				throwEx = whenInvokeException(e, chain.getTarget(), chain.getMethod(), chain.getArgs());
				Context.meFinished();
			} else if(allowNesting) {
				log("allow", "after", chain);
				throwEx = whenInvokeException(e, chain.getTarget(), chain.getMethod(), chain.getArgs());
			} else {
				log("prevent", "after", chain);
			}
			
			if (throwEx) {
				throw e;
			}
		} finally {
			if(Context.isMe(chain, this)) {
				Object obj = afterInvoke(s,chain.getReturnValue(),chain.getTarget(),chain.getMethod(),chain.getArgs());
				chain.setReturnValue(obj);
				Context.meFinished();
			} else if(allowNesting) {
				log("allow", "after", chain);
				Object obj = afterInvoke(s,chain.getReturnValue(),chain.getTarget(),chain.getMethod(),chain.getArgs());
				chain.setReturnValue(obj);
			} else {
				log("prevent", "after", chain);
			}
		}
		
	}

이 부분을 세 번 반복한 걸 알 수 있어요.

if(Context.isMe(chain, this)) {
    ...
} else if(allowNesting) {
    ...
} else {
    ...
}

내가 세 번째 글을 썼을 때 이미 미쳐버렸다. 이것은 이미 몇 줄의 코드가 많고 몇 줄의 코드가 적은 일이 아니다. 나는 앞으로 누군가가 이 코드를 유지할 때 묵묵히 나를 저주할까 봐 두렵다.
템플릿 메서드를 적용하여 다음과 같이 수정합니다.

//     
private static abstract class Template {
		String type;
		
		public Template(String type) {
			super();
			this.type = type;
		}

		boolean intercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			boolean r = true;
			if (Context.isMe(chain, i)) {
				r = doIntercept(chain, i,e,beginTime);
				Context.meFinished();
			} else if (i.allowNesting) {
				i.log("allow", type, chain);
				r = doIntercept(chain, i,e,beginTime);
			} else {
				i.log("prevent", type, chain);
			}
			return r;
		}

		abstract boolean doIntercept(InterceptorChain chain,
				AbstractInterceptor i,Exception e,long beginTime);
	}
	
        //   3      。

	private static final Template before = new Template("before") {
		boolean doIntercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			return i.beforeInvoke(chain.getTarget(), chain.getMethod(), chain.getArgs());
		}
	};
	
	private static final Template after = new Template("after") {
		boolean doIntercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			Object obj = i.afterInvoke(beginTime,chain.getReturnValue(),chain.getTarget(),chain.getMethod(),chain.getArgs());
			chain.setReturnValue(obj);
			return true;
		}
	};
	
	private static final Template whenException = new Template("whenException") {
		boolean doIntercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			 return i. whenInvokeException(e, chain.getTarget(), chain.getMethod(), chain.getArgs());
		}
	};
	
	//          
	public void intercept(InterceptorChain chain) throws Throwable {
		boolean doChain = before.intercept(chain, this, null, 0L);

		long s = System.nanoTime();
		
		try {
			if (doChain) {
				chain.doChain();
			}
		} catch (Exception e) {
			if (whenException.intercept(chain, this, e, s)) {
				throw e;
			}
		} finally {
			after.intercept(chain, this, null, s);
		}

	}

코드가 원래보다 적은 것은 아니지만 마음은 상쾌하고 즐겁게 일하는 원칙에 부합된다.

좋은 웹페이지 즐겨찾기