readme

Java面向对象程序设计-答疑(二)

需求分析

在上个项目中我们实现了学生提问,教授答疑的功能。可是,在实际应用过程中,我们发现学生提问的数量很多,教授可能无法即时回复每一个问题。因此,我们将进一步改进答疑的流程。在答疑的环节中,我们增加教学助理(Teaching Assistant, or TA)角色。当学生提出问题后,首先交由教学助理处理。如果问题较为复杂,教学助理不能处理,则再转交给教授处理。

在本项目中,我们将使用责任链模式空对象模式来实现问题解答环节。

步骤一

首先,我们在com.littlewaterdrop.qa包中创建一个新类Respondent,用于表示回答问题的人。它有一个Respondent类型的成员变量next,指向下一个处理者。类Respondent还声明了一个成员方法respond()。该方法接收一个Message类型的参数,无返回结果。respond()的方法将入参Message传递给next指向的Respondent对象处理。

public void respond(Message msg) {
    if (next != null)
        next.respond(msg);
}

我们再在com.littlewaterdrop.bean包中创建一个新类,命名为TeachingAssistant。TeachingAssistant类继承自Respondent类。并覆盖了respond()方法。

我们再将Professor类继承自Respondent类,并覆盖了respond()方法。

步骤二

我们在com.littlewaterdrop.qa包中新增一个新类RespondentSubscriber。它继承自Respondent,并实现了Subscriber接口。RespondentSubsriber类作为教授的代表,订阅Topic。当学生发布了问题之后,RespondentSubscriber会接收该问题,并将问题传递给责任链上的第一个回答者:TeachingAssistant对象。

我们还可以看到,在使用责任链模式时,为了确保每一个问题都会有相应的对象处理。一般来说,责任链的最后一个对象会处理所有的问题。所以,在本项目,我们将使用空对象模式来创建最后一个消息处理对象。当该对象接收到问题时,它记录一条消息,说明"该消息没有被任何人处理。"。该空对象可按照如下方式创建。

Respondent chainOfRespondents = new Respondent() {
    @Override
    public void respond(Message msg) {
        System.err.println("The message " + msg + " is not processed by anybody");
    }
};

所以,在这条责任链上,有四个对象。第一个对象是RespondentSubscriber,它作为一个Subscriber对象,从Topic中接收问题,并转发给责任链上的第二个对象。第二个对象是TeachingAssistant对象,用于解答问题。第三个对象为Professor对象,用于解答问题。第四个对象为上述的"空对象",用于记录无人处理的问题。因此,这条回答问题的责任链可以按照如下方式构成。当然,学员也可以使用建造者模式或者工厂模式创建。

Professor aProfessor = ProfessorFactory.newProfessor("PCS0001", "Thomas", MajorEnum.ComputerScience, "thomas@littlewaterdrop.com");
Respondent chainOfRespondents = new Respondent() {
    @Override
    public void respond(Message msg) {
        System.err.println("The message " + msg + " is not processed by anybody");
    }
};
aProfessor.setNext(chainOfRespondents);
chainOfRespondents = aProfessor;
chainOfRespondents = new TeachingAssistant(chainOfRespondents);
chainOfRespondents = new RespondentSubscriber(chainOfRespondents);

步骤三

最后,我们假设TeachingAssitant只能回答简单问题,即问题的type()为MessageType.SIMPLE的对象。当遇到复杂问题时,交由责任链上的下一个对象回答。我们假设教授能够回答所有问题。我们在下一个项目中进一步扩展回答问题的流程。

public class TeachingAssistant extends Respondent {
    @Override
    public void respond(Message msg) {
        if (MessageType.SIMPLE.equals(msg.type())) {
            System.out.println("I can process this message");
        } else {
            super.respond(msg);
        }
    }
}

public class Professor extends Respondent implements Assignee, Subscriber {
    @Override
    public void onMessage(Message msg) {
        System.out.println("I can help on this message");
    }
}

参考文档

  1. Java编程语言的基本概念
  2. 设计模式
  3. Maven工程管理工具
Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.