职责链模式
题目
假设某公司的订单业务处理流程如下: 当有一笔订单进来,会先在后台通过初审人员进行审批,初审不通过,订单流程结束。初审通过以后,会转给终审人员进行审批,不通过,流程结束;通过,流转到财务人员进行处理。请用职责链模式模拟该场景。
1、画出UML图描述出相应的角色。
2、给出Java程序代码,程序代码有恰当的注释。
代码
// 抽象处理者角色
abstract class OrderHandler {
protected OrderHandler successor; // 下一个处理者
public void setSuccessor(OrderHandler handler) {
this.successor = handler;
}
public abstract boolean handleOrder(Order order);
}
// 具体处理者角色:初审人员
class FirstApprover extends OrderHandler {
@Override
public boolean handleOrder(Order order) {
if (order.getPrice() < 1000) { // 初审条件
System.out.println("初审通过");
if (successor != null) { // 转交给下一个处理者
return successor.handleOrder(order);
}
return true;
} else {
System.out.println("初审不通过");
return false;
}
}
}
// 具体处理者角色:终审人员
class FinalApprover extends OrderHandler {
@Override
public boolean handleOrder(Order order) {
if (order.getPrice() < 5000) { // 终审条件
System.out.println("终审通过");
if (successor != null) { // 转交给下一个处理者
return successor.handleOrder(order);
}
return true;
} else {
System.out.println("终审不通过");
return false;
}
}
}
// 具体处理者角色:财务人员
class FinancialOfficer extends OrderHandler {
@Override
public boolean handleOrder(Order order) {
System.out.println("财务处理订单:" + order.getOrderNumber());
return true;
}
}
// 订单类
class Order {
private int orderNumber;
private double price;
public Order(int orderNumber, double price) {
this.orderNumber = orderNumber;
this.price = price;
}
public int getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(int orderNumber) {
this.orderNumber = orderNumber;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
// 测试代码
public class Client {
public static void main(String[] args) {
OrderHandler firstApprover = new FirstApprover();
OrderHandler finalApprover = new FinalApprover();
OrderHandler financialOfficer = new FinancialOfficer();
firstApprover.setSuccessor(finalApprover);
finalApprover.setSuccessor(financialOfficer);
// 模拟不通过的情况
Order order1 = new Order(1, 3000);
firstApprover.handleOrder(order1);
// 模拟通过的情况
Order order2 = new Order(2, 800);
firstApprover.handleOrder(order2);
}
}
命令模式
题目
为了用户使用方便,某系统提供了一系列功能键,用户可以自定义功能键的功能,如功能键FunctionButton可以用于退出系统(SystemExitClass),也可以用于打开帮助界面(DisplayHelpClass)。用户可以通过修改配置文件来改变功能键的用途,现使用命令模式来设计该系统,使得功能键类与功能类之间解耦,相同的功能键可以对应不同的功能。
1、画出UML图描述相应的角色。
2、给出Java程序代码,程序代码有恰当的注释。
代码
package command;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
// 调用者角色:功能键类
class FunctionButton {
private Command command; // 命令对象
public void setCommand(Command command) {
this.command = command;
}
public void onClick() {
command.execute();
}
}
// 抽象命令角色
interface Command {
void execute();
}
class SystemExitClass {
public void exit() {
System.out.println("正在退出系统...");
System.exit(0); // 强制退出程序
}
}
class DisplayHelpClass {
public void display() {
System.out.println("正在显示帮助界面...");
}
}
// 具体命令角色:退出系统
class SystemExitCommand implements Command {
protected SystemExitClass systemExitClass;
@Override
public void execute() {
systemExitClass.exit();
}
}
// 具体命令角色:显示帮助界面
class DisplayHelpCommand implements Command {
protected DisplayHelpClass displayHelpClass;
@Override
public void execute() {
displayHelpClass.display();
}
}
// 测试代码
public class Client {
public static void main(String[] args) {
// 读取配置文件,生成命令对象
String sysExitCmdClassName = "SystemExitCommand";
Command sysExitCmd = (Command) XMLUtil.getBean(sysExitCmdClassName);
String displayHelpCmdClassName = "DisplayHelpCommand";
Command displayHelpCmd = (Command) XMLUtil.getBean(displayHelpCmdClassName);
// 创建两个功能键对象并设置命令对象
FunctionButton button1 = new FunctionButton();
button1.setCommand(sysExitCmd);
FunctionButton button2 = new FunctionButton();
button2.setCommand(displayHelpCmd);
// 模拟用户点击功能键
button1.onClick(); // 点击退出系统
button2.onClick(); // 点击显示帮助界面
}
}
class XMLUtil
{
public static Object getBean(String args)
{
try
{
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("./command.xml"));
NodeList nl=null;
Node classNode=null;
String cName=null;
nl = doc.getElementsByTagName("className");
if(args.equals("SystemExitCommand"))
{
classNode=nl.item(0).getFirstChild();
}
else if(args.equals("DisplayHelpCommand"))
{
classNode=nl.item(1).getFirstChild();
}
cName=classNode.getNodeValue();
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
XML文件:
<?xml version="1.0"?>
<config>
<className>command.SystemExitCommand</className>
<className>command.DisplayHelpCommand</className>
</config>