淺談設計模式的學習(中)

在《淺談設計模式的學習(上)》中我說到了設計模式的基石-----抽象思惟。爲何須要抽象思惟呢?由於越抽象就越不容易出錯,就像有些領導人說話:堅持改革開放。但怎麼算堅持改革開放呢,沒有具體的標準,因事而異,因此就不容易違背這個堅持改革開放的原則了。java

三、學習設計模式,要保持抽象的思惟編程

    什麼是抽象思惟呢?真的很差說,抽象的東西每每難以說明白,聽了也難以搞明白,仍是經過具體的例子來講吧
設計模式

    有這麼一個學生請假的場景,若是請假時間一天之內則有班長批准就能夠了,三天之內則須要老師批准,超過三天就得找校長審批了,校長能審批不超過五天,超過五天就須要開會解決了。在這裏咱們就以這個場景爲例,展現一下如何抽象編程。ide

  第一步:學習

       在上邊的請假流程中咱們看到了班長、老師、校長等實體(爲了把注意力放在請假流程上,暫不對學生和請假實體多處理)。運用抽象思惟咱們抽象一下,這幾個實體有什麼共同特徵呢?對他們都是人,好吧咱們就寫一我的的接口,可是裏邊該有什麼方法呢?與咱們上邊需求相關的方法目前尚未,不要緊,暫時空着this

public interface IPerson {

}

 第二步:在第一步中絕對夠抽象了吧,咱們如今再具體一點吧,一步步往下具體。班長、老師、校長都是什麼人呢?是否是都有必定的管理權力啊,並且在咱們這個需求裏,他們都有批准假期的權力,同時班長、校長都有本身的上級領導。如今咱們的接口出來了:spa

public interface IManager extends IPerson{
	
	public void process(Request request);
	
	public void setLeader(IManager leader);
}

這裏用到了請求實體類:設計

public class Request {

	/**請假人名字*/
	private String name;
	/**請假天數*/
	private int days;
	/**請假緣由*/
	private String cause;
	/**請假日期*/
	private Date date;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getDays() {
		return days;
	}
	public void setDays(int days) {
		this.days = days;
	}
	public String getCause() {
		return cause;
	}
	public void setCause(String cause) {
		this.cause = cause;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	
}

第三步:咱們再往下具體,在IManager接口中有兩個方法,設置領導的方法和處理請假請求的方法。試想一下,設置上級領導的方法對班長、老師和校長來講是否是都是同樣的。同時處理請假的流程也是同樣的,想一想看,每一個領導是否是都是先根據本身的批准能力來,若是請假天數在本身的批准能力範圍內則處理,超過了則請求本身的上級領導批准。而具體怎麼處理,每一個領導則是不一樣的對吧。因此這裏在一個抽象類裏實現了設置領導和批假的模板方法,並抽象了一個具體批准處理的抽象方法。來看代碼:blog

public abstract class AbstractManager implements IManager{

	protected IManager leader;
	
	protected int handleDay;
	
	/**
	 * 
	 * @param handleDay 能批准的天數
	 */
	public AbstractManager(int handleDay){
		this.handleDay = handleDay;
	}
	
	@Override
	public void setLeader(IManager leader) {
		this.leader=leader;
	}
	
	@Override
	public final void process(Request request) {
		boolean isOk = handleRequest(request);
		if(!isOk){
			if(leader!=null){
				leader.process(request);
			}
		}
	}
	/**假期處理方法*/
	protected abstract boolean handleRequest(Request request);
}

第四步:好了到這裏再往下具體就是咱們的實體:班長、老師、校長了。他們有各自的假期處理方式。下邊是班長、老師、校長三個實體類:接口

班長類:

public class Monitor extends AbstractManager {

	public Monitor(int handleDay) {
		super(handleDay);
	}

	@Override
	public boolean handleRequest(Request request) {
		if(this.handleDay>=request.getDays()){
			System.out.println("班長:假期請求批准了");
			return true;
		}else{
			System.out.println("班長:沒有權限,請老師批准");
			return false;
		}
	}
}

老師類:

public class Teacher extends AbstractManager {

	public Teacher(int handleDay) {
		super(handleDay);
	}

	@Override
	protected boolean handleRequest(Request request) {
		if(this.handleDay>=request.getDays()){
			System.out.println("老師:假期請求批准了");
			return true;
		}else{
			System.out.println("老師:沒有權限,讓校長批准");
			return false;
		}
	}
}

校長類:

public class SchoolMaster extends AbstractManager {

	public SchoolMaster(int handleDay) {
		super(handleDay);
	}

	@Override
	protected boolean handleRequest(Request request) {
		if(this.handleDay>=request.getDays()){
			System.out.println("校長:假期請求批准了");
			return true;
		}else{
			System.out.println("校長:沒有權限,咱們開會商量一下");
			return false;
		}
	}
}

第五步:咱們以Client爲學生作假期的請求申請,看看Client的代碼:

public class Client {
	
	public static void main(String[] args) {

		Request request = new Request();
		request.setName("小李");
		request.setDays(6);
		request.setDate(new Date());
		request.setCause("不舒服");
		
		IManager monitor = new Monitor(1);
		IManager teacher = new Teacher(3);
		IManager master = new SchoolMaster(5);
		
		monitor.setLeader(teacher);
		teacher.setLeader(master);
		
		monitor.process(request);
	}

}

到這裏整個流程結束了。這就是咱們從抽象一步步走向具體的過程。聰明的你可能已經看出代碼使用的什麼設計模式。就是責任鏈模式。但這裏有你更應該注意的一個設計模式-------模板方法模式。

   在AbstractManager的process方法中咱們用了final修飾,就是不讓子類重寫此方法,由於客戶端就是調用此方法來完成處理流程的,這是一個模板方法,在模板方法裏咱們調用了抽象方法handleRequest()。而handleRequest則是根據具體的領導具體實現。

   模板方法能夠說是無處不在,好比servlet的service方法,若是你讀一些開源項目,會發現更多的模板方法,因此掌握此模式絕對是有必要的。而模板方法模式就是將相同的處理流程提取到了抽象類中,具體處理方式則由子類來實現。因此一切還要從抽象開始。

相關文章
相關標籤/搜索