【软考】设计模式之访问者模式

news2025/1/11 2:16:20

目录

        • 1. 说明
        • 2. 应用场景
        • 3. 结构图
        • 4. 构成
        • 5. java示例
          • 5.1 喂动物
            • 5.1.1 抽象访问者
            • 5.1.2 具体访问者
            • 5.1.3 抽象元素
            • 5.1.4 具体元素
            • 5.1.5 对象结构
            • 5.1.6 客户端类
            • 5.1.7 结果示例
          • 5.2 超市销售系统
            • 5.2.1 业务场景
            • 5.2.2 业务需求类图
            • 5.2.3 抽象访问者
            • 5.2.4 具体访问者
            • 5.2.5 抽象元素
            • 5.2.6 具体元素
            • 5.2.7 对象结构
            • 5.2.8 客户端类
            • 5.2.9 结果示例
            • 5.2.10 改进

1. 说明
  • 1.访问者设计模式(Visitor Design Pattern)是一种常见的软件设计模式
  • 2.属于行为型设计模式,行为型对象模式
  • 3.目的:分离数据结构与数据操作,在不改变元素数据结构的情况下,进行添加元素操作
2. 应用场景
  • 1.类的结构改变较少,但经常要增加新的基于该结构的操作
  • 2.需要对某一对象结构的对象进行很多不同的并且不相关的操作,而需要避免让这些操作污染这些对象的类,也不希望在新增操作时修改这些类
3. 结构图

在这里插入图片描述

4. 构成
  • 1.访问者模式由抽象访问者、具体访问者、抽象元素、具体元素、对象结构等角色构成
  • 2.抽象访问者(Visitor):定义访问具体元素的接口,为每个具体元素类声明一个Visit操作,该操作的参数类型标识了被访问的具体元素
  • 3.具体访问者(ConcreteVisitor):实现抽象访问者中声明的各个Visit操作
  • 4.抽象元素(Element):声明一个包含接受操作Accept()的接口,Accept()参数为被接受访问者
  • 5.具体元素(ConcreteElement):实现一个访问者为参数的Accept操作
  • 6.对象结构(ObjectStructure):包含抽象元素的容器,提供让访问者对象遍历容器中所有元素的方法(List、Set、Map等)
5. java示例
5.1 喂动物
5.1.1 抽象访问者
  • 1.一个抽象访问者接口
  • 2.定义访问具体元素的方法feed,为每个具体元素类声明一个喂养的方法,喂狗和喂猫,喂养操作的参数类型标识了被访问的具体元素为狗和猫
package com.learning.visitor;
/**
* 抽象访问者
*/
public interface Person {
    public void feed(Dog dog);

    public void feed(Cat cat);
}

5.1.2 具体访问者
  • 1.具体访问者(ConcreteVisitor):实现抽象访问者中声明的各个Visit操作
  • 2.自家主人实现抽象访问者中声明的喂狗、喂猫操作
  • 3.其他人实现抽象访问者中声明的喂狗、喂猫操作
package com.learning.visitor;

/**
 *  自家主人
 */
public class Owner implements Person{
    @Override
    public void feed(Cat cat) {
        System.out.println("主人喂食猫");
    }

    @Override
    public void feed(Dog dog) {
        System.out.println("主人喂食狗");
    }
}
package com.learning.visitor;

/**
 * 其他人
 */
public class Someone implements Person{

    @Override
    public void feed(Dog dog) {
        System.out.println("其他人喂食狗");
    }

    @Override
    public void feed(Cat cat) {
        System.out.println("其他人喂食猫");
    }
}
5.1.3 抽象元素
  • 1.定一个动物接口,声明一个接收一个人的方法
  • 2.表明是谁喂,参数人为被接受访问者
package com.learning.visitor;
/**
* 抽象元素  动物
*/
public interface Animal {
    void accept(Person person);
}
5.1.4 具体元素
  • 1.实现accept操作,参数是一个访问者
