属于“数据结构”模式。
动机:一个请求可能被多个对象中的一个处理处理,运行时只能有一个接收者。为解决请求发送者与接收者之间的紧耦合,使多个对象都有机会处理请求,将这些对象连成一条链,并沿着这链传递请求,直到有一个对象处理它为止。
1.问题引入:(员工的加薪申请的审批)
public class Test {
public static void main(String[] args) {
//三个管理者
Manager jingli=new Manager("刘刘");
Manager zongjian=new Manager("张张");
Manager zongjingli=new Manager("王王");
//设置小菜请求加薪100
Request request=new Request();
request.setRequestType("加薪");
request.setRequestContent("小菜请求加薪");
request.setNumber(100);
//不同的级别对小菜的请求进行审批
jingli.getResult("经理", request);
System.out.println("-------------------------------------");
zongjian.getResult("总监", request);
System.out.println("-------------------------------------");
zongjingli.getResult("总经理", request);
System.out.println();
System.out.println();
//设置小菜请假3天的请求
request.setRequestType("请假");
request.setRequestContent("小菜请假三天");
request.setNumber(3);
jingli.getResult("经理", request);
System.out.println("-------------------------------------");
zongjian.getResult("总监", request);
System.out.println("-------------------------------------");
zongjingli.getResult("总经理", request);
}
}
//申请类
class Request {
// 申请类别
private String requestType;
// 申请内容(实际没有用到)
private String requestContent;
// 申请数量
private int number;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequestContent() {
return requestContent;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
//管理者类
class Manager{
//管理者姓名
protected String name;
public Manager(String name) {
this.name = name;
}
//审批方法
public void getResult(String managerLevel,Request request) {//managerLevel是管理者的职位
System.out.println("请求类别:"+request.getRequestType()+" 请求数量:"+request.getNumber());
if(managerLevel.equals("经理")) {
if(request.getRequestType().equals("请假")&&request.getNumber()<=2) {
System.out.println("请假天数<=2,被经理批准。");
}else {
System.out.println("经理无权批准。");
}
}else if(managerLevel.equals("总监")) {
if(request.getRequestType().equals("请假")&&request.getNumber()<=5) {
System.out.println("请假天数<=5,被总监批准。");
}else {
System.out.println("总监无权批准。");
}
}else if(managerLevel.equals("总经理")) {
if(request.getRequestType().equals("请假")) {
System.out.print("请假被总经理批准。");
}else if(request.getRequestType().equals("加薪")&&request.getNumber()<=500) {
System.out.println("加薪<=500,被总经理批准。");
}else {
System.out.println("加新>500,总经理无权批准。");
}
}
}
}
缺点:Manager类的getResult()方法太长、有太多分支,违背了单一职责原则和开放封闭原则。
2.解决:设置管理者基类,且各个具体管理者之间有关系可以实现上报
public class Test {
public static void main(String[] args) {
// 三个管理者
CommonManager jingli = new CommonManager("刘刘");
MajorManager zongjian = new MajorManager("张张");
GenerManager zongjingli = new GenerManager("王王");
// 设置小菜请求加薪100
Request request = new Request();
request.setRequestType("加薪");
request.setRequestContent("小菜请求加薪");
request.setNumber(100);
// 不同的级别对小菜的请求进行审批
jingli.requestApplications(request);
System.out.println("-------------------------------------");
zongjian.requestApplications(request);
System.out.println("-------------------------------------");
zongjingli.requestApplications(request);
System.out.println();
System.out.println();
// 设置小菜请假3天的请求
request.setRequestType("请假");
request.setRequestContent("小菜请假三天");
request.setNumber(3);
jingli.requestApplications(request);
System.out.println("-------------------------------------");
zongjian.requestApplications(request);
System.out.println("-------------------------------------");
zongjingli.requestApplications(request);
}
}
//申请类
class Request {
// 申请类别
private String requestType;
// 申请内容(实际没有用到)
private String requestContent;
// 申请数量
private int number;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequestContent() {
return requestContent;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
//管理者基类
abstract class Manager {
// 管理者姓名
protected String name;
// 管理者上级
protected Manager superior;
public Manager(String name) {
super();
this.name = name;
}
public void setSuperior(Manager superior) {
this.superior = superior;
}
public abstract void requestApplications(Request request);
}
//经理类(具体管理者)
class CommonManager extends Manager{
public CommonManager(String name) {
super(name);
}
public void requestApplications(Request request) {
if(request.getRequestType().equals("请假")&&request.getNumber()<=2) {
System.out.println(name+":"+request.getRequestContent()+" 数量"+request.getNumber()+" 被批准。");
}else {
if(superior!=null) {
superior.requestApplications(request);
}
}
}
}
//总监类(具体管理者)
class MajorManager extends Manager{
public MajorManager(String name) {
super(name);
}
public void requestApplications(Request request) {
if(request.getRequestType().equals("请假")&&request.getNumber()<=5) {
System.out.println(name+":"+request.getRequestContent()+" 数量"+request.getNumber()+" 被批准。");
}else {
if(superior!=null) {
superior.requestApplications(request);
}
}
}
}
//总经理类(具体管理者)
class GenerManager extends Manager{
public GenerManager(String name) {
super(name);
}
public void requestApplications(Request request) {
if(request.getRequestType().equals("请假")) {
System.out.println(name+":"+request.getRequestContent()+" 数量"+request.getNumber()+" 被批准。");
}else if(request.getRequestType().equals("加薪")&&request.getNumber()<=500) {
System.out.println(name+":"+request.getRequestContent()+" 数量"+request.getNumber()+" 被批准。");
}else {
System.out.println(name+":"+request.getRequestContent()+" 数量"+request.getNumber()+" 再说吧。");
}
}
}
3.职责链模式:
发出请求的客户端并不知道那个对象会最终处理这个请求。
public class Test {
public static void main(String[] args) {
//定义3个审批人
Handler h1=new ConcreteHandler1();
h1.setName("审批人1");
Handler h2=new ConcreteHandler2();
h2.setName("审批人2");
Handler h3=new ConcreteHandler3();
h3.setName("审批人3");
//设置审批人的下一个审批人
h1.setSuccessor(h2);
h2.setSuccessor(h3);
int[] requests= {2,5,14,22,18,3,27,20};
for(int i=0;i<requests.length;i++) {
//全都是从审批人1开始
h1.handleRequest(requests[i]);
}
}
}
abstract class Handler {
protected String name;
// 继任者
protected Handler successor;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
//具体处理者类1
class ConcreteHandler1 extends Handler{
public void handleRequest(int request) {
if(request>=0&&request<10) {
System.out.println(name+"处理请求"+request);
}else if(successor!=null) {
successor.handleRequest(request);
}
}
}
//具体处理者类2
class ConcreteHandler2 extends Handler{
public void handleRequest(int request) {
if(request>=10&&request<20) {
System.out.println(name+"处理请求"+request);
}else if(successor!=null) {
successor.handleRequest(request);
}
}
}
//具体处理者类3
class ConcreteHandler3 extends Handler{
public void handleRequest(int request) {
if(request>=20&&request<30) {
System.out.println(name+"处理请求"+request);
}else if(successor!=null) {
successor.handleRequest(request);
}
}
}
优点:
请求是沿着链传递直至有一个ConcreteHandler对象负责处理它。请求者不用管该请求由哪个对象处理。
链中的对象也不知道链的结构,简化了对象的相互连接。
缺点:产生很多细粒度的对象;有的请求到最后也不能被处理。
本质:分离职责,动态耦合。