当前位置: 首页 > news >正文

天津设计网站北京vi设计哪家公司好

天津设计网站,北京vi设计哪家公司好,河北住房和城乡建设厅网站6,海城建设网站系列文章目录 后续补充~~~ 文章目录 一、责任链模式基础入门1.1 责任链模式的定义1.2 核心角色剖析1.2.1 抽象处理者#xff08;Handler#xff09;1.2.2 具体处理者#xff08;ConcreteHandler#xff09;1.2.3 客户端#xff08;Client#xff09; 1.3 类图结构展示 二…系列文章目录 后续补充~~~ 文章目录 一、责任链模式基础入门1.1 责任链模式的定义1.2 核心角色剖析1.2.1 抽象处理者Handler1.2.2 具体处理者ConcreteHandler1.2.3 客户端Client 1.3 类图结构展示 二、Java 代码示例解析2.1 简单示例请假审批流程2.1.1 定义抽象处理者2.1.2 具体处理者实现2.1.3 客户端调用 2.2 电商交易系统示例订单状态处理2.2.1 订单状态处理抽象类2.2.2 具体订单状态处理器2.2.3 客户端测试 三、实际使用场景深度挖掘3.1 工作流引擎中的应用3.1.1 工作流场景描述3.1.2 基于责任链模式的实现3.1.3 优势与挑战 3.2 消息处理系统中的应用3.2.1 消息处理场景分析3.2.2 消息处理责任链构建3.2.3 应用效果与优化 四、责任链模式的优势与局限4.1 显著优势4.1.1 解耦请求与处理4.1.2 增强系统灵活性4.1.3 符合单一职责原则 4.2 存在的局限性4.2.1 可能导致请求无法处理4.2.2 调试困难4.2.3 性能开销 五、责任链模式与其他设计模式的关联与区别5.1 与策略模式对比5.1.1 策略模式简介5.1.2 两者区别分析 5.2 与观察者模式对比5.2.1 观察者模式简介5.2.2 两者差异剖析 六、责任链模式的最佳实践与优化策略6.1 最佳实践建议6.1.1 合理设计责任链长度6.1.2 明确处理者职责6.1.3 处理者顺序优化 6.2 优化策略探讨6.2.1 缓存处理结果6.2.2 分拆责任链6.2.3 增加日志记录 七、总结与展望7.1 责任链模式回顾7.2 未来应用展望 一、责任链模式基础入门 1.1 责任链模式的定义 责任链模式Chain of Responsibility Pattern是一种行为型设计模式它允许你将请求沿着处理者链传递。当一个请求到达链上的某个处理者时该处理者可以选择自己处理这个请求或者将请求传递给链中的下一个处理者。这种模式将请求的发送者和接收者解耦使得系统在不影响客户端的情况下能够动态地重新组织和分配责任。 例如在一个公司的请假审批流程中员工提交请假申请后请求会先到达直属领导处。如果请假天数在直属领导的审批权限内比如 3 天以内直属领导就可以直接处理该请求如果请假天数超过了直属领导的权限直属领导会将请求传递给上级领导如部门经理由部门经理来决定是否批准。如果部门经理也无法处理例如请假时间过长超过了部门经理的审批权限则继续向上传递直到有合适的领导能够处理该请求为止。 1.2 核心角色剖析 1.2.1 抽象处理者Handler 抽象处理者是责任链模式中的抽象类或接口它定义了处理请求的接口方法通常包含一个用于处理请求的抽象方法handleRequest。同时它还维护了一个指向链中下一个处理者的引用通过这个引用处理者可以将请求传递给下一个处理者。这个引用为具体处理者提供了统一的抽象使得所有的具体处理者都能够按照相同的方式进行请求处理和传递。 以电商系统中的订单处理为例假设我们有一个抽象处理者OrderHandler它可能定义如下 public abstract class OrderHandler {// 下一个处理者protected OrderHandler nextHandler;// 设置下一个处理者public void setNextHandler(OrderHandler nextHandler) {this.nextHandler nextHandler;}// 处理订单的抽象方法public abstract void handleRequest(Order order); }在这个例子中OrderHandler定义了handleRequest方法来处理订单请求并且通过nextHandler来维护责任链的传递关系。 1.2.2 具体处理者ConcreteHandler 具体处理者是抽象处理者的子类它实现了抽象处理者中定义的处理请求的接口方法。每个具体处理者都有自己的处理逻辑和判断条件用于决定是否能够处理当前请求。如果当前具体处理者能够处理请求它就会执行相应的处理逻辑如果不能处理它会将请求传递给下一个处理者即调用下一个处理者的handleRequest方法。 例如在上述电商系统的订单处理中我们可能有具体处理者PaymentHandler来处理订单的支付逻辑 public class PaymentHandler extends OrderHandler {Overridepublic void handleRequest(Order order) {if (order.getStatus() OrderStatus.PENDING_PAYMENT) {// 处理支付逻辑System.out.println(处理订单支付 order.getOrderId());order.setStatus(OrderStatus.PAID);} else if (nextHandler! null) {// 传递给下一个处理者nextHandler.handleRequest(order);}} }在这个PaymentHandler中首先判断订单状态是否为待支付如果是则处理支付逻辑否则将订单传递给下一个处理者。 1.2.3 客户端Client 客户端是责任链模式的使用者它负责创建处理链并向链首的处理者提交请求。客户端不需要关心具体的处理过程和请求在链中的传递路径只需要知道将请求发送到链首的处理者即可。这种方式使得客户端与具体的处理者解耦提高了系统的灵活性和可维护性。 继续以上述电商系统为例客户端代码可能如下 public class Client {public static void main(String[] args) {// 创建处理者OrderHandler paymentHandler new PaymentHandler();OrderHandler shippingHandler new ShippingHandler();// 组装责任链paymentHandler.setNextHandler(shippingHandler);// 创建订单Order order new Order(1, OrderStatus.PENDING_PAYMENT);// 提交请求paymentHandler.handleRequest(order);} }在客户端代码中创建了PaymentHandler和ShippingHandler两个具体处理者并将它们组装成责任链然后将订单请求发送给PaymentHandler进行处理。 1.3 类图结构展示 下面是责任链模式的类图 在这个类图中 Handler是抽象处理者接口定义了处理请求的方法handleRequest和设置下一个处理者的方法setNextHandler。ConcreteHandler1和ConcreteHandler2是具体处理者它们实现了Handler接口并且各自维护了一个指向Handler类型的下一个处理者的引用nextHandler。Client是客户端它持有一个Handler类型的引用handler用于向责任链提交请求。Request是请求对象包含了请求的相关信息在实际应用中请求对象可能会有更多的属性和方法用于存储请求的具体内容、参数等信息。例如在一个文件上传的场景中Request对象可能包含文件名、文件大小、文件内容等属性以及获取这些属性的方法。客户端在创建请求对象时会根据具体的业务需求设置这些属性的值然后将请求对象传递给责任链中的处理者进行处理。 二、Java 代码示例解析 2.1 简单示例请假审批流程 2.1.1 定义抽象处理者 在请假审批流程中首先定义抽象处理者LeaveHandler它定义了处理请假请求的基本框架。代码如下 public abstract class LeaveHandler {// 下一个处理者protected LeaveHandler nextHandler;// 设置下一个处理者public void setNextHandler(LeaveHandler nextHandler) {this.nextHandler nextHandler;}// 处理请假请求的抽象方法public abstract void handleRequest(LeaveRequest leaveRequest); }在这段代码中LeaveHandler抽象类包含了一个nextHandler引用用于指向下一个处理者通过setNextHandler方法来设置。同时handleRequest方法是抽象的具体的处理逻辑将由具体处理者实现。这个抽象类为整个请假审批流程提供了统一的抽象使得不同的处理者能够按照相同的方式进行请求处理和传递。 2.1.2 具体处理者实现 接下来是具体处理者的实现分别有组长TeamLeader、CTO、CEO。 组长TeamLeader的实现 public class TeamLeader extends LeaveHandler {Overridepublic void handleRequest(LeaveRequest leaveRequest) {if (leaveRequest.getDays() 2) {System.out.println(组长批准了 leaveRequest.getName() 的请假申请请假天数为 leaveRequest.getDays());} else if (nextHandler! null) {nextHandler.handleRequest(leaveRequest);} else {System.out.println(请假申请未通过没有更高权限的审批人。);}} }组长TeamLeader在handleRequest方法中首先判断请假天数是否小于等于 2 天。如果是则直接批准请假申请如果不是且存在下一个处理者则将请假请求传递给下一个处理者如果不存在下一个处理者则提示请假申请未通过。 CTO 的实现 public class CTO extends LeaveHandler {Overridepublic void handleRequest(LeaveRequest leaveRequest) {if (leaveRequest.getDays() 5) {System.out.println(CTO批准了 leaveRequest.getName() 的请假申请请假天数为 leaveRequest.getDays());} else if (nextHandler! null) {nextHandler.handleRequest(leaveRequest);} else {System.out.println(请假申请未通过没有更高权限的审批人。);}} }CTO 在处理请假请求时判断请假天数是否小于等于 5 天。若满足条件则批准请假申请否则按照与组长类似的逻辑将请求传递给下一个处理者或提示申请未通过。 CEO 的实现 public class CEO extends LeaveHandler {Overridepublic void handleRequest(LeaveRequest leaveRequest) {if (leaveRequest.getDays() 5) {System.out.println(CEO批准了 leaveRequest.getName() 的请假申请请假天数为 leaveRequest.getDays());} else if (nextHandler! null) {nextHandler.handleRequest(leaveRequest);} else {System.out.println(请假申请未通过没有更高权限的审批人。);}} }CEO 负责处理请假天数大于 5 天的请假申请批准后输出相应信息否则同样进行请求传递或提示未通过。 2.1.3 客户端调用 客户端代码用于创建处理链并提交请假请求。 public class Client {public static void main(String[] args) {// 创建处理者LeaveHandler teamLeader new TeamLeader();LeaveHandler cto new CTO();LeaveHandler ceo new CEO();// 组装责任链teamLeader.setNextHandler(cto);cto.setNextHandler(ceo);// 创建请假请求LeaveRequest leaveRequest1 new LeaveRequest(张三, 1);LeaveRequest leaveRequest2 new LeaveRequest(李四, 3);LeaveRequest leaveRequest3 new LeaveRequest(王五, 7);// 提交请求teamLeader.handleRequest(leaveRequest1);teamLeader.handleRequest(leaveRequest2);teamLeader.handleRequest(leaveRequest3);} }在客户端代码中首先创建了TeamLeader、CTO和CEO三个具体处理者。然后通过setNextHandler方法将它们组装成责任链。接着创建了三个不同请假天数的请假请求leaveRequest1、leaveRequest2和leaveRequest3。最后将这些请假请求提交给责任链的起始处理者teamLeader进行处理。运行上述代码输出结果如下 组长批准了张三的请假申请请假天数为1 CTO批准了李四的请假申请请假天数为3 CEO批准了王五的请假申请请假天数为7从输出结果可以看出不同的请假请求根据请假天数被相应权限的处理者进行了审批体现了责任链模式在请假审批流程中的应用。 2.2 电商交易系统示例订单状态处理 2.2.1 订单状态处理抽象类 在电商交易系统中定义订单处理抽象类OrderHandler它是订单状态处理责任链的基础。代码如下 public abstract class OrderHandler {// 下一个处理者protected OrderHandler nextHandler;// 设置下一个处理者public void setNextHandler(OrderHandler nextHandler) {this.nextHandler nextHandler;}// 处理订单的抽象方法public abstract void handleRequest(Order order); }OrderHandler抽象类同样包含了nextHandler引用和setNextHandler方法用于构建责任链。handleRequest抽象方法负责处理订单具体的订单状态处理逻辑将由具体的订单状态处理器实现。 2.2.2 具体订单状态处理器 已支付状态处理器PaidOrderHandler public class PaidOrderHandler extends OrderHandler {Overridepublic void handleRequest(Order order) {if (order.getStatus() OrderStatus.PAID) {System.out.println(订单已支付准备发货...);// 模拟发货操作order.setStatus(OrderStatus.SHIPPED);if (nextHandler! null) {nextHandler.handleRequest(order);}} else if (nextHandler! null) {nextHandler.handleRequest(order);}} }PaidOrderHandler在handleRequest方法中首先判断订单状态是否为已支付。如果是则进行发货相关的操作如输出提示信息并将订单状态设置为已发货然后将订单传递给下一个处理者如果订单状态不是已支付且存在下一个处理者则直接将订单传递给下一个处理者。 已发货状态处理器ShippedOrderHandler public class ShippedOrderHandler extends OrderHandler {Overridepublic void handleRequest(Order order) {if (order.getStatus() OrderStatus.SHIPPED) {System.out.println(订单已发货等待收货...);// 模拟收货操作order.setStatus(OrderStatus.RECEIVED);if (nextHandler! null) {nextHandler.handleRequest(order);}} else if (nextHandler! null) {nextHandler.handleRequest(order);}} }ShippedOrderHandler负责处理已发货状态的订单当订单状态为已发货时进行收货相关的操作并更新订单状态然后根据情况传递订单给下一个处理者。 已收货状态处理器ReceivedOrderHandler public class ReceivedOrderHandler extends OrderHandler {Overridepublic void handleRequest(Order order) {if (order.getStatus() OrderStatus.RECEIVED) {System.out.println(订单已收货交易完成。);} else if (nextHandler! null) {nextHandler.handleRequest(order);}} }ReceivedOrderHandler处理已收货状态的订单当订单状态为已收货时输出交易完成的信息。如果订单状态不是已收货且存在下一个处理者则将订单传递给下一个处理者。 2.2.3 客户端测试 客户端代码用于创建订单并处理订单状态。 public class OrderClient {public static void main(String[] args) {// 创建处理者OrderHandler paidHandler new PaidOrderHandler();OrderHandler shippedHandler new ShippedOrderHandler();OrderHandler receivedHandler new ReceivedOrderHandler();// 组装责任链paidHandler.setNextHandler(shippedHandler);shippedHandler.setNextHandler(receivedHandler);// 创建订单Order order new Order(1, OrderStatus.PAID);// 处理订单paidHandler.handleRequest(order);} }在客户端代码中创建了PaidOrderHandler、ShippedOrderHandler和ReceivedOrderHandler三个具体的订单状态处理器并将它们组装成责任链。然后创建了一个已支付状态的订单order并将其提交给责任链的起始处理者paidHandler进行处理。运行上述代码输出结果如下 订单已支付准备发货... 订单已发货等待收货... 订单已收货交易完成。从输出结果可以清晰地看到订单在不同状态下的处理流程每个处理器根据订单的当前状态进行相应的处理并将订单传递给下一个处理器直到订单处理完成。这种方式使得订单状态处理逻辑清晰各个状态的处理相互独立提高了系统的可维护性和扩展性。如果需要新增订单状态处理逻辑只需添加新的具体处理器并将其加入责任链即可而不会影响到已有的处理逻辑。 三、实际使用场景深度挖掘 3.1 工作流引擎中的应用 3.1.1 工作流场景描述 在企业的日常运营中工作流无处不在。以一个简单的采购流程为例员工首先需要提交采购申请申请中包含采购物品的详细信息如名称、数量、预计价格等。这个申请会被发送到部门经理处部门经理需要审核采购的必要性和预算合理性。如果采购金额较小在部门经理的审批权限范围内假设为 5000 元以下部门经理可以直接批准该申请若采购金额超过了部门经理的权限则申请会被传递给财务部门进行进一步审核。财务部门主要审查公司的资金状况是否允许此次采购以及采购预算是否符合公司的财务规划。若财务部门审核通过申请可能会继续流转到更高层的领导如总经理处总经理从公司整体战略和资源配置的角度来决定是否批准该采购申请。 在这个过程中每一个审批环节都可以看作是责任链上的一个节点每个节点都有自己的处理逻辑和判断条件。这种场景非常适合使用责任链模式因为它能够将不同的审批逻辑解耦使得系统在面对业务规则变化时更加灵活。例如如果公司调整了审批权限只需要在责任链的组装环节进行相应的修改而不需要对每个审批节点的代码进行大量改动。同时新的审批环节也可以很容易地添加到责任链中满足企业不断变化的业务需求。 3.1.2 基于责任链模式的实现 下面展示如何在工作流引擎中使用责任链模式实现上述采购审批流程。 首先定义抽象处理者Approver public abstract class Approver {protected Approver nextApprover;public void setNextApprover(Approver nextApprover) {this.nextApprover nextApprover;}public abstract void approve(PurchaseRequest request); }在这个抽象类中nextApprover用于指向下一个审批者approve方法是抽象的具体的审批逻辑将由子类实现。 然后实现具体处理者如DepartmentManager部门经理、FinanceDepartment财务部门和GeneralManager总经理 public class DepartmentManager extends Approver {Overridepublic void approve(PurchaseRequest request) {if (request.getAmount() 5000) {System.out.println(部门经理批准采购申请采购金额 request.getAmount());} else if (nextApprover! null) {nextApprover.approve(request);}} }public class FinanceDepartment extends Approver {Overridepublic void approve(PurchaseRequest request) {// 模拟财务部门的审核逻辑如检查资金状况等System.out.println(财务部门审核采购申请采购金额 request.getAmount());if (nextApprover! null) {nextApprover.approve(request);}} }public class GeneralManager extends Approver {Overridepublic void approve(PurchaseRequest request) {System.out.println(总经理批准采购申请采购金额 request.getAmount());} }DepartmentManager在approve方法中判断采购金额是否小于 5000 元若是则直接批准否则将请求传递给下一个审批者。FinanceDepartment模拟了财务部门的审核逻辑然后根据情况传递请求。GeneralManager则负责最终的审批。 最后在客户端组装责任链并提交采购申请 public class Client {public static void main(String[] args) {Approver departmentManager new DepartmentManager();Approver financeDepartment new FinanceDepartment();Approver generalManager new GeneralManager();departmentManager.setNextApprover(financeDepartment);financeDepartment.setNextApprover(generalManager);PurchaseRequest request1 new PurchaseRequest(3000);PurchaseRequest request2 new PurchaseRequest(8000);departmentManager.approve(request1);departmentManager.approve(request2);} }class PurchaseRequest {private double amount;public PurchaseRequest(double amount) {this.amount amount;}public double getAmount() {return amount;} }在客户端代码中创建了DepartmentManager、FinanceDepartment和GeneralManager三个具体审批者并将它们组装成责任链。然后创建了两个采购申请request1和request2分别提交给责任链的起始审批者departmentManager进行处理。 3.1.3 优势与挑战 在工作流引擎中使用责任链模式具有显著的优势 流程灵活配置通过责任链模式企业可以根据自身的业务规则和组织结构灵活地配置工作流的审批流程。例如当公司调整部门架构或审批权限时只需要重新组装责任链而不需要修改大量的代码。这种灵活性使得工作流引擎能够快速适应企业业务的变化。 解耦业务逻辑每个审批节点的业务逻辑相互独立一个审批节点的修改不会影响到其他节点。这降低了系统的耦合度提高了代码的可维护性和可扩展性。例如如果需要修改财务部门的审核逻辑只需要在FinanceDepartment类中进行修改而不会影响到部门经理和总经理的审批逻辑。 提高代码可读性责任链模式将复杂的工作流审批逻辑分解为多个简单的处理节点每个节点的职责单一使得代码结构更加清晰可读性更强。开发人员可以更容易地理解和维护整个工作流系统。 然而使用责任链模式也可能面临一些挑战 长流程性能问题当工作流流程较长责任链上的节点较多时请求在链上的传递可能会带来一定的性能开销。每个节点的处理都需要时间和资源随着节点数量的增加这种开销可能会变得不可忽视。例如在一个涉及多个部门和层级的复杂项目审批流程中请求可能需要经过多个审批节点的传递和处理这可能导致审批时间过长影响业务效率。 调试难度增加由于请求在责任链上的传递路径不直观当出现问题时调试和定位问题可能会比较困难。开发人员需要跟踪请求在多个处理节点之间的传递过程才能确定问题出在哪里。例如当一个采购申请被拒绝但不清楚是哪个审批节点做出的决定时就需要花费更多的时间和精力去排查问题。 责任链的维护随着业务的发展责任链可能会不断变化如添加、删除或修改节点。这需要开发人员仔细维护责任链的组装和配置确保责任链的正确性和有效性。否则可能会导致工作流出现错误或异常。例如如果在添加新的审批节点时没有正确设置其与其他节点的关系可能会导致审批流程中断或出现错误的审批结果。 3.2 消息处理系统中的应用 3.2.1 消息处理场景分析 在消息处理系统中消息通常需要经过多个处理环节。以一个电商系统的订单消息处理为例当用户下单后系统会产生一条订单消息。这条消息首先会进入消息队列然后被消息处理系统获取。在处理过程中消息可能需要经过以下几个环节 消息过滤系统需要判断该消息是否是合法的订单消息例如检查消息格式是否正确、消息内容是否完整等。如果消息不符合要求将被过滤掉不再进行后续处理。消息转换将消息从一种格式转换为另一种格式以便后续的处理组件能够正确处理。例如将 JSON 格式的订单消息转换为系统内部使用的对象格式提取出订单的关键信息如订单号、商品信息、用户信息等。消息分发根据订单的类型如普通订单、促销订单、团购订单等或其他条件将消息分发给不同的处理模块进行进一步处理。例如普通订单可能被发送到常规的订单处理模块而促销订单则可能被发送到专门的促销活动处理模块。 在这个过程中责任链模式可以很好地应用。每个处理环节可以看作是责任链上的一个节点消息在这些节点之间依次传递每个节点根据自身的职责对消息进行处理。这种方式使得消息处理系统的结构更加清晰各个处理环节之间解耦便于系统的扩展和维护。 3.2.2 消息处理责任链构建 下面展示如何在消息处理系统中使用责任链模式构建消息处理流程。 首先定义抽象消息处理器MessageHandler public abstract class MessageHandler {protected MessageHandler nextHandler;public void setNextHandler(MessageHandler nextHandler) {this.nextHandler nextHandler;}public abstract void handle(Message message); }在这个抽象类中nextHandler用于指向下一个消息处理器handle方法是抽象的具体的消息处理逻辑将由子类实现。 然后实现具体消息处理器如FilterHandler消息过滤处理器、TransformerHandler消息转换处理器和DispatcherHandler消息分发处理器 public class FilterHandler extends MessageHandler {Overridepublic void handle(Message message) {if (isValidMessage(message)) {System.out.println(消息过滤通过消息内容 message.getContent());if (nextHandler! null) {nextHandler.handle(message);}} else {System.out.println(消息过滤失败消息内容 message.getContent());}}private boolean isValidMessage(Message message) {// 模拟消息过滤逻辑如检查消息格式return message.getContent().startsWith({);} }public class TransformerHandler extends MessageHandler {Overridepublic void handle(Message message) {System.out.println(消息转换开始消息内容 message.getContent());// 模拟消息转换逻辑如将JSON字符串转换为对象String transformedContent transformMessage(message.getContent());message.setContent(transformedContent);System.out.println(消息转换完成转换后的内容 message.getContent());if (nextHandler! null) {nextHandler.handle(message);}}private String transformMessage(String content) {// 简单模拟转换逻辑实际应用中可能更复杂return Transformed: content;} }public class DispatcherHandler extends MessageHandler {Overridepublic void handle(Message message) {System.out.println(消息分发开始消息内容 message.getContent());dispatchMessage(message);System.out.println(消息分发完成);}private void dispatchMessage(Message message) {// 模拟消息分发逻辑根据消息类型分发if (message.getContent().contains(promotion)) {System.out.println(将消息分发给促销活动处理模块);} else {System.out.println(将消息分发给常规订单处理模块);}} }FilterHandler在handle方法中首先判断消息是否合法若合法则传递给下一个处理器否则提示过滤失败。TransformerHandler模拟了消息转换逻辑并在转换后将消息传递给下一个处理器。DispatcherHandler负责消息的分发根据消息内容判断分发方向。 最后在客户端组装责任链并提交消息 public class Client {public static void main(String[] args) {MessageHandler filterHandler new FilterHandler();MessageHandler transformerHandler new TransformerHandler();MessageHandler dispatcherHandler new DispatcherHandler();filterHandler.setNextHandler(transformerHandler);transformerHandler.setNextHandler(dispatcherHandler);Message message new Message({\orderId\:123, \product\:\Book\});filterHandler.handle(message);} }class Message {private String content;public Message(String content) {this.content content;}public String getContent() {return content;}public void setContent(String content) {this.content content;} }在客户端代码中创建了FilterHandler、TransformerHandler和DispatcherHandler三个具体消息处理器并将它们组装成责任链。然后创建了一条订单消息并将其提交给责任链的起始处理器filterHandler进行处理。 3.2.3 应用效果与优化 在消息处理系统中使用责任链模式带来了以下应用效果 提高可扩展性当系统需要添加新的消息处理环节时只需要创建新的具体处理器类并将其加入责任链即可。例如如果需要在消息处理流程中添加一个日志记录环节只需要创建一个LoggerHandler类实现日志记录逻辑并将其插入到责任链中的合适位置而不会影响到其他已有的处理环节。 增强维护性各个处理环节的逻辑相互独立使得代码的维护更加容易。如果某个处理环节的逻辑发生变化只需要修改对应的具体处理器类而不会对整个消息处理系统造成影响。例如如果消息过滤的规则发生变化只需要在FilterHandler类中修改isValidMessage方法的实现即可。 清晰的流程控制责任链模式使得消息处理的流程更加清晰每个处理器的职责明确。开发人员可以很容易地理解和跟踪消息在系统中的处理过程便于调试和优化。 然而为了进一步提升消息处理系统的性能和效率还可以考虑以下优化方向 缓存处理结果对于一些处理结果不会频繁变化的处理器可以缓存其处理结果。例如在消息转换处理器中如果转换后的结果在一段时间内不会改变可以将其缓存起来当下次处理相同的消息时直接从缓存中获取结果避免重复处理提高处理效率。优化责任链顺序根据消息处理的频率和性能要求合理调整责任链中处理器的顺序。将处理速度快、经常执行的处理器放在前面这样可以尽早过滤掉不符合要求的消息减少不必要的处理开销。例如如果消息过滤的条件比较简单且执行频率较高可以将FilterHandler放在责任链的最前面。异步处理对于一些耗时较长的处理器可以考虑采用异步处理的方式。将消息处理任务提交到线程池或消息队列中让其在后台异步执行避免阻塞整个消息处理流程。例如在消息分发环节如果分发到某些处理模块的过程比较耗时可以将分发任务异步化提高系统的响应速度。 四、责任链模式的优势与局限 4.1 显著优势 4.1.1 解耦请求与处理 责任链模式最大的优势之一就是将请求的发送者和处理者解耦。在传统的设计中如果有多个处理者可以处理一个请求发送者通常需要明确知道应该将请求发送给哪个处理者这就导致发送者与处理者之间存在紧密的耦合关系。例如在一个订单处理系统中如果没有使用责任链模式订单创建后客户端可能需要根据订单的类型、金额等信息判断应该调用哪个具体的处理模块如普通订单处理模块、大额订单处理模块等来处理订单。这样一来客户端代码中会充斥着大量的条件判断语句并且当新增或修改处理模块时客户端代码也需要相应地修改这使得系统的维护和扩展变得困难。 而在责任链模式中发送者只需要将请求发送到责任链的起始端不需要关心具体是哪个处理者来处理请求请求会在责任链中自动传递直到被合适的处理者处理。以电商系统的订单处理为例客户端创建订单后只需将订单请求发送给责任链的第一个处理者如订单验证处理器订单验证处理器如果能够处理该订单如验证订单信息的合法性则进行处理如果不能处理如订单金额超出其处理范围则将订单传递给下一个处理者如大额订单处理器。这种方式使得客户端与具体的处理者之间的耦合度大大降低系统更加灵活和可维护。当需要新增一个处理者如促销订单处理器时只需要将其添加到责任链中而不需要修改客户端代码。 4.1.2 增强系统灵活性 责任链模式使得系统具有高度的灵活性。一方面责任链的结构可以在运行时动态调整。例如在一个工作流系统中审批流程可能会根据不同的业务场景、项目类型或用户角色而有所不同。使用责任链模式可以在运行时根据具体的条件动态地添加、删除或调整责任链中的处理者。比如在一个普通的项目审批流程中可能只需要经过项目经理、部门经理的审批但对于一个重要的战略项目可能需要额外经过公司高层领导的审批。通过责任链模式我们可以在运行时根据项目的重要性动态地将高层领导的审批环节添加到责任链中而不需要修改大量的代码。 另一方面责任链模式可以方便地应对业务规则的变化。随着业务的发展处理请求的规则可能会不断变化。在责任链模式中每个处理者只负责自己的处理逻辑当业务规则发生变化时只需要修改相应的处理者的代码而不会影响到其他处理者和整个系统的结构。例如在一个消息处理系统中原来的消息过滤规则是根据消息的来源进行过滤后来业务需求发生变化需要根据消息的内容进行过滤。此时只需要修改消息过滤处理器的代码而不需要对整个消息处理系统进行大规模的重构。 4.1.3 符合单一职责原则 在责任链模式中每个具体处理者都只负责自己特定的业务逻辑符合单一职责原则。单一职责原则是指一个类应该只有一个引起它变化的原因即一个类应该只负责一项职责。在责任链模式中每个处理者都专注于自己的职责如在请假审批流程中组长只负责审批请假天数在自己权限范围内的请假申请CTO 只负责审批请假天数在自己权限范围内的申请CEO 负责审批超出 CTO 权限的申请。每个处理者的职责明确代码结构清晰当需要修改某个处理者的业务逻辑时只需要修改该处理者对应的类而不会影响到其他处理者。 这种符合单一职责原则的设计使得代码的可维护性大大提高。当系统出现问题时开发人员可以很容易地定位到是哪个处理者出现了问题从而进行针对性的调试和修复。同时也便于代码的复用因为每个处理者的功能单一在其他类似的业务场景中可以很方便地复用这些处理者。例如在一个权限管理系统中不同的权限验证逻辑可以分别封装在不同的处理者中这些处理者可以在其他需要权限验证的系统中复用。 4.2 存在的局限性 4.2.1 可能导致请求无法处理 虽然责任链模式提供了一种灵活的请求处理方式但如果责任链中没有合适的处理者请求可能得不到处理。例如在一个文件上传系统中责任链中依次有文件格式验证处理器、文件大小限制处理器、文件内容过滤处理器。如果有一个特殊的文件它既不符合格式要求大小也超出限制并且内容也不符合过滤规则而责任链中没有一个处理者能够处理这种特殊情况那么这个文件上传请求就无法得到处理。在这种情况下系统需要设计一种默认处理机制例如返回一个错误信息给客户端告知用户请求无法处理的原因。 为了避免这种情况在设计责任链时需要充分考虑各种可能的请求情况并确保责任链中至少有一个处理者能够处理所有可能的请求或者在责任链的末端添加一个默认处理者。例如在上述文件上传系统中可以在责任链的末端添加一个通用错误处理处理器当其他处理者都无法处理请求时由这个通用错误处理处理器返回一个统一的错误信息给用户提示用户文件上传失败并说明可能的原因如文件格式错误、文件过大或内容违规等。 4.2.2 调试困难 由于请求在多个处理者之间传递当责任链较长时调试难度会显著增加。在调试过程中开发人员需要跟踪请求在各个处理者之间的传递路径判断每个处理者对请求的处理是否正确。例如在一个复杂的电商订单处理系统中订单请求可能需要经过多个处理者如订单验证、库存检查、支付处理、物流分配等。如果订单处理出现问题开发人员需要依次检查每个处理者的处理逻辑包括输入参数、输出结果以及对请求的修改等。这需要花费大量的时间和精力并且由于处理者之间的传递关系可能比较复杂很容易出现遗漏或错误的判断。 为了降低调试难度可以在每个处理者中添加详细的日志记录记录请求的进入和离开时间、处理结果以及传递给下一个处理者的信息等。这样在调试时开发人员可以通过查看日志来了解请求的处理过程快速定位问题所在。此外还可以使用一些调试工具如断点调试在每个处理者的关键代码处设置断点逐步跟踪请求的处理过程观察变量的值和处理逻辑的执行情况。 4.2.3 性能开销 当责任链过长时每个处理者的处理和传递操作可能会带来一定的性能问题。每个处理者在处理请求时都需要消耗一定的时间和资源如 CPU、内存等。当请求在责任链中传递时这些处理和传递操作的开销会累积起来导致系统性能下降。例如在一个大型企业的审批流程中一个请假申请可能需要经过多个层级的领导审批每个领导的审批操作都需要查询数据库、验证权限等这些操作都会消耗一定的时间。如果责任链过长请假申请的审批时间可能会变得很长影响员工的工作效率。 为了减少性能开销可以对责任链进行优化。例如合理设计责任链的结构避免不必要的处理者和过长的传递路径。可以根据业务的实际 情况将一些处理逻辑合并到一个处理者中减少处理者的数量。同时对于一些耗时较长的处理操作可以考虑采用异步处理的方式将这些操作放到后台线程或队列中进行处理避免阻塞整个责任链的执行。此外还可以对处理者的代码进行优化提高处理效率如使用缓存、优化算法等。 五、责任链模式与其他设计模式的关联与区别 5.1 与策略模式对比 5.1.1 策略模式简介 策略模式Strategy Pattern定义了一系列算法将每个算法封装起来使它们可以相互替换并且算法的变化不会影响到使用算法的客户端。策略模式主要包含三个角色 抽象策略角色Strategy这是一个接口或抽象类定义了所有具体策略类需要实现的方法它是策略的抽象为具体策略提供统一的接口。例如在一个图形绘制系统中可能定义一个抽象的绘图策略接口ShapeDrawingStrategy其中包含一个抽象方法drawShape用于绘制不同形状的图形。 具体策略角色ConcreteStrategy实现了抽象策略角色中定义的接口方法每个具体策略类都封装了一种具体的算法或行为。继续以上述图形绘制系统为例可能有CircleDrawingStrategy类实现ShapeDrawingStrategy接口在drawShape方法中实现绘制圆形的具体逻辑还有RectangleDrawingStrategy类实现绘制矩形的具体逻辑。 环境角色Context持有一个抽象策略角色的引用通过这个引用调用具体策略类的方法。在图形绘制系统中可能有一个DrawingContext类它持有ShapeDrawingStrategy类型的引用。在需要绘制图形时DrawingContext根据具体需求设置不同的具体策略对象如CircleDrawingStrategy或RectangleDrawingStrategy然后调用drawShape方法进行图形绘制。 5.1.2 两者区别分析 意图不同责任链模式的主要意图是将请求的发送者和接收者解耦使多个对象都有机会处理这个请求将这些对象连成一条链并沿着这条链传递请求直到有一个对象处理它为止。例如在一个电商系统的订单审核流程中订单请求会依次经过多个审核人员如客服初审、财务审核、经理终审等每个审核人员根据自己的职责和权限来决定是否处理该订单请求若不能处理则传递给下一个审核人员。而策略模式的意图是定义一系列算法将每个算法封装起来使它们可以相互替换主要用于解决在多个算法或行为中进行选择的问题。比如在一个支付系统中有多种支付方式如信用卡支付、支付宝支付、微信支付等客户端可以根据用户的选择动态地切换支付策略。 结构不同责任链模式中处理者之间形成一条链状结构每个处理者都持有下一个处理者的引用请求在链上依次传递。在请假审批流程中组长、CTO、CEO 等审批者形成一条责任链组长处理不了的请假请求会传递给 CTOCTO 处理不了再传递给 CEO。而策略模式中环境角色持有一个抽象策略的引用具体策略之间是平行的关系没有直接的关联。在电商系统的促销策略中满减策略、折扣策略、赠品策略等具体策略类都是独立的它们都实现了抽象的促销策略接口由环境角色如促销活动管理类根据不同的促销活动选择合适的策略。 使用场景不同责任链模式适用于有多个对象可以处理一个请求但具体由哪个对象处理在运行时才能确定的场景并且请求的处理过程可能需要多个步骤每个步骤由不同的对象负责。例如在一个工作流系统中任务的审批流程可能涉及多个部门和人员每个部门和人员根据自己的职责和权限对任务进行处理。策略模式适用于需要在不同情况下使用不同的算法或行为并且这些算法或行为可以相互替换的场景。比如在一个游戏开发中不同的角色可能有不同的移动策略如跑步、飞行、跳跃等可以根据角色的类型和游戏场景动态地选择合适的移动策略。 决策方式不同责任链模式中处理者根据自身的条件和逻辑来决定是否处理请求若不能处理则传递给下一个处理者决策过程是链式的、逐步进行的。而策略模式中客户端根据具体的业务需求和条件选择合适的策略决策过程是集中在客户端进行的客户端明确知道选择哪种策略来执行相应的算法。例如在一个数据分析系统中根据数据的类型和分析目的客户端选择不同的数据分析策略如统计分析策略、机器学习策略等。 5.2 与观察者模式对比 5.2.1 观察者模式简介 观察者模式Observer Pattern定义了对象之间的一种一对多依赖关系使得每当一个对象被观察者也称为主题的状态发生改变时其相关依赖对象观察者皆得到通知并被自动更新。观察者模式主要包含以下几个角色 抽象主题Subject也称为被观察者它是一个接口或抽象类定义了添加、删除观察者以及通知观察者的方法。例如在一个股票行情系统中可能有一个抽象的股票主题接口StockSubject其中包含attach方法用于添加观察者如股民detach方法用于删除观察者notifyObservers方法用于在股票价格发生变化时通知所有观察者。 具体主题ConcreteSubject实现了抽象主题接口维护一个观察者列表当自身状态改变时会调用notifyObservers方法通知所有观察者。在股票行情系统中具体的股票类如AppleStock就是具体主题它实现了StockSubject接口当苹果股票的价格发生变化时会遍历观察者列表调用每个观察者的更新方法。 抽象观察者Observer定义了一个更新接口当被观察者状态改变时观察者会收到通知并调用这个接口进行相应的处理。在股票行情系统中可能有一个抽象的股民接口StockObserver其中包含update方法用于接收股票价格变化的通知并进行处理如显示最新的股票价格、计算盈亏等。 具体观察者ConcreteObserver实现了抽象观察者接口在接收到被观察者的通知时执行具体的更新操作。例如在股票行情系统中具体的股民类如InvestorA实现了StockObserver接口在update方法中实现根据股票价格变化进行相应操作的逻辑如根据新的股票价格计算自己的资产状况并输出到控制台。 5.2.2 两者差异剖析 对象关系不同在责任链模式中处理者之间是链式的关联关系每个处理者只知道下一个处理者是谁它们共同构成一条责任链来处理请求。例如在一个文件上传系统的权限验证流程中可能依次有普通用户权限验证处理器、管理员权限验证处理器、超级管理员权限验证处理器它们形成一条责任链普通用户权限验证处理器处理不了的请求会传递给管理员权限验证处理器。而在观察者模式中被观察者和观察者之间是一对多的依赖关系一个被观察者可以有多个观察者当被观察者状态改变时会通知所有注册的观察者。比如在一个社交媒体平台中一个用户发布了一条新动态被观察者状态改变关注这个用户的所有其他用户观察者都会收到通知。 消息传递方向不同责任链模式中消息请求是沿着责任链单向传递的从链首的处理者开始依次向后传递直到有处理者能够处理该请求或者到达链尾。在订单处理的责任链中订单请求从最开始的订单验证处理器开始依次经过库存检查处理器、支付处理处理器等每个处理器根据自己的逻辑决定是否处理订单请求以及是否传递给下一个处理器。而观察者模式中消息是从被观察者向所有注册的观察者广播的被观察者不知道具体有哪些观察者也不关心观察者如何处理消息只要自身状态改变就会通知所有观察者。例如在一个邮件订阅系统中当有新的邮件到达被观察者状态改变时系统会向所有订阅该邮件的用户观察者发送通知告知有新邮件。 应用场景不同责任链模式主要用于处理请求的流程化处理将请求的处理分散到多个对象中每个对象负责一部分处理逻辑适用于需要根据不同条件或权限进行逐步处理的场景。比如在一个审批流程中不同级别的领导根据自己的权限对审批请求进行处理。观察者模式主要用于当一个对象的状态改变需要通知其他多个对象并让这些对象做出相应反应的场景适用于实现事件驱动的系统、消息通知机制等。例如在一个实时监控系统中当被监控的设备状态发生变化如温度过高、压力过大等时需要及时通知所有关注该设备状态的用户或系统模块。 目的不同责任链模式的目的是解耦请求的发送者和接收者将请求的处理逻辑分散到多个处理者中提高系统的灵活性和可扩展性使得系统在不影响客户端的情况下能够动态地重新组织和分配责任。而观察者模式的目的是实现对象之间的事件通知机制当一个对象的状态发生变化时能够自动通知其他依赖它的对象实现对象之间的联动和交互降低对象之间的耦合度。 六、责任链模式的最佳实践与优化策略 6.1 最佳实践建议 6.1.1 合理设计责任链长度 在设计责任链时应根据具体的业务场景和性能要求合理控制责任链的长度。过长的责任链会导致请求处理的性能下降因为每个处理者的处理和传递操作都需要消耗时间和资源。例如在一个电商系统的订单处理流程中如果责任链过长从订单创建到最终发货的整个流程可能会变得缓慢影响用户体验。因此在设计责任链时需要对业务流程进行深入分析确保每个处理者都承担必要的职责避免不必要的处理环节。可以通过定期评估业务流程和处理者的职责及时调整责任链的结构去除冗余的处理者以提高责任链的处理效率。 6.1.2 明确处理者职责 每个处理者的职责应该明确避免出现职责模糊的情况。这有助于提高代码的可读性和可维护性当系统出现问题时也更容易定位和解决。例如在一个工作流系统中每个审批者的审批权限和职责应该清晰定义如组长负责审批小额费用报销部门经理负责审批中等额度的费用报销总经理负责审批大额费用报销。如果职责不明确可能会导致审批流程混乱出现重复审批或无人审批的情况。在定义处理者职责时可以使用详细的文档说明每个处理者的功能、输入输出要求以及与其他处理者的关系确保开发人员和维护人员能够准确理解每个处理者的作用。 6.1.3 处理者顺序优化 根据请求处理的频率和优先级合理优化处理者在责任链中的顺序。将处理频率高、处理速度快的处理者放在责任链的前面这样可以尽早处理请求减少不必要的处理开销。例如在一个消息处理系统中如果消息过滤的操作比较简单且频繁执行应该将消息过滤处理器放在责任链的最前面先对消息进行过滤避免无效消息进入后续的处理环节从而提高整个消息处理系统的效率。同时对于一些具有优先级的请求应该将能够处理高优先级请求的处理者放在前面确保高优先级请求能够得到及时处理。 6.2 优化策略探讨 6.2.1 缓存处理结果 对于一些重复处理的请求可以考虑缓存处理结果。如果某个处理者对某个请求的处理结果在一段时间内不会发生变化那么可以将该处理结果缓存起来当下次接收到相同的请求时直接从缓存中获取处理结果避免重复处理提高处理效率。例如在一个数据查询系统中如果某个查询条件经常被使用且查询结果在一定时间内不会改变可以将该查询结果缓存起来。当再次接收到相同的查询请求时直接从缓存中返回结果而不需要再次执行复杂的数据查询操作这样可以大大提高系统的响应速度。 6.2.2 分拆责任链 对于复杂的业务场景可以将责任链分拆为多个子链每个子链负责处理特定类型的请求或业务逻辑的一部分。这样可以提高处理效率同时也便于维护和扩展。例如在一个大型电商系统中订单处理可能涉及多个环节如订单验证、库存检查、支付处理、物流分配等。可以将这些环节拆分为多个子链如订单验证子链、支付处理子链、物流分配子链等。每个子链可以独立维护和扩展当业务需求发生变化时只需要修改相应的子链而不会影响其他子链的正常运行。同时分拆责任链还可以根据不同的业务场景和流量情况对各个子链进行针对性的优化和调整提高整个系统的性能。 6.2.3 增加日志记录 在每个处理者中增加详细的日志记录有助于调试和监控责任链的运行情况。日志可以记录请求的进入和离开时间、处理结果、传递给下一个处理者的信息等。当系统出现问题时开发人员可以通过查看日志快速定位问题所在了解请求在责任链中的处理过程从而更容易进行调试和修复。例如在一个分布式系统中责任链可能跨越多个服务和节点通过日志记录可以清晰地了解请求在不同服务和节点之间的传递和处理情况便于排查故障。同时日志记录还可以用于监控责任链的性能统计每个处理者的处理时间和请求量为系统的优化提供数据支持。 七、总结与展望 7.1 责任链模式回顾 责任链模式作为一种行为型设计模式通过将请求沿着处理者链传递实现了请求发送者与处理者之间的解耦。在本文中我们深入探讨了责任链模式的核心概念、实现方式以及在实际项目中的应用。 从定义上看责任链模式允许请求在处理者链中传递直到有处理者能够处理该请求。这种模式的关键在于抽象处理者、具体处理者和客户端三个核心角色的协同工作。抽象处理者定义了处理请求的接口和传递请求的机制为具体处理者提供了统一的抽象具体处理者实现了处理请求的具体逻辑根据自身的职责判断是否能够处理请求若不能则将请求传递给下一个处理者客户端负责创建处理链并将请求发送到链首的处理者。 在 Java 代码示例中我们通过请假审批流程和电商交易系统订单状态处理两个案例详细展示了责任链模式的实现过程。在请假审批流程中不同级别的审批者组长、CTO、CEO构成了责任链根据请假天数的不同请求在链中传递并被相应的审批者处理。在电商交易系统中订单状态从已支付到已发货再到已收货的处理过程通过不同的订单状态处理器已支付订单处理器、已发货订单处理器、已收货订单处理器组成的责任链来完成每个处理器根据订单的当前状态进行相应的处理并传递订单。 在实际使用场景方面责任链模式在工作流引擎和消息处理系统中有着广泛的应用。在工作流引擎中如采购审批流程通过责任链模式可以将不同的审批环节解耦使系统能够根据业务规则和组织结构的变化灵活调整审批流程。在消息处理系统中如电商系统的订单消息处理消息可以依次经过消息过滤、消息转换、消息分发等处理环节每个环节由相应的处理器负责提高了消息处理的灵活性和可扩展性。 责任链模式具有显著的优势它解耦了请求与处理使得系统更加灵活符合单一职责原则提高了代码的可维护性和可扩展性。然而它也存在一些局限性例如可能导致请求无法处理当责任链中没有合适的处理者时请求得不到处理调试困难由于请求在多个处理者之间传递责任链较长时调试难度增加性能开销当责任链过长时处理和传递操作可能会带来性能问题。 7.2 未来应用展望 随着分布式系统和微服务架构的不断发展责任链模式在这些领域将有更广阔的应用前景。 在分布式系统中责任链模式可以用于实现请求的分布式处理。例如在一个分布式电商系统中用户的订单请求可能需要经过多个服务节点的处理如订单验证服务、库存管理服务、支付处理服务等。通过责任链模式可以将这些服务节点组织成责任链订单请求在链中依次传递每个服务节点根据自身的职责对订单进行处理。这样可以实现分布式系统中请求处理的流程化和规范化提高系统的可维护性和可扩展性。同时责任链模式还可以与分布式缓存、消息队列等技术相结合进一步优化系统性能。例如在责任链中可以在适当的节点使用分布式缓存来缓存处理结果减少重复计算和数据库访问利用消息队列实现异步处理提高系统的响应速度和吞吐量。 在微服务架构中责任链模式可以用于构建微服务之间的通信和协作机制。每个微服务可以看作是责任链中的一个处理者根据业务需求微服务之间可以形成不同的责任链。例如在一个多租户的 SaaS 应用中用户请求可能需要经过身份验证微服务、租户权限验证微服务、业务逻辑处理微服务等。通过责任链模式可以灵活地配置和管理这些微服务之间的协作关系当业务需求发生变化时只需要调整责任链的结构而不需要修改每个微服务的内部代码。此外责任链模式还可以帮助微服务架构更好地实现服务治理。例如通过在责任链中添加监控、日志记录、限流等功能的微服务可以对整个微服务架构的运行状态进行实时监控和管理提高系统的稳定性和可靠性。 总之责任链模式作为一种强大的设计模式在未来的软件开发中尤其是在分布式系统和微服务架构中将继续发挥重要作用为构建更加灵活、高效、可维护的软件系统提供有力支持。
文章转载自:
http://www.morning.pwwdp.cn.gov.cn.pwwdp.cn
http://www.morning.gfjgq.cn.gov.cn.gfjgq.cn
http://www.morning.jnptt.cn.gov.cn.jnptt.cn
http://www.morning.ffksr.cn.gov.cn.ffksr.cn
http://www.morning.zwznz.cn.gov.cn.zwznz.cn
http://www.morning.clqpj.cn.gov.cn.clqpj.cn
http://www.morning.fmswb.cn.gov.cn.fmswb.cn
http://www.morning.gwhjy.cn.gov.cn.gwhjy.cn
http://www.morning.cbpkr.cn.gov.cn.cbpkr.cn
http://www.morning.pghfy.cn.gov.cn.pghfy.cn
http://www.morning.llthz.cn.gov.cn.llthz.cn
http://www.morning.bxrlt.cn.gov.cn.bxrlt.cn
http://www.morning.qxycf.cn.gov.cn.qxycf.cn
http://www.morning.rjnky.cn.gov.cn.rjnky.cn
http://www.morning.msmtf.cn.gov.cn.msmtf.cn
http://www.morning.kmkpm.cn.gov.cn.kmkpm.cn
http://www.morning.kxymr.cn.gov.cn.kxymr.cn
http://www.morning.pmsl.cn.gov.cn.pmsl.cn
http://www.morning.tpyrn.cn.gov.cn.tpyrn.cn
http://www.morning.nnwnl.cn.gov.cn.nnwnl.cn
http://www.morning.guangda11.cn.gov.cn.guangda11.cn
http://www.morning.rbkl.cn.gov.cn.rbkl.cn
http://www.morning.bbxbh.cn.gov.cn.bbxbh.cn
http://www.morning.hrnrx.cn.gov.cn.hrnrx.cn
http://www.morning.huxinzuche.cn.gov.cn.huxinzuche.cn
http://www.morning.lmrcq.cn.gov.cn.lmrcq.cn
http://www.morning.mlbn.cn.gov.cn.mlbn.cn
http://www.morning.kgcss.cn.gov.cn.kgcss.cn
http://www.morning.wjpsn.cn.gov.cn.wjpsn.cn
http://www.morning.alive-8.com.gov.cn.alive-8.com
http://www.morning.stbhn.cn.gov.cn.stbhn.cn
http://www.morning.nxdqz.cn.gov.cn.nxdqz.cn
http://www.morning.rnrwq.cn.gov.cn.rnrwq.cn
http://www.morning.gyqnc.cn.gov.cn.gyqnc.cn
http://www.morning.pabxcp.com.gov.cn.pabxcp.com
http://www.morning.zdydj.cn.gov.cn.zdydj.cn
http://www.morning.rddlz.cn.gov.cn.rddlz.cn
http://www.morning.mtsck.cn.gov.cn.mtsck.cn
http://www.morning.yrdt.cn.gov.cn.yrdt.cn
http://www.morning.sgfgz.cn.gov.cn.sgfgz.cn
http://www.morning.bpmnl.cn.gov.cn.bpmnl.cn
http://www.morning.pkfpl.cn.gov.cn.pkfpl.cn
http://www.morning.hmwjk.cn.gov.cn.hmwjk.cn
http://www.morning.rjnx.cn.gov.cn.rjnx.cn
http://www.morning.klyyd.cn.gov.cn.klyyd.cn
http://www.morning.cjcry.cn.gov.cn.cjcry.cn
http://www.morning.nqyzg.cn.gov.cn.nqyzg.cn
http://www.morning.kltsn.cn.gov.cn.kltsn.cn
http://www.morning.ygkq.cn.gov.cn.ygkq.cn
http://www.morning.cylbs.cn.gov.cn.cylbs.cn
http://www.morning.wqhlj.cn.gov.cn.wqhlj.cn
http://www.morning.gtqws.cn.gov.cn.gtqws.cn
http://www.morning.jwsrp.cn.gov.cn.jwsrp.cn
http://www.morning.txmkx.cn.gov.cn.txmkx.cn
http://www.morning.skql.cn.gov.cn.skql.cn
http://www.morning.nwfxp.cn.gov.cn.nwfxp.cn
http://www.morning.dtgjt.cn.gov.cn.dtgjt.cn
http://www.morning.pjfmq.cn.gov.cn.pjfmq.cn
http://www.morning.mnkz.cn.gov.cn.mnkz.cn
http://www.morning.rykmf.cn.gov.cn.rykmf.cn
http://www.morning.haolipu.com.gov.cn.haolipu.com
http://www.morning.cwgt.cn.gov.cn.cwgt.cn
http://www.morning.jjsxh.cn.gov.cn.jjsxh.cn
http://www.morning.fsfz.cn.gov.cn.fsfz.cn
http://www.morning.hnrdtz.com.gov.cn.hnrdtz.com
http://www.morning.kngx.cn.gov.cn.kngx.cn
http://www.morning.yrjfb.cn.gov.cn.yrjfb.cn
http://www.morning.hfytgp.cn.gov.cn.hfytgp.cn
http://www.morning.zwdrz.cn.gov.cn.zwdrz.cn
http://www.morning.hwnqg.cn.gov.cn.hwnqg.cn
http://www.morning.syfty.cn.gov.cn.syfty.cn
http://www.morning.tpnxj.cn.gov.cn.tpnxj.cn
http://www.morning.bwygy.cn.gov.cn.bwygy.cn
http://www.morning.nlglm.cn.gov.cn.nlglm.cn
http://www.morning.ykgp.cn.gov.cn.ykgp.cn
http://www.morning.rbffj.cn.gov.cn.rbffj.cn
http://www.morning.jljwk.cn.gov.cn.jljwk.cn
http://www.morning.jwfqq.cn.gov.cn.jwfqq.cn
http://www.morning.gqdsm.cn.gov.cn.gqdsm.cn
http://www.morning.ykrss.cn.gov.cn.ykrss.cn
http://www.tj-hxxt.cn/news/278348.html