package com.learning.visitor;
/**
* 狗
*/
public class Dog implements Animal{
    @Override
    public void accept(Person person) {
        person.feed(this);
        System.out.println("汪汪汪");
    }
}
package com.learning.visitor;

/**
 * 猫
 */
public class Cat implements Animal{
    @Override
    public void accept(Person person) {
        person.feed(this);
        System.out.println("喵喵喵");
    }
}
5.1.5 对象结构
  • 1.包含抽象元素的容器,提供让访问者对象遍历容器中所有元素的方法(List、Set、Map等)
  • 2.通过add方法,将具体的元素狗和猫放进List中
  • 3.提供遍历List中所有元素的方法action
package com.learning.visitor;

import java.util.ArrayList;
import java.util.List;

/**
 * 家
 */
public class Home {
    // 声明一个集合对象,用来存储元素对象
    private List<Animal> animalList = new ArrayList<>();

    // 添加元素功能
    public void add(Animal animal){
        animalList.add(animal);
    }

    public void action(Person person){
        //遍历集合,获取每一个元素,让访问者访问每一个元素
        for(Animal animal : animalList){
            animal.accept(person);
        }
    }
}

5.1.6 客户端类
package com.learning.visitor;

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        //创建home对象
        Home home = new Home();
        // 添加元素到home对象中
        home.add(new Dog());
        home.add(new Cat());

        //创建主人对象
        Owner owner = new Owner();
        // 主人喂猫
        home.action(owner);

        //创建其他人对象
        Someone someone = new Someone();
        //其他人喂食
        home.action(someone);
    }
}
5.1.7 结果示例

在这里插入图片描述

5.2 超市销售系统
5.2.1 业务场景
  • 1.假设现在要创建一个简单的超市销售系统,顾客将毛巾、饼干、酸奶等物品(Item)加入购物车(Shopping_Cart),在收银台(Checkout)人工(Manual)或自动(Auto)地将购物车中每个物品的价格汇总到总价格后结账。
5.2.2 业务需求类图

在这里插入图片描述

5.2.3 抽象访问者
  • 1.该场景下,抽象访问者为收银台Checkout
  • 2.定义访问具体元素的方法checkout,为每个具体元素类声明一个结账的方法,结账操作的参数类型标识了被访问的具体元素为毛巾、饼干和酸奶等
package com.learning.visitor.shop;

// 结账接口
interface Checkout {
    // 结账毛巾
    void checkout(Towel towel);

    // 结账饼干
    void checkout(Cookie cookie);

    // 结账酸奶
    void checkout(Yogurt yogurt);
}  
5.2.4 具体访问者
  • 1.具体访问者(ConcreteVisitor):实现抽象访问者中声明的各个结账操作
  • 2.人工结账实现抽象访问者中声明的结账毛巾、饼干、酸奶操作
  • 3.自动结账实现抽象访问者中声明的结账毛巾、饼干、酸奶操作
package com.learning.visitor.shop;

// 人工结账类
public class ManualCheckout implements Checkout {

    @Override
    public void checkout(Towel towel) {
        System.out.println("人工结账毛巾");
    }

    @Override
    public void checkout(Cookie cookie) {
        System.out.println("人工结账饼干");
    }

    @Override
    public void checkout(Yogurt yogurt) {
        System.out.println("人工结账酸奶");
    }
}
package com.learning.visitor.shop;

// 自动结账类
public class AutoCheckout implements Checkout {
    @Override
    public void checkout(Towel towel) {
        System.out.println("自动结账毛巾");
    }

    @Override
    public void checkout(Cookie cookie) {
        System.out.println("自动结账饼干");
    }

    @Override
    public void checkout(Yogurt yogurt) {
        System.out.println("自动结账酸奶");
    }
}
5.2.5 抽象元素
  • 1.定一个物品接口,声明一个接收一个结账方式的方法
  • 2.表明是哪种方式结账,其中方法的参数即收银台为被接受访问者
 package com.learning.visitor.shop;

