디렉토리
1. 개념
그래서 비즈니스 요구에 따라 서브 클래스는 상위 클래스에 정의 된 알고리즘 프레임, 충전 프레임의 특정 단계를 구현합니다. 템플릿 메소드는 서브 클래스가 알고리즘의 구조를 변경하지 않고 알고리즘의 구현의 일부를 다시 정의 할 수 있습니다.
서브 클래스는 템플릿 메소드를 오버라이드 (override)하지 않는 것을 보장하기 위해, 템플릿 메소드는 final로 선언되어야합니다
2. 적용
- 상위 클래스가 구현하는 알고리즘의 동일한 부분 및하자 아이 클래스는 행동의 변화 가능성을 구현합니다.
- 피하기 코드 중복을 하나 개의 공통 클래스의 서브 클래스와이 분해 사이의 일반적인 행동.
프로그램의 3 예
등 지난해 심은 밀, 옥수수 심기 올해의 희망, 예를 들어 우리 삼촌 모돈 농가, 재배 과정이 크게으로 나누어 져있는 동안 : 등, 물 씨앗 파종의 구매에 관계없이 Zhongsha의,이 갈이 프로세스에 의해입니다 현상은, 그것은 템플릿 메소드 패턴에 기인한다.
우리는 그것을 달성하기 위해 특정 코드를 좀 봐!
3.1 추상 클래스는 핵심 알고리즘과 알고리즘 프레임 워크를 캡슐화
public abstract class AbstractPlantMethod {
/**
* 购买种子
*/
public abstract String buySeeds();
/**
* 播撒
*/
public abstract void sow(String seeds);
/**
* 浇水
*/
public abstract void watering(String seeds);
/**
* 种植方法(定义为final,防止子类重写该核心算法)
*/
public final void planting() {
String seeds = this.buySeeds();
this.sow(seeds);
this.watering(seeds);
}
}
3.2. 조파 밀
public class WheatMethod extends AbstractPlantMethod {
@Override
public String buySeeds() {
System.out.println("购买小麦作物中...");
return "wheats";
}
@Override
public void sow(String seeds) {
System.out.println("正在播撒" + seeds + "中...");
}
@Override
public void watering(String seeds) {
System.out.println("正在给" + seeds + "浇水中...");
}
}
3.3. 심기 옥수수
public class CornMethod extends AbstractPlantMethod {
@Override
public String buySeeds() {
System.out.println("购买玉米作物中...");
return "corns";
}
@Override
public void sow(String seeds) {
System.out.println("正在播撒" + seeds + "中...");
}
@Override
public void watering(String seeds) {
System.out.println("正在给" + seeds + "浇水中...");
}
}
3.4. 농부 삼촌
public class Farmers {
private AbstractPlantMethod plantMethod;
public Farmers(AbstractPlantMethod plantMethod) {
this.plantMethod = plantMethod;
}
public void plant() {
plantMethod.planting();
}
public void changeMethod(AbstractPlantMethod plantMethod) {
this.plantMethod = plantMethod;
}
}
3.5 클라이언트 호출
public class Client {
public static void main(String[] args) {
Farmers farmers = new Farmers(new WheatMethod());
//播种小麦
farmers.plant();
farmers.changeMethod(new CornMethod());
//播种玉米
farmers.plant();
}
}
3.6. 인쇄
购买小麦作物中...
正在播撒wheats中...
正在给wheats浇水中...
购买玉米作物中...
正在播撒corns中...
正在给corns浇水中...
템플릿 항에있어서 JDK1.8의 패턴에 사용 된
키 코드의 일부는 부모 클래스의 AbstractList를 아래 ArrayList를 우리가 매일 사용하고 있다고 생각하지만, 우리는 부모 클래스와 달성하기 위해 인터페이스에 대해 우려 적이 없습니다, 나는 나열했습니다.
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//get方法(抽象的方法,必须让子类按照自己的业务去实现)
abstract public E get(int index);
//addAll方法,允许子类去重写该方法,如果不重写,也可用父类中已经定义好的方法。
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
boolean modified = false;
for (E e : c) {
add(index++, e);
modified = true;
}
return modified;
}
}
ArrayList에 그것의 핵심 코드를 살펴 보자
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//实现的get方法
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
//重写父类的addAll方法
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
}
스프링에 사용되는 템플릿 패턴 항에있어서,
시스템을 구축 할 때 서블릿 봄, 우리는 템플릿 메소드 패턴을 사용, 부모 클래스의 키 코드에서의 모습을 보자.
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
//重写了Javax提供的init方法,并将方法用final修饰,那么它的子类就没有权限修改init方法了
@Override
public final void init() throws ServletException {
// Set bean properties from init parameters.
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
if (!pvs.isEmpty()) {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
if (logger.isErrorEnabled()) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
}
throw ex;
}
}
// Let subclasses do whatever initialization they like.
initServletBean();
}
}
그리고 그 서브 클래스는 FrameworkServlet와 DispatcherServlet이이 방법의 일부를 다시 작성하기 만하면, 초기화 메소드를 오버라이드 (override) 갈 수 없어, 공통의 init 메소드입니다.
6. 요약
우리는 부모 클래스의 메소드를 수정하지 않는 서브 클래스로 원하는 경우에만 할 수있는 최종 수정을 추가해야합니다, 당신은 부모 클래스의 서브 클래스는 부모 클래스 추상적 인 수정을 사용하는 메소드를 오버라이드 (override) 할 필요가 원하는 경우, 서브 클래스는 변경 될 수있는 경우 당신이 오퍼레이션과 addAll 방법으로 할 수 있던대로 수정할 수 없습니다, 당신은 디자인 할 수 있습니다.