相关文章:

  • 浙江网站建设品牌升级襄阳网站推广优化技巧
  • 网站开发后端做什么手机端下载
  • 网站导航设计模板凡科建站seo
  • 北京制作网站软件html制作一个网站代码
  • 如何做网站的内链和外链wordpress 导航网站模板
  • 网站开发的关系图和e-r图今天中美关系最新消息
  • 专业做汽车零部件平台的网站wordpress子网页
  • 安阳网站建设哪家公司好wordpress商城支付主题
  • 新吴区住房和建设交通局网站宁波专业网站搭建地址
  • 网站会员系统源码鱼台做网站多少钱
  • 重新安wordpress网站北京制作app
  • 产品营销型网站建设wordpress 站外链接
  • 外贸网站建设与推广wordpress显示文章全文
  • 网站执行速度wordpress 首页 插件
  • 山东省建设工程领域挂证存颖网站四大网站
  • 2018年做淘宝客网站还能挣钱吗6公司形象墙设计效果图
  • 成都网站建设电话2017网站icp备案
  • 北京网站建设价位网站关键词在哪里添加
  • 比较好的网站开发教学网站wordpress 七牛插件
  • 网站建设平台的分析响应式设计网站
  • 陇西学做网站廊坊网站搭建
  • 网站设计有什么前景聊城建设银行官方网站
  • php html5企业网站源码产品线上推广渠道
  • 手机微信官方网站首页横沥网站仿做
  • 做网站赚钱多吗网站描述技巧
  • asp.net网站开发视频教程低价网站建设案例
  • 珠宝网站建设公司jsp网站开发标准
  • 高端的网站名称电商平台网站开发
  • 信誉好的天津网站建设淘客单网站
  • 北京专业网站维护公司设计网页代码源代码