// 物品接口
public interface Item {

    void accept(Checkout checkout);
    double getPrice();
    String getName();
}  
5.2.6 具体元素
  • 1.实现accept操作,参数是一个访问者即收银台
package com.learning.visitor.shop;

/**
 * 毛巾类
 */
public class Towel implements Item{

    @Override
    public void accept(Checkout checkout) {
        checkout.checkout(this);
    }

    @Override
    public double getPrice() {
        return 5.99;
    }

    @Override
    public String getName() {
        return "毛巾";
    }
}

package com.learning.visitor.shop;

/**
 * 饼干
 */
public class Cookie implements Item {
    @Override
    public void accept(Checkout checkout) {
        checkout.checkout(this);
    }

    @Override
    public double getPrice() {
        return 2.99;
    }

    @Override
    public String getName() {
        return "饼干";
    }
}

package com.learning.visitor.shop;

/**
 * 酸奶
 */
public class Yogurt implements Item {
    @Override
    public void accept(Checkout checkout) {
        checkout.checkout(this);
    }

    @Override
    public double getPrice() {
        return 1.99;
    }

    @Override
    public String getName() {
        return "酸奶";
    }
}

5.2.7 对象结构
  • 1.包含抽象元素的容器,提供让访问者对象遍历容器中所有元素的方法(List、Set、Map等)
  • 2.通过add方法,将具体的元素毛巾、饼干、酸奶放进List中
  • 3.提供遍历List中所有元素的方法action
package com.learning.visitor.shop;

import java.util.ArrayList;
import java.util.List;  
  
// 购物车类  
public class ShoppingCart {
    private List<Item> items = new ArrayList<>();  
  
    public void addItem(Item item) {  
        items.add(item);  
    }

    /**
     * 结账action
     * @param checkout
     */
    public void action(Checkout checkout) {
        for (Item item : items) {
            item.accept(checkout);
        }
    }  
}
5.2.8 客户端类
package com.learning.visitor.shop;

/**
 * 超市销售系统
 */
public class SupermarketSystem {
    public static void main(String[] args) {  
        // 创建物品  
        Item towel = new Towel();  
        Item cookie = new Cookie();
        Item yogurt = new Yogurt();  
  
        // 创建购物车并添加物品  
        ShoppingCart cart = new ShoppingCart();  
        cart.addItem(towel);  
        cart.addItem(cookie);
        cart.addItem(yogurt);  
  
        // 使用人工结账  
        ManualCheckout manualCheckout = new ManualCheckout();
        cart.action(manualCheckout);
  
        // 使用自动结账  
        AutoCheckout autoCheckout = new AutoCheckout();  
        cart.action(autoCheckout);
    }  
}
5.2.9 结果示例

在这里插入图片描述

5.2.10 改进
  • 1.结账接口可以把购物车作为参数进行结账
