中國古代對婦女制定了“三從四德”的道德規範,“三從”是指“未嫁從父、既嫁從夫、夫
死從子”。也就是說,一位女性在結婚之前要聽從於父親,結婚之後要聽從於丈夫,如果丈
夫死了還要聽從於兒子。舉例來說,如果一位女性要出去逛街,在她出嫁前必須徵得父親的
同意,出嫁之後必須獲得丈夫的許可,那丈夫死了怎麼辦?那就得問問兒子是否允許自己出
去逛街。估計你接下來馬上要問:“要是沒有兒子怎麼辦?”那就請示小叔子、侄子等。在父
系社會中,婦女只佔從屬地位,現在想想中國古代的婦女還是挺悲慘的,連逛街都要多番請
示。作爲父親、丈夫或兒子,只有兩種選擇:要不承擔起責任來,允許她或不允許她逛街;
要不就讓她請示下一個人,這是整個社會體系的約束,應用到我們項目中就是業務規則。下
面來看如何通過程序來實現“三從”,需求很簡單:通過程序描述一下古代婦女的“三從”制
度。好,我們先來看類圖,如圖
類圖非常簡單,IHandler是三個有決策權對象的接口,IWomen是女性的代碼,其實現也
非常簡單
package ZeRenLianP;
public interface IWomen {
/**
* 一個是取得當前的個人狀況getType,通過返回值決定是結婚了還
是沒結婚、丈夫是否在世等
* @return
*/
public int getType();
/**
* 方法getRequest是要請示的內容,要出去逛街還是吃
飯
* @return
*/
public String getRequest();
}
package ZeRenLianP;
public class Women implements IWomen {
/**
* 通過一個int類型的參數來描述婦女的個人狀況
* 1--未出嫁
* 2--出嫁
* 3--夫死
* @return
*/
private int type = 0;
private String request = "";
public Women(int type,String request){
this.type = type;
this.request = request;
}
@Override
public int getType() {
return this.type;
}
@Override
public String getRequest() {
return this.request;
}
}
package ZeRenLianP;
public interface IHandler {
public void HandleMessage(Women women);
}
package ZeRenLianP;
public class Father implements IHandler {
@Override
public void HandleMessage(Women women) {
System.out.println("女兒的請示是:"+women.getRequest());
System.out.println("父親的答覆是:同意");
}
}
package ZeRenLianP;
public class Husband implements IHandler {
@Override
public void HandleMessage(Women women) {
System.out.println("妻子的請示是:"+women.getRequest());
System.out.println("丈夫的答覆是:同意");
}
}
package ZeRenLianP;
public class Son implements IHandler {
@Override
public void HandleMessage(Women women) {
System.out.println("母親的請示是:"+women.getRequest());
System.out.println("兒子的答覆是:同意");
}
}
package ZeRenLianP;
import java.util.ArrayList;
import java.util.Random;
public class Client {
public static void main(String[] args) {
Random random = new Random();
ArrayList<Women> womenArrayList =new ArrayList<>();
for (int i = 0; i<5 ; i++){
womenArrayList.add(new Women(random.nextInt(4),"guangjie"));
}
IHandler father = new Father();
IHandler husband = new Husband();
IHandler son = new Son();
for (Women women:womenArrayList){
if(women.getType() ==1){ //未結婚少女,請示父親
System.out.println("\n--------女兒向父親請示-------");
father.HandleMessage(women);
}else if(women.getType() ==2){ //已婚少婦,請示丈夫
System.out.println("\n--------妻子向丈夫請示-------");
husband.HandleMessage(women);
}else if(women.getType() == 3){ //母親請示兒子
System.out.println("\n--------母親向兒子請示-------");
son.HandleMessage(women);
}else{
//暫時什麼也不做
}
}
}
}
代碼有以下幾個問題:
● 職責界定不清晰
對女兒提出的請示,應該在父親類中做出決定,父親有責任、有義務處理女兒的請示,
因此Father類應該是知道女兒的請求自己處理,而不是在Client類中進行組裝出來,也就是說
原本應該是父親這個類做的事情拋給了其他類進行處理,不應該是這樣的。
● 代碼臃腫
我們在Client類中寫了if...else的判斷條件,而且能隨着能處理該類型的請示人員越
多,if...else的判斷就越多,想想看,臃腫的條件判斷還怎麼有可讀性?!
● 耦合過重
這是什麼意思呢,我們要根據Women的type來決定使用IHandler的那個實現類來處理請
求。有一個問題是:如果IHandler的實現類繼續擴展怎麼辦?修改Client類?與開閉原則違背
了!
● 異常情況欠考慮
妻子只能向丈夫請示嗎?如果妻子(比如一個現代女性穿越到古代了,不懂什麼“三從
四德”)向自己的父親請示了,父親應該做何處理?我們的程序上可沒有體現出來,邏輯失
敗了!
可以抽象成這樣一個結構,女性的請求先發送到父親類,父親類一看是自己要處理的,就
作出迴應處理,如果女兒已經出嫁了,那就要把這個請求轉發到女婿來處理,那女婿一旦去
天國報道了,那就由兒子來處理這個請求。
package ZeRenLianP;
public abstract class Handle {
public final static int FATHER_LEVEL_REQUEST = 1;
public final static int HUSBAND_LEVEL_REQUEST = 2;
public final static int SON_LEVEL_REQUEST = 3;
//能處理的級別
private int level =0;
//責任傳遞,下一個人責任人是誰
private Handle nextHandler;
//每個類都要說明一下自己能處理哪些請求
public Handle(int _level){
this.level = _level;
}
//一個女性(女兒、妻子或者是母親)要求逛街,你要處理這個請求
public final void HandleMessage(Women women){
if (women.getType() == this.level){
this.response(women);
}else {
if (this.nextHandler != null){
this.nextHandler.HandleMessage(women);
}else {
System.out.println("沒有人了,不同意");
}
}
}
/**
* 如果不屬於你處理的請求,你應該讓她找下一個環節的人,如女兒出嫁了,
* 還向父親請示是否可以逛街,那父親就應該告訴女兒,應該找丈夫請示
* @param
*/
public void setNext(Handle handle){
this.nextHandler = handle;
}
protected abstract void response(IWomen w);
}
package ZeRenLianP;
public class Father extends Handle {
public Father(){
super(Handle.FATHER_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("--------女兒向父親請示-------");
System.out.println(women.getRequest());
System.out.println("父親的答覆是:同意\n");
}
}
package ZeRenLianP;
public class Husband extends Handle {
public Husband(){
super(Handle.HUSBAND_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("--------妻子向丈夫請示-------");
System.out.println(women.getRequest());
System.out.println("丈夫的答覆是:同意\n");
}
}
package ZeRenLianP;
public class Son extends Handle {
public Son(){
super(Handle.SON_LEVEL_REQUEST);
}
@Override
protected void response(IWomen women) {
System.out.println("--------母親向兒子請示-------");
System.out.println(women.getRequest());
System.out.println("兒子的答覆是:同意\n");
}
}
package ZeRenLianP;
public class Women implements IWomen {
/**
* 通過一個int類型的參數來描述婦女的個人狀況
* 1--未出嫁
* 2--出嫁
* 3--夫死
* @return
*/
private int type = 0;
private String request = "";
public Women(int type,String request){
this.type = type;
//this.request = request;
switch (type){
case 1:
this.request = "女兒的請求是:" + request;
break;
case 2:
this.request = "妻子的請求是:" + request;
break;
case 3:
this.request = "母親的請求是:" + request;
}
}
@Override
public int getType() {
return this.type;
}
@Override
public String getRequest() {
return this.request;
}
}
package ZeRenLianP;
import java.util.ArrayList;
import java.util.Random;
public class Client1 {
public static void main(String[] args) {
//隨機挑選幾個女性
Random rand = new Random();
ArrayList<Women> arrayList = new ArrayList();
for(int i=0;i<5;i++){
arrayList.add(new Women(rand.nextInt(4),"我要出去逛街"));
}
//定義三個請示對象
Handle father = new Father();
Handle husband = new Husband();
Handle son = new Son();
//設置請示順序
father.setNext(husband);
husband.setNext(son);
for (Women women:arrayList){
father.HandleMessage(women);
}
}
}
責任鏈模式定義如下:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to
handle the request.Chain the receiving objects and pass the request along the chain until an object
handles it.(使多個對象都有機會處理請求,從而避免了請求的發送者和接受者之間的耦合關
系。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它爲止。)
抽象的處理者實現三個職責:一是定義一個請求的處理方法handleMessage,唯一對外開
放的方法;二是定義一個鏈的編排方法setNext,設置下一個處理者;三是定義了具體的請求
者必須實現的兩個方法:定義自己能夠處理的級別getHandlerLevel和具體的處理任務echo。