我用 ChatGPT 学设计模式之访问者模式

news/2024/10/25 15:19:52/

作者:明明如月学长, CSDN 博客专家,蚂蚁集团高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。

热门文章推荐

  • (1)《人工智能时代,软件工程师们将会被取代?》
  • (2)《超全人工智能 AI工具导航网站合集》
  • (3)《如何写出高质量的文章:从战略到战术》
  • (4)《我的技术学习方法论》
  • (5)《什么? 你还没用过 Cursor? 智能 AI 代码生成工具 Cursor 安装和使用介绍》
  • (6)《我的性能方法论》
  • (7)《AI 时代的学习方式: 和文档对话》
  • (8)《人工智能终端来了,你还在用过时的 iterm?》
  • (9)《无需魔法打开即用的 AI 工具集锦》

一、背景

最近需要调研如何将 SQL 中的表名解析出来。
通过对 New Bing 不断提问,得知 com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser可以实现这个功能。

继续对 New Bing 进行提问,让 New Bing 帮我们写出 Demo 代码:
在这里插入图片描述

能不能使用Java 语言,借助 com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser 将下面的 SQL 中 表名 user 提取出来, SQL : select * form user where userId =10086。

New Bing 的回复:可以使用 Java 语言,借助 com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser 将 SQL 中的表名 user 提取出来。这是一个可能的代码示例:

import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;public class Main {public static void main(String[] args) {String sql = "select * from user where userId = 10086";MySqlStatementParser parser = new MySqlStatementParser(sql);SQLStatement statement = parser.parseStatement();SchemaStatVisitor visitor = new SchemaStatVisitor();statement.accept(visitor);System.out.println(visitor.getTables().keySet()); // 输出 [user]}
}

从这份代码中我们发现, druid 中使用了访问者模来实现这部分功能。
于是,我们趁机学习一下访问者模式吧。

二、访问者模式

2.1 使用场景

访问者模式是一种行为型设计模式,它可以让你在不修改对象结构的情况下,为对象结构中的元素添加新的操作。
访问者模式的应用场景是:

  • 当你有一个复杂的对象结构(例如一个对象树),并且想在不改变这个结构的前提下,对其中的元素执行不同的操作,而且这些操作可能随着时间的推移而发生变化。
  • 当你想将一些与数据结构无关的行为封装到一个类中,而不是分散在多个类中,从而提高代码的可维护性和复用性。

一个典型的例子是 Java 的 ASM 库,它可以用来操作字节码。ASM 提供了一个抽象的访问者接口,让用户可以自定义访问者类来实现对字节码的各种操作,例如修改、增加、删除、优化等。这样,ASM 就可以保持其核心功能的稳定性,同时提供了灵活的扩展性。

2.2 代码示例

有两种类型的游戏:收费游戏和免费游戏,它们都是被访问者。
有两种类型的玩家:付费玩家和免费玩家,它们都是访问者。
不同类型的玩家对不同类型的游戏有不同的操作,例如付费玩家可以下载收费游戏,而免费玩家只能试玩收费游戏。这些操作都是通过访问者模式来实现的,代码如下:

// Game 父类 ( 被访问者 )
public abstract class Game {// 游戏名称private String name;// 游戏价格private double price;public Game(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public double getPrice() {return price;}// 接受访问者的访问public abstract void accept(IVisitor visitor);
}// VipGame 收费游戏 ( 被访问者 )
public class VipGame extends Game {public VipGame(String name, double price) {super(name, price);}@Overridepublic void accept(IVisitor visitor) {// 调用访问者的访问方法visitor.visit(this);}
}// FreeGame 免费游戏 ( 被访问者 )
public class FreeGame extends Game {public FreeGame(String name, double price) {super(name, price);}@Overridepublic void accept(IVisitor visitor) {// 调用访问者的访问方法visitor.visit(this);}
}// IVisitor 访问者接口
public interface IVisitor {// 访问收费游戏void visit(VipGame vipGame);// 访问免费游戏void visit(FreeGame freeGame);
}// VipVisitor 付费玩家 ( 访问者 )
public class VipVisitor implements IVisitor {@Overridepublic void visit(VipGame vipGame) {System.out.println("付费玩家可以下载收费游戏:" + vipGame.getName() + ",价格为:" + vipGame.getPrice());}@Overridepublic void visit(FreeGame freeGame) {System.out.println("付费玩家可以下载免费游戏:" + freeGame.getName() + ",价格为:" + freeGame.getPrice());}
}// FreeVisitor 免费玩家 ( 访问者 )
public class FreeVisitor implements IVisitor {@Overridepublic void visit(VipGame vipGame) {System.out.println("免费玩家只能试玩收费游戏:" + vipGame.getName() + ",价格为:" + vipGame.getPrice());}@Overridepublic void visit(FreeGame freeGame) {System.out.println("免费玩家可以下载免费游戏:" + freeGame.getName() + ",价格为:" + freeGame.getPrice());}
}// 测试类
public class Test {public static void main(String[] args) {// 创建两个游戏对象Game vipGame = new VipGame("英雄联盟", 99.9);Game freeGame = new FreeGame("消消乐", 0);// 创建两个玩家对象IVisitor vipVisitor = new VipVisitor();IVisitor freeVisitor = new FreeVisitor();// 付费玩家访问两个游戏对象vipVisitor.visit(vipGame);vipVisitor.visit(freeGame);// 免费玩家访问两个游戏对象freeVisitor.visit(vipGame);freeVisitor.visit(freeGame);}
}

输出结果为:

付费玩家可以下载收费游戏:英雄联盟,价格为:99.9
付费玩家可以下载免费游戏:消消乐,价格为:0.0
免费玩家只能试玩收费游戏:英雄联盟,价格为:99.9
免费玩家可以下载免费游戏:消消乐,价格为:0.0

2.3 优、缺点

访问者模式的优点有:

  • 可以将与数据结构无关的操作封装到访问者类中,从而实现了操作和数据结构的分离,提高了代码的可维护性和复用性
  • 可以在不修改数据结构的前提下,为数据结构添加新的操作,提高了系统的扩展性
  • 可以利用双分派技术,实现多态和动态绑定

访问者模式的缺点有:

  • 增加了系统的复杂性,需要定义访问者接口和具体访问者类,以及被访问者的抽象类和具体类。
  • 违反了迪米特原则,访问者需要暴露被访问者的细节,从而降低了系统的封装性。
  • 增加了耦合,如果数据结构发生变化,需要修改所有的访问者类,降低了系统的稳定性。

四、总结

大家在日常开发中见到某种设计模式的影子时,可以去源码中学习该功能是如何使用该设计模式来实现的。主动重温该设计模式的适用场景,该设计模式的优点和缺点。这样才能够对该设计模式理解更加深刻,才更容易在未来遇到相关场景时想到该设计模式并加以致用。


创作不易,如果本文对你有帮助,欢迎点赞、收藏加关注,你的支持和鼓励,是我创作的最大动力。
在这里插入图片描述

欢迎加入我的知识星球,知识星球ID:15165241 一起交流学习。
https://t.zsxq.com/Z3bAiea 申请时标注来自CSDN。

欢迎加入我们的 slack 工作区,在里面可以对ai 和我进行提问。
https://join.slack.com/t/ai-yx51081/shared_invite/zt-1t8cp1lk3-ZMAFutZcN3PCW~8WQDGjPg


http://www.ppmy.cn/news/959499.html

相关文章

【C++】C++11 (3): lambda表达式和包装器

一、lambda表达式 C98中的一个例子 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法。 #include <algorithm> #include <functional> int main() {int a[] { 4,1,8,5,3,7,0,9,2,6 };// 默认按照小于比较&#xff…

50+ 可以帮助提高前端开发效率的 ChatGPT Prompts

大厂技术 高级前端 Node进阶 点击上方 程序员成长指北&#xff0c;关注公众号 回复1&#xff0c;加入高级Node交流群 如果你已经厌倦了繁琐重复的编码日常&#xff0c;想要提升自己的效率&#xff0c;那你可是来对地方了&#xff01;借助 ChatGPT 的强大能力&#xff0c;你可…

ChatGPT 前端 = 有点er意思

HOT! HOT! HOT! &#x1f525; &#x1f525; &#x1f525; 首先我们先来看下最近的热度来的有多么的突然&#xff0c;那简直是太炸裂了&#xff0c;语言不好描述&#xff0c;我收集了一些常见平台的指数截图&#xff0c;大家可以感受一下&#xff1a; 点击跳转到百度指数 …

ChatGPT对前端程序员有什么帮助?

如果你是一名前端程序员&#xff0c;那么你一定会遇到各种问题。有时候你可能会感觉自己被卡住了&#xff0c;就算是最简单的问题也无法解决。这时候&#xff0c;ChatGPT就能够派上用场了。 ChatGPT是什么&#xff1f; ChatGPT是一种基于人工智能的聊天机器人&#xff0c;它的…

ChatGpt学习angular

用angular12 封装一个可以统计输入的字符的textarea组件 您可以使用 Angular 12 实现一个带有字符统计功能的 textarea 组件&#xff0c;以下是一个示例实现&#xff1a; // textarea.component.ts import { Component, Output, EventEmitter, ViewEncapsulation } from angu…

前端同学都是如何玩转 ChatGPT 的???

ChatGPT最近一周忽然登上了国内各大平台的热搜榜&#xff0c;应该在去年11月末的时候就有不少同学了解并使用过&#xff0c;那个时候它刚刚问世&#xff0c;在互联网圈子里有了很大的热度&#xff0c;但是对于大众来说&#xff0c;还是不太了解的。 我在去年的时候就跟风注册了…

Spring、SpringBoot、SpringCloud、SpringCloud Alibaba、Elasticsearch版本对应,附下载地址

1、GitHub Alibaba 发布SpringCloud Alibaba和SpringCloud 、SpringBoot版本 Spring Cloud Alibaba VersionSpring Cloud VersionSpring Boot2022.0.0.0-RC2Spring Cloud 2022.0.03.02022.0.0.0-RC1Spring Cloud 2022.0.03.0.02021.0.5.0*Spring Cloud 2021.0.52.6.132021.0.4…

用chatgpt重构代码,优化代码,体验蛮惊艳

下面纯属探索ChatGPT于重构代码、辅助编程方面的可能性&#xff0c;实际工作是否如此&#xff0c;不予讨论。下面1代表提问者&#xff0c;2为ChatGPT。整个过程的体验令人震撼&#xff0c;几乎感觉被高手环绕指导&#xff0c;人工智能潜力不可限量。 import osimport openai fr…