// 结账接口  
interface Checkout {  
    void checkout(ShoppingCart cart);  
}  
// 人工结账类  
class ManualCheckout implements Checkout {  
    @Override  
    public void checkout(ShoppingCart cart) {  
        System.out.println("Manual Checkout");  
        System.out.println("Total price: " + cart.getTotalPrice());  
        // 在这里执行人工结账的逻辑,比如接收现金或刷卡  
    }  
}  
// 自动结账类  
class AutoCheckout implements Checkout {  
    @Override  
    public void checkout(ShoppingCart cart) {  
        System.out.println("Auto Checkout");  
        System.out.println("Total price: " + cart.getTotalPrice());  
        // 在这里执行自动结账的逻辑,比如扫描条形码或使用移动支付  
    }  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1497932.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAR ADC学习笔记(4)

CDAC电容阵列 一、电容失配 二、电容失配对CDAC线性度的影响 1.电容失配对DNL的影响 2.电容失配对INL的影响 三、分段结构的CDAC 四、CDAC开关切换方案&#xff1a;传统开关切换策略 第一次比较阶段&#xff1a;如果VP(1)-VN(1)<0 第一次比较阶段&#xff1a;如果VP(1)-VN…

【Godot4.2】GDScript数组分类及类型化数组和紧缩数组概述

概述 GDScript的数组是一种很常用的数据类型。本文主要阐述一下GDScript数组分类&#xff0c;以及官方文档和大多数视频或教程较少提及的类型化数组和紧缩数组。 GDScript数组分类 通过反复查阅GDScript内置文档并进行细节比较&#xff0c;发现GDScript的数组&#xff0c;可…

LVS集群(Linux Virtual server)

集群概念lvs模型lvs调度算法lvs实现lvs高可用性&#xff0c;负载均衡 1 集群和分布式 系统性能扩展方式&#xff1a; Scale UP&#xff1a;垂直扩展&#xff0c;向上扩展,增强&#xff0c;性能更强的计算机运行同样的服务 升级单机的硬件设备Scale Out&#xff1a;水平扩展…

【DP】蓝桥杯第十三届-费用报销

#include<iostream> #include<algorithm> #include<cstring> #include<set> #include<queue> using namespace std; const int N1010; int dp[N][5010];//dp[i][j]:选到第i个物品是否能取到价值j&#xff1b; int month[13]{0,31,28,31,30,31,30…

Unity3D学习之XLua实践——背包系统

文章目录 1 前言2 新建工程导入必要资源2.1 AB包设置2.2 C# 脚本2.3 VSCode 的环境搭建 3 面板拼凑3.1 主面板拼凑3.2 背包面板拼凑3.3 格子复合组件拼凑3.4 常用类别名准备3.5 数据准备3.5.1 图集准备3.5.2 json3.5.3 打AB包 4 Lua读取json表及准备玩家数据5 主面板逻辑6 背包…

仓储管理系统(WMS) 的研发历程-PRD撰写

题外话&#xff1a;PRD的展现形式有多种&#xff0c;有的人喜欢在axure上直接做产品描述&#xff0c;觉得word较为过时&#xff0c;有的人认为axure不专业&#xff0c;任何展现形式都无可厚非&#xff0c;重要的达到PRD的目的&#xff0c;PRD的目标是让团队知道需求实现细节&am…

[数据结构初阶]队列

鼠鼠我呀&#xff0c;今天写一个基于C语言关于队列的博客&#xff0c;如果有兴趣的读者老爷可以抽空看看&#xff0c;很希望的到各位老爷观点和点评捏&#xff01; 在此今日&#xff0c;也祝各位小姐姐女生节快乐啊&#xff0c;愿笑容依旧灿烂如初阳&#xff0c;勇气与童真永不…

2024/3/7—2575. 找出字符串的可整除数组

代码实现&#xff1a; int* divisibilityArray(char *word, int m, int *returnSize) {int n strlen(word);int *res (int*)malloc(sizeof(int) * n);long cur 0;for (int i 0; i < n; i) {cur (cur * 10 (word[i] - 0)) % m;res[i] (cur 0) ? 1 : 0;}*returnSize …

[Unity实战]使用NavMeshAgent做玩家移动

其实除了Character Controller, Rigidbody&#xff0c;我们还可以使用NavMeshAgent去做。这么做的好处是能避免玩家去莫名其妙的地方&#xff08;毕竟基于烘焙过的导航网格&#xff09;&#xff0c;一般常见于元宇宙应用和mmo。 根据Unity手册&#xff0c;NavMeshAgent 也有和…

考研新手小白,必须提前了解的考研常识

关于考研需要知道的一些常识&#xff1a; 在大三上学期开学&#xff0c;通常是在9月左右&#xff0c;开始考虑选择学校和专业&#xff0c;购买相关资料&#xff0c;收集相关信息&#xff0c;启动研究生考试的复习计划。 接下来的年度&#xff08;即第四学年制的大四学期&…

C语言数据类型详解及相关题——各种奇奇怪怪的偏难怪

文章目录 一、C语言基本数据类型溢出 二、存储原理符号位原码反码补码补码操作的例子 三、赋值中的类型转换常见返回类型——巨坑总结 一、C语言基本数据类型 溢出 因为数据范围&#xff08;即存储单元的位的数量&#xff09;的限制&#xff0c;可以表达的位数是有限的。 溢出…

AtCoder Beginner Contest 343(A,B,C,D,E,F)

比赛链接 CE是暴力&#xff0c;D是数据结构题&#xff0c;F是线段树。这场的E比较有意思&#xff0c;其他的感觉有点水。 A - Wrong Answer 题意&#xff1a; 给你两个数 A , B A,B A,B ( 0 ≤ A , B ≤ 9 ) (0\le A,B\le 9) (0≤A,B≤9)&#xff0c;返回一个个位数&#…

手机app制作商用系统软件开发

手机端的用户占比已经超过了电脑端的用户量&#xff0c;企业想要发展手机端的业务就必须拥有自己的app软件&#xff0c;我们公司就是专门为企业开发手机软件的公司&#xff0c;依据我们多年的开发经验为大家提供在开发app软件的时候怎么选择开发软件的公司。 手机app制…

spring-jpa

一、介绍 1.1ORM 1.2 Java Persistence API 放在javaee版本 优点 支持持久化复杂的Java对象&#xff0c;简化Java应用的对象持久化开发支持使用JPQL语言进行复杂的数据查询使用简单&#xff0c;支持使用注解定义对象关系表之间的映射规范标准化&#xff0c;由Java官 方统一规…

阿里云服务器购买搭建

1.首先在阿里云官网购买ESC云服务器 2.在域名处&#xff0c;购买域名&#xff0c;申请免费的SSL证书&#xff0c;但是这个证书需要去备案&#xff0c;这个周期比较长。 3.登录你的服务器就可以安装你需要的环境&#xff0c;进行开发&#xff0c;当然使用docker很好用。 以下…

【开源物联网平台】FastBee认证方式和MQTT主题设计

&#x1f308; 个人主页&#xff1a;帐篷Li &#x1f525; 系列专栏&#xff1a;FastBee物联网开源项目 &#x1f4aa;&#x1f3fb; 专注于简单&#xff0c;易用&#xff0c;可拓展&#xff0c;低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 设备认证 1.2 设备交…

【Leetcode】3028.边界上的蚂蚁

题目描述 思路 题目中要求我们返回 蚂蚁返回到边界的次数。简单来想&#xff0c;就是蚂蚁原来的位置的一维坐标为0&#xff0c;然后经过&#xff0c;若干次移动&#xff0c;统计有几次坐标再次变为0的个数。 我们利用前缀和&#xff0c;像定义一个数组&#xff0c;算出前缀和数…

贪心算法详解及机器人运动应用Demo

一、引言 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。贪心算法在有最优子结构的问题中尤为有效。今天&#xff0c;我们将通过一个机器人运动的Demo来详细解析贪心算…

网络编程作业day7

作业项目&#xff1a;基于UDP的聊天室 服务器代码&#xff1a; #include <myhead.h>//定义客户信息结构体 typedef struct magtye {char type; //消息类型char name[100]; //客户姓名char text[1024]; //客户发送聊天信息 }msg_t;//定义结构体存储…

基于YOLOv5的驾驶员疲劳驾驶行为​​​​​​​检测系统

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要内容:详细介绍了疲劳驾驶行为检测整个过程&#xff0c;从数据集到训练模型到结果可视化分析。 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff09;YOLOv5、v7、v8优化创新&#xff0c;轻松涨点和模型轻量…