1,為什麼要使用職責鏈設計模式
如果我們現在有一個需求,一個人他生了病,這個病要在三級醫院才能看,但是這個病人並不清楚,就先去了一級醫院,一級醫院的醫生告訴他你的病要去二級醫院看,二級醫院也告訴他
你的病我這裡看不了,你要去三級醫院才能看,最後他去三級醫院把病看好了.
這個過程直接寫成代碼:
class Patient{//病情等級public final static int PATIENTTYPEONE = 0;public final static int PATIENTTYPETWO = 1;public final static int PATIENTTYPETHREE = 2;private int patientType = 0;public Patient(int patientType) throws Exception{if(patientType < 0 || patientType > 2){throw new Exception("類型錯誤");}this.patientType = patientType;}public int getPatientType() {return patientType;}}class Hospital{public void seeDoctor(Patient patient){switch(patient.getPatientType()){case Patient.PATIENTTYPEONE:System.out.println("一級Hospital看病");break;case Patient.PATIENTTYPETWO:System.out.println("二級Hospital看病");break;case Patient.PATIENTTYPETHREE:System.out.println("三級Hospital看病");break;}}}public class Main {public static void main(String[] args) throws Exception{Patient patient = new Patient(Patient.PATIENTTYPETHREE);Hospital hospital = new Hospital();hospital.seeDoctor(patient);}}
Hospital類中的seeDoctor的責任太多違背了單一職責的原則,如果我們要去增加另外等級的醫院(現在醫院只有三級的劃分,不過這裡只做假設),這時我們就需要修改Hospital類,
違背了開閉原則.這麼可以考慮一下把Hospital抽象出來,然後一級Hospital,二級Hospital,三級Hospital繼承Hospital,但是子類怎麼去處理Patient?這裡我們可以這樣考慮,把
Patient先交給一級Hospital,如果一級Hospital沒有資格處理那麼就交給二級Hospital,最後不行的話就交給三級Hospital。這就是職責鏈模式。
2,什麼是職責鏈設計模式
職責鏈模式:使多個對象都有機會處理請求,從而避免請求的寄件者和接收者之間的耦合關係.將這個對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它為止.
接收者和寄件者都沒有對象的明確資訊,且鏈中的對象自己也並不知道鏈的結構.結果是職責鏈可簡化對象的相互串連,它們僅需保持一個指向後繼者的引用,而不需要保持它所有
的.
3,怎麼使用職責鏈設計模式
按照剛才的思路設計出的的UML
HospitalHandler.class
public abstract class HospitalHandler {protected HospitalHandler successor = null;//設定下一級public void setSuccessor(HospitalHandler successor){this.successor = successor;}//處理請求public abstract void HandleRequest(Patient request);}
FristLevelHospital.class
public class FristLevelHospital extends HospitalHandler{@Overridepublic void HandleRequest(Patient request) {// TODO Auto-generated method stubif(request.getPatientType() == Patient.PATIENTTYPEONE){System.out.println("一級醫院醫治病人");}else{if(successor != null){successor.HandleRequest(request);}else{System.out.println("一級醫院不能醫治病人,下級醫院未設定");}}}}
SecondLevelHospital.class
public class SecondLevelHospital extends HospitalHandler{@Overridepublic void HandleRequest(Patient request) {// TODO Auto-generated method stubif(request.getPatientType() == Patient.PATIENTTYPETWO){System.out.println("二級醫院醫治病人");}else{if(successor != null){successor.HandleRequest(request);}else{System.out.println("二級醫院不能醫治病人,下級醫院未設定");}}}}
ThirdLevelHospital.class
public class ThirdLevelHospital extends HospitalHandler{
@Override public void HandleRequest(Patient request) { // TODO Auto-generated method stub if(request.getPatientType() == Patient.PATIENTTYPETHREE){ System.out.println("三 級醫院醫治病人"); }else{ if(successor != null){ successor.HandleRequest(request); }else{ System.out.println("三 級醫院不能醫治病人,下級醫院未設定"); } } }
}
Patient.class
public class Patient {public final static int PATIENTTYPEONE = 0;public final static int PATIENTTYPETWO = 1;public final static int PATIENTTYPETHREE = 2;private int patientType = 0; public Patient(int patientType) throws Exception{if(patientType < 0 || patientType > 2){throw new Exception("type error");}this.patientType = patientType;}public int getPatientType() {return patientType;}}
Main.class
public class Main {public static void main(String [] args) throws Exception{HospitalHandler hospitalHandler1 = new FristLevelHospital();HospitalHandler hospitalHandler2 = new SecondLevelHospital();HospitalHandler hospitalHandler3 = new ThirdLevelHospital();//設定職責鏈hospitalHandler1.setSuccessor(hospitalHandler2);hospitalHandler2.setSuccessor(hospitalHandler3);hospitalHandler1.HandleRequest(new Patient(Patient.PATIENTTYPETHREE));}}
最後輸出:
三 級醫院醫治病人