中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父、既嫁从夫、 夫死从子”,在父系社会中,妇女只占从属地位,现在想想中国的妇女还是比较悲 惨的,逛个街还要请示来请示去,而且作为 父亲、丈夫、儿子 只有两种选择:要不承担起责任来告诉她允 许或不允许逛街,要不就让她请示下一个人 ,这是整个社会体 系的约束。
通过程序描述一下古代妇女的“三从 ”制度,好我们先看类图:
publicinterface IWomen {
//获得个人状况
publicint getType();
//获得个人请示,你要干什么?出去逛街?约会?还是看电影
public String getRequest();
}
女性就两个参数,一个是当前的个人状况, 是结婚了呢还是没结婚,丈夫有没有去世,另外一个是要请示的内容,要出去逛街呀还是吃饭,我们看实现类:
publicclass Women implements IWomen{
/* * 通过一个int类型的参数来描述妇女的个人状况 * 1---未出嫁 * 2---出嫁 * 3---夫死 */
privateinttype=0;
//妇女的请示
private String request = "";
//构造函数传递过来请求
public Women(int _type,String _request){
this.type = _type;
this.request = _request;
}
//获得自己的状况
publicint getType(){
returnthis.type;
}
//获得妇女的请求
public String getRequest(){
returnthis.request;
}
}
我们再来看有处理权的人员接口:
public interface IHandler {
//一个女性(女儿,妻子或者是母亲)要求逛街,你要处理这个请求
public void HandleMessage(IWomen women);
}
父亲、丈夫、儿子都是这个IHandler接口的实现者:
父亲
publicclass Father implements IHandler {
//未出嫁女儿来请示父亲
publicvoid HandleMessage(IWomen women) {
System.out. println("女儿的请示是:"+women.getRequest());
System.out.println("父亲的答复是:同意");
}
}
丈夫类
publicclass Husband implements IHandler {
//妻子向丈夫请示
publicvoid HandleMessage(IWomen women) {
System.out. println("妻子的请示是:"+women. getRequest());
System.out. println("丈夫的答复是:同意");
}
}
儿子类
publicclass Son implements IHandler {
//目前向儿子请示
public void HandleMessage(IWomen women) {
System.out. println("母亲的请示是:"+women. getRequest());
System.out. println("儿子的答复是:同意");
}
}
这三个类非常非常的简单,就一个方法,处理女儿、妻子、母亲提出的请求,再来看Client是怎么组装的:
public class Client {
public static void main(String[] args) {
//随机挑选几个女性
Random rand = new Random();
ArrayList<IWomen> arrayList = new ArrayList();
for(int i=0;i<5;i++){
arrayList.add(new Women(rand.nextInt(4),"我要出去逛街"));
}
//定义三个请示对象
IHandler father = new Father();
IHandler husband = new Husband();
IHandler son = new Son();
for(IWomen women:arrayList){
if(women.getType() ==1){
//未结婚少女,请示父亲
System.out.println("\n--------女儿向父亲请示-------");
father.HandleMessage(women);
}elseif(women.getType()==2){
//已婚少妇,请示丈夫
System.out.println("\n--------妻子向丈夫请示-------");
husband.HandleMessage(women);
}elseif(women.getType() == 3){
//母亲请示儿子
System.out.println("\n--------母亲向儿子请示-------");
son.HandleMessage (women);
}else{
//暂时啥也不做
}
}
}
}
运行结果如下:
--------女儿向父亲请示------- 女儿的请示是:我要出去逛街
父亲的答复是:同意
--------妻子向丈夫请示------- 妻子的请示是:我要出去逛街
丈夫的答复是:同意
--------妻子向丈夫请示------- 妻子的请示是:我要出去逛街
丈夫的答复是:同意
--------女儿向父亲请示------- 女儿的请示是:我要出去逛街
父亲的答复是:同意
这段代码有以下几个问题:
失去面向对象的意义。对女儿提出的请示,应该在父亲类中做出决定,父亲这个类应该是知道女儿的请求应该自己处理,而不是在 Client 类中进行组装出来,也就是说原本应该是父亲这个类做的事情抛给了其他类进行处理;耦合过重。这个什么意思呢,我们要根据 Women 的 type 来决定使用 IHandler 的那个实现类来处理请求,我问你,如果 IHanlder 的实现类继续扩展怎么办?修改 Client 类?与开闭原则违背喽!
异常情况没有考虑。妻子只能向丈夫请示吗?如果妻子向自己的父亲请示了,父亲应该做何处理?我们的程序上可没有体现出来。
既然有这么多的问题,那我们要想办法来解决这些问题,我们可以抽象成这样一个结构,女性的请求先发送到父亲类,父亲类一看是自己要处理的,就回应处理,如果女儿已经出嫁了,那就要把这个请求转发到女婿来处理,那女婿一旦去天国报道了,那就由儿子来处理这个请求,类似于这样请求:
父亲、丈夫、儿子每个节点有两个选择:要么承担责任,做出回复;要么把请求转发到后序环节。
三个实现类 Father、Husband、Son 只要实现构造函数和父类的中抽象方法就可以了,具体怎么处理这些请求,都已经转移到了 Hanlder 抽象类中:
public abstract class Handler {
//能处理的级别
private int level =0;
//责任传递,下一个人责任人是谁
private Handler nextHanlder;
//每个类都要说明一下自己能处理哪些请求
public Handler(int _level){
this.level = _level;
}
//一个女性(女儿,妻子或者是母亲)要求逛街,你要处理这个请求
public final void HandleMessage(IWomen women){
if(women.getType() == this.level){
this.response(women);
}else{
if(this.nextHanlder != null){ //有后续环节,才把请求往后递送
this.nextHanlder.HandleMessage(women);
}else{ //已经没有后续处理人了,不用处理了
System.out.println("-----------没地方请示了,不做处理!---------\n");
}
}
}
/*
* 如果你属于你处理的返回,你应该让她找下一个环节的人,比如
* 女儿出嫁了,还向父亲请示是否可以逛街,那父亲就应该告诉女儿,应该找丈夫请示
*/
public void setNext(Handler _handler){
this.nextHanlder = _handler;
}
//有请示那当然要回应
public abstract void response(IWomen women);
}
其实在这里也用到模版方法模式,在模版方法中判断请求的级别和当前能够处理的级别,如果相同则调用基本方法,做出反馈;如果不相等,则传递到下一个环节,由下一环节做出回应。基本方法 response 要各个实现类都要实现:
父亲:
public class Father extends Handler {
//父亲只处理女儿的请求
public Father(){
super(1);
}
//父亲的答复
@Override
public void response(IWomen women) {
System.out.println("--------女儿向父亲请示-------");
System.out.println(women.getRequest());
System.out.println("父亲的答复是:同意\n");
}
}
丈夫:
public class Husband extends Handler {
//丈夫只处理妻子的请求
public Husband(){
super(2);
}
//丈夫请示的答复
@Override
public void response(IWomen women) {
System.out.println("--------妻子向丈夫请示-------");
System.out.println(women.getRequest());
System.out.println("丈夫的答复是:同意\n");
}
}
儿子;
public class Son extends Handler {
//儿子只处理母亲的请求
public Son(){
super(3);
}
//儿子的答复
public void response(IWomen women) {
System.out.println("--------母亲向儿子请示-------");
System.out.println(women.getRequest());
System.out.println("儿子的答复是:同意\n");
}
}
Women 类的接口没有任何变化,实现类少有变化:
public class Women implements IWomen{
/*
* 通过一个int类型的参数来描述妇女的个人状况
* 1---未出嫁
* 2---出嫁
* 3---夫死
*/
private int type=0;
//妇女的请示
private String request = "";
//构造函数传递过来请求
public Women(int _type,String _request){
this.type = _type;
//为了显示好看点,我在这里做了点处理
switch(this.type){
case 1:
this.request = "女儿的请求是:" + _request;
break;
case 2:
this.request = "妻子的请求是:" + _request;
break;
case 3:
this.request = "母亲的请求是:" + _request;
break;
}
}
//获得自己的状况
public int getType(){
return this.type;
}
//获得妇女的请求
public String getRequest(){
return this.request;
}
}
我们再来看 Client 类是怎么描述古代这一个礼节的:
public class Client {public static void main(String[] args) {
//随机挑选几个女性
Random rand = new Random();
ArrayList arrayList = new ArrayList();
for(int i=0;i<5;i++){
arrayList.add(new Women(rand.nextInt(4),"我要出去逛街"));
}
//定义三个请示对象
Handler father = new Father();
Handler husband = new Husband();
Handler son = new Son();
//设置请示顺序
father.setNext(husband);
husband.setNext(son);
for(IWomen women:arrayList){
father.HandleMessage(women);
}
}
运行结果如下:
--------妻子向丈夫请示-------
妻子的请求是:我要出去逛街
丈夫的答复是:同意
--------女儿向父亲请示-------
女儿的请求是:我要出去逛街
父亲的答复是:同意
--------母亲向儿子请示-------
母亲的请求是:我要出去逛街
儿子的答复是:同意
--------妻子向丈夫请示-------
妻子的请求是:我要出去逛街
丈夫的答复是:同意
--------母亲向儿子请示-------
母亲的请求是:我要出去逛街
儿子的答复是:同意
是责任链模式通用类图: