• 链设计模式-装饰模式、职责链设计模式


    一、链设计模式设计理念:

            使用java面向对象的三大特征(继承、多态、封装)对原有对象实现功能扩展,通过处理机制对于不同层级之间实现继承关系生成多个不同子类继承共同的“类型”,通过对每个子类传入父类,重写并调用父类方法以实现对原有的代码不修改增加并实现新的功能模块。简单通俗,装饰模式就是动态的对一个原有对象添加一些额外的职责;职责链模式就是对一个事务对象根据链设计关系对该事务的动态处理。

    二、装饰模式:

            1.作用:动态的给一个对象添加新的职责。

            2.实现方式:将一个类的对象嵌入到另外一个新的对象之中,由另外一个对象(原有对象)来决定是否调用嵌入对象的行为对自己的扩展功能,这个新的对象为装饰器(装饰机制)。为了使得装饰器与它所装饰的对象客户端来说是透明的,装饰器类和被装饰必须实现相同的接口,客户使用时不需要知道一个类的对象是否被装饰过,可以一致性地使用装饰的对象以及被装饰的对象

            3.小菜穿衣代码实践:

            (1)首先需要创建一个角色展示的接口 Component;在接口中有一个展示的方法(行为)

    1. package com.example;
    2. /**
    3. * @BelongsProject: 装饰模式
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:22
    7. */
    8. public interface Component {
    9. /**
    10. * @description: 角色展示
    11. * @author: mr.zhang
    12. * @date: 2022/11/10 19:26
    13. * @param: []
    14. * @return: void
    15. **/
    16. abstract void show();
    17. }

    (2)具体被装扮者人类

    1. package com.example;
    2. /**
    3. * @BelongsProject: 具体的被装扮者类
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:30
    7. */
    8. public class Person implements Component{
    9. private String name;//被装扮的人
    10. public Person(String name) {
    11. this.name = name;
    12. }
    13. public String getName() {
    14. return name;
    15. }
    16. public void setName(String name) {
    17. this.name = name;
    18. }
    19. @Override
    20. public void show() {
    21. System.out.println("装扮的"+name);
    22. }
    23. }

    (3)构建一个装饰器(服饰类)实现角色接口;

    1. package com.example;
    2. /**
    3. * @BelongsProject: 服饰类 装饰器
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:36
    7. */
    8. public class Finery implements Component {
    9. protected Component component;//引入被装饰者
    10. public void decorate(Component component){
    11. this.component=component;
    12. }
    13. /**
    14. * @description: 当存在一个被装饰者时就调用他的展示方法
    15. * @author: mr.zhang
    16. * @date: 2022/11/10 19:39
    17. * @param: []
    18. * @return: void
    19. **/
    20. @Override
    21. public void show() {
    22. if (component!=null)
    23. component.show();
    24. }
    25. }

    (4)具体需要的服饰(装饰配件)

    1. package com.example;
    2. /**
    3. * @BelongsProject: 具体服饰类 跨库
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:42
    7. */
    8. public class Kuaku extends Finery{
    9. public void show(){
    10. System.out.println("垮裤");
    11. super.show();
    12. }
    13. }
    1. package com.example;
    2. /**
    3. * @BelongsProject: 破球鞋
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:53
    7. */
    8. public class Pqx extends Finery{
    9. public void show(){
    10. System.out.println("破球鞋");
    11. super.show();
    12. }
    13. }
    1. package com.example;
    2. /**
    3. * @BelongsProject: T恤
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:56
    7. */
    8. public class T_shirt extends Finery{
    9. public void show(){
    10. System.out.println("T恤");
    11. super.show();
    12. }
    13. }
    1. package com.example;
    2. /**
    3. * @BelongsProject: 西装
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:58
    7. */
    8. public class Suit extends Finery{
    9. public void show(){
    10. System.out.println("西装");
    11. super.show();
    12. }
    13. }
    1. package com.example;
    2. /**
    3. * @BelongsProject: 皮鞋
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 19:59
    7. */
    8. public class PX extends Finery{
    9. public void show(){
    10. System.out.println("皮鞋");
    11. super.show();
    12. }
    13. }

    (5)客户端测试代码  创建被装饰者对象(小菜),选择装饰服饰,确定装饰关系

    1. package com.example;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.boot.test.context.SpringBootTest;
    4. @SpringBootTest
    5. class Tests {
    6. @Test
    7. void contextLoads() {
    8. Person person = new Person("小菜");//被装饰者小菜
    9. System.out.println("第一次被装扮:");
    10. Pqx pqx = new Pqx();
    11. Kuaku kuaku = new Kuaku();
    12. T_shirt shirt = new T_shirt();
    13. //装饰过程
    14. pqx.decorate(person);//选择破球鞋
    15. kuaku.decorate(pqx);//继续选择了垮裤
    16. shirt.decorate(kuaku);//最后选择了T恤
    17. shirt.show();/* 第一次被装扮:
    18. T恤
    19. 垮裤
    20. 破球鞋
    21. 装扮的小菜 逆序输出是因为super在打印语句之后
    22. **/
    23. System.out.println("第二次被装扮:");
    24. PX px = new PX();
    25. Suit suit = new Suit();
    26. px.decorate(person);
    27. suit.decorate(px);
    28. suit.show();/*
    29. 第二次被装扮:
    30. 西装
    31. 皮鞋
    32. 装扮的小菜
    33. **/
    34. }
    35. }

    三、职责链模式:

            1.作用:主要构造事件层级处理机制、客户请求者,客户发出请求通过在职责链发送至处理层,请求在整个链路传递过程中都有可能被该层级处理对象处理,让事件处理者与发送者实现解耦关系。

            2.职责链模式与装饰模式:满足了设计模式的开闭原则,以及单一原则;在任意位置可以增添新事件和新对象,提高了代码的维护性和可拓展性;责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句;责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

            3.小菜涨薪代码实践

            (1)创建一个代办事件实体bean封装客户请求

    1. package com.example;
    2. /**
    3. * @BelongsProject: 代办事件请求实体bean
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 20:55
    7. */
    8. public class Request {
    9. private String requestType;//类别
    10. private String requestContent;//内容
    11. private int number;//数量
    12. public Request() {
    13. }
    14. public String getRequestType() {
    15. return requestType;
    16. }
    17. public void setRequestType(String requestType) {
    18. this.requestType = requestType;
    19. }
    20. public String getRequestContent() {
    21. return requestContent;
    22. }
    23. public void setRequestContent(String requestContent) {
    24. this.requestContent = requestContent;
    25. }
    26. public int getNumber() {
    27. return number;
    28. }
    29. public void setNumber(int number) {
    30. this.number = number;
    31. }
    32. }

            (2)请求者封装信息类

    1. package com.example;
    2. /**
    3. * @BelongsProject: 发出请求者封装bean
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 20:53
    7. */
    8. public abstract class Solicitant {
    9. protected String name;
    10. protected Solicitant solicitant;
    11. public Solicitant(String name) {
    12. this.name = name;
    13. }
    14. public String getName() {
    15. return name;
    16. }
    17. public void setName(String name) {
    18. this.name = name;
    19. }
    20. public Solicitant getSolicitant() {
    21. return solicitant;
    22. }
    23. public void setSolicitant(Solicitant solicitant) {
    24. this.solicitant = solicitant;
    25. }
    26. public abstract void processRequest(Request request);
    27. }

            (3)处理事务者一部门总监,并对其权限设置,如果不能处理上交到上级领导,如果能处理则处理不上报

    1. package com.example;
    2. /**
    3. * @BelongsProject: 总监
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 21:07
    7. */
    8. public class Majordomo extends Solicitant{
    9. public Majordomo(String name) {
    10. super(name);
    11. }
    12. @Override
    13. public void processRequest(Request request) {
    14. if (request.getRequestType().equals("请假") && request.getNumber() <= 5){
    15. System.out.println(name +":"+ request.getRequestContent()+"数量"+request.getNumber()+",被批准");
    16. }else {
    17. if (request != null){
    18. solicitant.processRequest(request);
    19. }
    20. }
    21. }
    22. }

            (4)部门经理,权限大于部门总监实现功能一致

    1. package com.example;
    2. /**
    3. * @BelongsProject: 部门经理
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 20:56
    7. */
    8. public class TechnicalManager extends Solicitant{
    9. public TechnicalManager(String name) {
    10. super(name);
    11. }
    12. @Override
    13. public void processRequest(Request request) {
    14. if (request.getRequestType().equals("请假") && request.getNumber() <= 2) {
    15. System.out.println(name +":"+ request.getRequestContent()+"数量"+request.getNumber()+"被批准");
    16. }else {
    17. if (request != null){
    18. solicitant.processRequest(request);
    19. }
    20. }
    21. }
    22. }

            (5)最大权限者(最高职位者)总经理无论事件大小下级管理者无法处理的事件都有该管理者处理

    1. package com.example;
    2. /**
    3. * @BelongsProject: 总经理
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 21:06
    7. */
    8. public class GeneralManager extends Solicitant{
    9. public GeneralManager(String name) {
    10. super(name);
    11. }
    12. @Override
    13. public void processRequest(Request request) {
    14. if (request.getRequestType().equals("请假")){
    15. System.out.println(name +":"+ request.getRequestContent()+"数量"+request.getNumber()+"被批准");
    16. }else if (request.getRequestType().equals("涨工资") && request.getNumber() <=500){
    17. System.out.println(name +":"+ request.getRequestContent()+"数量"+request.getNumber()+"被批准");
    18. }else if (request.getRequestType().equals("涨工资") && request.getNumber() >500){
    19. System.out.println(name +":"+ request.getRequestContent()+"数量"+request.getNumber()+"再说吧");
    20. }
    21. }
    22. }

            (6)最后客户端测试代码

    1. package com.example;
    2. /**
    3. * @BelongsProject: 客户端测试类
    4. * @BelongsPackage: com.example
    5. * @Author: Mr.zhang
    6. * @CreateTime: 2022-11-10 21:08
    7. */
    8. public class Test1 {
    9. public static void main(String[] args) {
    10. TechnicalManager tm = new TechnicalManager("部门经理");
    11. Majordomo md = new Majordomo("总监");
    12. GeneralManager gm = new GeneralManager("总经理");
    13. tm.setSolicitant(md);
    14. md.setSolicitant(gm);
    15. Request request = new Request();
    16. request.setRequestType("请假");
    17. request.setRequestContent("小菜因为 个人事务处理 想要请假");
    18. request.setNumber(1);
    19. tm.processRequest(request);
    20. Request request1 = new Request();
    21. request1.setRequestType("涨工资");
    22. request1.setRequestContent("小菜因为工资太低,想要涨点工资");
    23. request1.setNumber(1500);
    24. tm.processRequest(request1);
    25. }
    26. }

    实现结果:

     每一个层级权限明确,要么直接处理,要么不做任何处理上报到上级领导处理,不能出现一个事件由两级不同领导同时处理。

  • 相关阅读:
    怎么使用 Flink 向 Apache Doris 表中写 Bitmap 类型的数据
    【教程7】疯壳·ARM功能手机-BLE透传实验教程
    代码随想录day53|1143.最长公共子序列 |1035.不相交的线| 53. 最大子序和|Golang
    Python中import机制
    在线论坛系统
    英语语法汇总(9.时态)
    opencv图片绘制图形-------c++
    接雨水【Leecode 42】(坐标轴上的故事)
    使用promise封装Ajax
    大赛征集令|首届“万应杯”低代码应用开发大赛报名开启啦!
  • 原文地址:https://blog.csdn.net/m0_71467744/article/details/127793169