java局域网聊天室小项目架构思路

java局域网聊天室小项目架构思路

项目需求

创建一个局域网聊天系统,要求:用户在登录界面登录后进入聊天窗口界面,能实现多用户同时在线聊天,并且用户之间可以进行私聊

项目用到的技术栈

  1. java网络编程
  2. java多线程
  3. java面向对象编程
  4. javaGUI技术(Swing)

第一步:创建项目并构建客户端登录界面与聊天窗口界面

创建项目

创建ChatRoom模块用于存放整个项目,其下创建Chat-Client与Chat-Server两个模块分别用于客户端与服务端的构建

登陆界面

登陆界面要有昵称输入框,用户可输入昵称,输入框下方有“登录”和“取消”两个按钮,两个按钮要绑定事件监听器,

登录按钮监测输入框中是否有文字,是则点击后关闭登录窗口,否则提示输入框不能为空,

取消按钮一旦点击则关闭登录窗口

利用通义千问来辅助完成登录界面

登录界面代码(初期)

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class ChatLoginUI extends JFrame implements ActionListener {// 定义界面组件private JLabel nicknameLabel;private JTextField nicknameField;private JButton loginButton;private JButton cancelButton;// 构造方法:初始化界面public ChatLoginUI() {// 设置窗口标题setTitle("聊天室登录界面");// 设置窗口大小setSize(400, 200);// 设置窗口关闭操作(关闭窗口时退出程序)setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置窗口居中显示setLocationRelativeTo(null);// 创建面板用于放置组件JPanel panel = new JPanel();panel.setLayout(new FlowLayout());// 创建昵称标签nicknameLabel = new JLabel("昵称:");panel.add(nicknameLabel);// 创建昵称输入框nicknameField = new JTextField(20);panel.add(nicknameField);// 创建登录按钮loginButton = new JButton("登录");loginButton.addActionListener(this); // 绑定事件监听panel.add(loginButton);// 创建取消按钮cancelButton = new JButton("取消");cancelButton.addActionListener(this); // 绑定事件监听panel.add(cancelButton);// 将面板添加到窗口add(panel);// 设置窗口可见setVisible(true);}// 按钮点击事件处理@Overridepublic void actionPerformed(ActionEvent e) {if (e.getSource() == loginButton) {// 获取输入框内容String nickname = nicknameField.getText().trim();// 验证昵称是否为空if (nickname.isEmpty()) {JOptionPane.showMessageDialog(this, "昵称不能为空!", "错误", JOptionPane.ERROR_MESSAGE);} else {// 显示昵称(示例:打印到控制台)System.out.println("登录成功,昵称:" + nickname);// 这里可以添加跳转到聊天室的逻辑dispose(); // 关闭登录窗口}} else if (e.getSource() == cancelButton) {// 取消按钮点击事件:关闭窗口dispose();}}
}

聊天窗口界面

聊天窗口界面左侧为聊天区右侧实时展示当前登录用户下方为聊天输入框和发送按钮,当输入文字后,点击发送按钮或者按下回车键即可发送消息到聊天区

借助通义千问来辅助完成

聊天窗口界面(初期)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class ChatRoom extends JFrame {private JTextArea chatTextArea;private JTextField messageField;private JButton sendButton;private JList<String> userList;private DefaultListModel<String> userListModel;public ChatRoom() {setTitle("Chat Room");setSize(800, 600);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);// 创建聊天区域chatTextArea = new JTextArea();chatTextArea.setEditable(false);JScrollPane chatScrollPane = new JScrollPane(chatTextArea);// 创建消息输入框和发送按钮JPanel inputPanel = new JPanel(new BorderLayout());messageField = new JTextField();sendButton = new JButton("Send");inputPanel.add(messageField, BorderLayout.CENTER);inputPanel.add(sendButton, BorderLayout.EAST);// 创建用户列表userListModel = new DefaultListModel<>();userList = new JList<>(userListModel);JScrollPane userScrollPane = new JScrollPane(userList);// 设置布局JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, chatScrollPane, userScrollPane);splitPane.setDividerLocation(600);getContentPane().add(splitPane, BorderLayout.CENTER);getContentPane().add(inputPanel, BorderLayout.SOUTH);// 添加发送按钮事件监听器sendButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});// 按Enter键发送消息messageField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});}private void sendMessage() {String message = messageField.getText().trim();if (!message.isEmpty()) {chatTextArea.append("You: " + message + "\n");messageField.setText("");}}// 更新用户列表的方法public void updateUserList(String[] users) {userListModel.clear();for (String user : users) {userListModel.addElement(user);}}
}

登录窗口与聊天窗口正常启动,第一步完成

第二步:构建局域网聊天室服务端

——先构建好服务器模块,再依据服务端逻辑构建客户端,因为服务端逻辑较为清晰简洁——

1.创建服务器启动端

  1. 由于聊天需要稳定传输,所以采用TCP通信方式
  2. 打印启动日志表确认服务端启动成功
  3. 循环监听并捕获客户端链接请求,为每个请求启动一个线程来处理(由于局域网通信人数少,并不会产生问题)

服务器启动端代码(初期)

package ServerTest;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;public class Server {public static void main(String[] args) {//创建服务器启动端try {ServerSocket server = new ServerSocket(ConstantServer.SERVER_PORT);//打印启动日志System.out.println("服务器启动成功...");//循环监听客户端连接while (true) {Socket socket = server.accept();//启动一个线程处理客户端请求new ServerReaderThread(socket).start();}} catch (Exception e) {e.printStackTrace();}}
}

2.创建服务器处理端

  1. 由于所有请求处理是同时进行的,所以采用多线程
  2. 用户发送来的消息包括1.登陆消息,2.群发消息,3.私聊消息
  3. 为每种消息设置标记进行区分,不同消息不同处理
  4. 客户端下线处理

由于需要保存用户信息,所以应该在服务器启动端设置一个唯一数组用于存储在线用户昵称在线用户管道,由于具有映射关系所以采用Map数组

public static final Map<Socket,String> userMap = new HashMap<>();

服务器处理端代码

package ServerTest;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.Map;public class ServerReaderThread extends Thread{private Socket socket;public ServerReaderThread(Socket socket){this.socket = socket;}@Overridepublic void run(){//开发服务端实现方法//1.获取客户端输入流try {DataInputStream dis = new DataInputStream(socket.getInputStream());//客户端的信息包括1.登录信息,2.群发消息,3.私聊消息while(true){int type = dis.readInt();switch (type) {case ConstantServer.LOGIN://登录信息//获取昵称,并且更新当前用户列表String nickname = dis.readUTF();Server.userMap.put(socket, nickname);updateUserList();break;case ConstantServer.GROUP_MESSAGE://群发消息String msg = dis.readUTF();String name = Server.userMap.get(socket);//设置群发消息方法groupMessage(msg,name);break;case ConstantServer.PRIVATE_MESSAGE://私聊消息String toName = dis.readUTF();String toMsg = dis.readUTF();privateMessage(toName,toMsg);}}} catch (Exception e) {System.out.println("客户端下线:"+socket.getInetAddress().getHostAddress());Server.userMap.remove(socket);updateUserList();}}private void privateMessage(String toName, String toMsg) {//将私聊信息先进行封装,再发送给指定客户端的socket管道StringBuilder sb = new StringBuilder();String name = Server.userMap.get(socket);LocalDateTime now = LocalDateTime.now();DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");sb.append(name).append(" ").append(df.format(now)).append("\r\n").append(toMsg).append("\r\n");//如果对方不在线,则向发送消息的客户端发送一个提示信息if(!Server.userMap.containsValue(toName)){try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantServer.PRIVATE_MESSAGE);dos.writeUTF("----对方不在线,请稍后再试----");return;} catch (Exception e) {e.printStackTrace();}}for(Socket socket:Server.userMap.keySet()){try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());if(Server.userMap.get(socket).equals(toName)){dos.writeInt(ConstantServer.PRIVATE_MESSAGE);dos.writeUTF(sb.toString());dos.flush();break;}} catch (Exception e) {e.printStackTrace();}}}private void groupMessage(String msg,String name) {//将群发消息转发给所有在线客户端Socket管道//封装消息StringBuilder sb = new StringBuilder();LocalDateTime now = LocalDateTime.now();DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");sb.append(name).append(" ").append(df.format(now)).append("\r\n").append(msg).append("\r\n");//发送消息for (Socket socket:Server.userMap.keySet()) {try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantServer.GROUP_MESSAGE);dos.writeUTF(sb.toString());dos.flush();//及时刷新} catch (Exception e) {e.printStackTrace();}}}private void updateUserList() {//更新在线用户列表//拿到所有在线客户端用户名称,将这些数据转发给全部在线客户端Socket管道Collection<String> users = Server.userMap.values();for (Socket socket:Server.userMap.keySet()) {try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantServer.LOGIN);dos.writeInt(users.size());for(String user:users){dos.writeUTF(user);}dos.flush();} catch (Exception e) {e.printStackTrace();}}}}

3.服务端各种常量

由于IP与端口等可变,所以将所有可变常量存放在一个类中,便于修改

package ServerTest;public class ConstantServer {public static final String SERVER_IP = "127.0.0.1";public static final int SERVER_PORT = 8888;public static final int LOGIN = 1;public static final int GROUP_MESSAGE = 2;public static final int PRIVATE_MESSAGE = 3;
}

第三步:连接客户端与服务端

1.完善登录界面功能

  1. 实现登录逻辑,将登录信息发送给服务端
  2. 实现切换窗口逻辑

登陆界面代码(完善后)

 @Overridepublic void actionPerformed(ActionEvent e) {if (e.getSource() == loginButton) {// 获取输入框内容String nickname = nicknameField.getText().trim();// 验证昵称是否为空if (nickname.isEmpty()) {JOptionPane.showMessageDialog(this, "昵称不能为空!", "错误", JOptionPane.ERROR_MESSAGE);} else {// 实现登录逻辑try {loginroom(nickname);} catch (Exception ex) {ex.printStackTrace();}// 这里可以添加跳转到聊天室的逻辑new ChatRoomUI(nickname,socket);dispose(); // 关闭登录窗口}} else if (e.getSource() == cancelButton) {// 取消按钮点击事件:关闭窗口dispose();}}private void loginroom(String nickname) throws Exception {//立即将登录消息发送给服务器socket = new Socket(ConstantClient.SERVER_IP,ConstantClient.SERVER_PORT);DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantClient.LOGIN);dos.writeUTF(nickname);dos.flush();}

2.完善聊天窗口功能

  1. 创建一个客户端接受信息类,用于接收服务端传回的信息,1.更新用户列表的消息,2.群发的消息,3.私聊的消息
  2. 将接收到的信息反映到用户界面上

客户端接受信息类

package UI;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;public class ClentReaderThread extends Thread{private Socket socket;private ChatRoomUI chatRoomUI;//每个管道对应一个界面private DataInputStream dis;public ClentReaderThread(Socket socket,ChatRoomUI chatRoomUI){this.socket = socket;this.chatRoomUI = chatRoomUI;}@Overridepublic void run(){try {dis = new DataInputStream(socket.getInputStream());//接受服务端发送的消息1.更新人数的消息,2.群发的消息,3.私聊的消息while(true){int type = dis.readInt();switch (type) {case ConstantClient.UPDATE_USERLIST://更新用户列表updateUserList();break;case ConstantClient.GROUP_MESSAGE://群发消息gotoshowmsg();break;case ConstantClient.PRIVATE_MESSAGE://私聊消息gotoshowPrivatemsg();break;}}} catch (Exception e) {e.printStackTrace();}}//接收私聊消息方法private void gotoshowPrivatemsg() throws Exception {String msg = dis.readUTF();chatRoomUI.showPrivateMsg(msg);}//接收群发消息方法private void gotoshowmsg() throws Exception {String msg = dis.readUTF();chatRoomUI.showMsg(msg);}//接收更新的用户列表方法private void updateUserList() throws Exception {int count = dis.readInt();String[] users = new String[count];for (int i = 0; i < count; i++) {users[i] = dis.readUTF();}chatRoomUI.updateUserList(users);}
}

聊天界面代码(完善后)

新增双击私发消息的功能

package UI;import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataOutputStream;
import java.net.Socket;public class ChatRoomUI extends JFrame {private JTextArea chatTextArea;private JTextField messageField;private JButton sendButton;private JList<String> userList;private DefaultListModel<String> userListModel;private Socket socket;private String nickname;public ChatRoomUI() {initFrame();setVisible(true);}public void initFrame(){setSize(800, 600);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);// 创建聊天区域chatTextArea = new JTextArea();chatTextArea.setEditable(false);JScrollPane chatScrollPane = new JScrollPane(chatTextArea);// 创建消息输入框和发送按钮JPanel inputPanel = new JPanel(new BorderLayout());messageField = new JTextField();sendButton = new JButton("Send");inputPanel.add(messageField, BorderLayout.CENTER);inputPanel.add(sendButton, BorderLayout.EAST);// 创建用户列表userListModel = new DefaultListModel<>();userList = new JList<>(userListModel);JScrollPane userScrollPane = new JScrollPane(userList);// 设置布局JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, chatScrollPane, userScrollPane);splitPane.setDividerLocation(600);getContentPane().add(splitPane, BorderLayout.CENTER);getContentPane().add(inputPanel, BorderLayout.SOUTH);// 添加发送按钮事件监听器sendButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});// 按Enter键发送消息messageField.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {sendMessage();}});// 添加用户列表双击事件监听器,用于私聊userList.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {// 判断是否为双击事件if (e.getClickCount() == 2) {// 获取选中的用户索引int selectedIndex = userList.getSelectedIndex();if (selectedIndex != -1) {// 获取选中的用户名String selectedUser = userListModel.getElementAt(selectedIndex);// 不能给自己发私聊消息if (!selectedUser.equals(nickname)) {// 弹出输入框,获取私聊内容String privateMessage = JOptionPane.showInputDialog(ChatRoomUI.this,"发送私聊消息给 " + selectedUser + ":", "私聊", JOptionPane.PLAIN_MESSAGE);// 发送私聊消息if (privateMessage != null && !privateMessage.trim().isEmpty()) {sendPrivateMessage(selectedUser, privateMessage.trim());}} else {// 提示不能给自己发消息JOptionPane.showMessageDialog(ChatRoomUI.this, "不能给自己发送私聊消息", "提示", JOptionPane.WARNING_MESSAGE);}}}}});}public ChatRoomUI(String nickname, Socket socket) {this();setTitle(nickname+"的聊天窗口");this.nickname = nickname;this.socket = socket;new ClentReaderThread(socket,this).start();}//发送群发消息到服务器方法private void sendMessage() {String message = messageField.getText().trim();if (!message.isEmpty()) {//将消息发送给服务器try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantClient.GROUP_MESSAGE);dos.writeUTF(message);dos.flush();messageField.setText("");} catch (Exception e) {e.printStackTrace();}}}//发送私聊消息到服务器的方法private void sendPrivateMessage(String toUser, String message) {try {DataOutputStream dos = new DataOutputStream(socket.getOutputStream());dos.writeInt(ConstantClient.PRIVATE_MESSAGE);dos.writeUTF(toUser);dos.writeUTF(message);dos.flush();chatTextArea.append("[私聊给 " + toUser + "] " + message + "\n");} catch (Exception e) {e.printStackTrace();}}//展示更新用户列表方法public void updateUserList(String[] users) {userListModel.clear();for (String user : users) {userListModel.addElement(user);}}//展示群发消息方法public void showMsg(String msg) {if (!msg.isEmpty()) {chatTextArea.append(msg + "\n");messageField.setText("");}}//展示私聊消息方法public void showPrivateMsg(String msg) {if (!msg.isEmpty()) {chatTextArea.append("[私聊] " + msg + "\n");}}
}

项目地址https://gitcode.com/2401_88685396/myfirstgitcodeofjava

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

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

相关文章

vulhub-corrosion2靶机

1.安装靶机 https://download.vulnhub.com/corrosion/Corrosion2.ovahttps://download.vulnhub.com/corrosion/Corrosion2.ova 2.扫描IP 3.扫描端口 4.访问端口 首先访问一下80端口 访问一个8080端口发现是一个apache的页面 5.扫描目录与漏洞探测 那么我们扫描一下目录 80…

Mysql深入学习:慢sql执行

目录 慢查询日志 慢查询主要步骤 11种慢查询的场景分析 场景一&#xff1a;SQL 没有建立索引 场景二&#xff1a;索引未生效的典型原因 场景三&#xff1a;LIMIT 深分页导致性能下降 场景四&#xff1a;单表数据量过大导致 SQL 性能下降 场景五&#xff1a;ORDER BY 出现…

李宏毅深度学习教程 第8-9章 生成模型+扩散模型

【2025版】12 生成式对抗网络GAN 一 – 基本概念介紹_哔哩哔哩_bilibili 目录 1. GAN生成式对抗网络 2. GAN的训练 散度差异 3.WGAN 4.训练GAN 5. 如何客观评估GAN 6. 条件型生成&#xff08;按照要求&#xff09; 7. Cycle GAN&#xff08;互转配对&#xff09; 8. d…

1.8 axios详解

Axios的定义与核心特性Axios是一个基于Promise的现代化HTTP客户端库&#xff0c;主要用于在浏览器和Node.js 环境中发送HTTP请求&#xff0c;旨在简化异步数据交互流程。其核心特性如下&#xff1a;跨平台支持&#xff1a;在浏览器中通过XMLHttpRequest对象发送请求&#xff0c…

41.安卓逆向2-frida hook技术-过firda检测(五)-利用ida分析app的so文件中frida检测函数过检测

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…

安卓调javaScript Not find method “forceLogout“ implementatidsignature or namesp

核对一下是否实现对应的javaScript或者javaScript的方法参数对不对&#xff0c; 在这里插入图片描述我这里一开始实现了这个方法但是没有给参数&#xff0c;一直报异常&#xff0c;后台说token没给就查token的问题&#xff0c;最后发现是搞偏了&#xff0c;两个原因&#xff0c…

【Linux网络】:UDP(传输层协议)

目录 一、铺垫知识 1、传输层 2、端口号 2.1、五元组表示 一个进程通信 2.2、端口号范围划分 2.3、知名端口 2.4、查看端口号 2.5、问题 3、pidof & netstat 命令 ①netsate 命令 ②pidof命令 二、UDP协议 1、UDP协议格式 2、UDP报文 1.1、UDP数据封装的过…

Effective C++ 条款19: 设计class犹如设计type

Effective C 条款19&#xff1a;设计class犹如设计type核心思想&#xff1a;设计新的class时&#xff0c;应当像语言设计者设计内置类型一样慎重&#xff0c;考虑对象的创建、销毁、初始化、拷贝、类型转换等所有方面。 ⚠️ 1. 类设计的关键问题域 对象生命周期管理&#xff1…

《汇编语言:基于X86处理器》第11章 MS-Windows编程(3)

本章展示的是如何用32 位Microsoft Windows API进行控制台窗口编程。应用编程接口(API:ApplicationProgramming Interface)是类型、常数和函数的集合体&#xff0c;它提供了一种用计算机代码操作对象的方式。本章将讨论文本I/O、颜色选择、时间与日期、数据文件I/O&#xff0c;…

在 macOS 上通过 Docker 部署DM8 (ARM 架构)

概述 达梦数据库 (DM8) 无法直接在 Apple macOS 操作系统上原生安装&#xff0c;通常需要通过虚拟机&#xff08;如 Parallels Desktop、VMware Fusion&#xff09;进行部署。另一种更轻量级且受 macOS 支持的方案是利用 Docker 容器技术来构建开发与测试环境。本文档将详细介…

网络协议之路由是怎么回事?

写在前面 要想去外面的世界看看, 就离不了路由器&#xff0c;而路由器工作的原理就是路由&#xff0c;那么具体是怎么路由的呢&#xff1f;本文就一起来看下这部分内容。 1&#xff1a;路由的配置 配置一条路由无非就是在配置以下三个信息&#xff1a; 1:包要去哪里&#x…

2106. 摘水果,梳理思路

文章目录题目概要java 解法详解题目概要 在一个无限的 x 坐标轴上&#xff0c;有许多水果分布在其中某些位置。给你一个二维整数数组 fruits &#xff0c;其中 fruits[i] [positioni, amounti] 表示共有 amounti 个水果放置在 positioni 上。fruits 已经按 positioni 升序排列…

深入理解消息队列(MQ)核心原理与设计精髓

引言&#xff1a;从一个“不堪重负”的订单系统说起想象一个简化的电商下单流程&#xff1a;用户点击“下单”后&#xff0c;系统需要&#xff1a;在订单数据库中创建一条记录。调用库存服务&#xff0c;扣减商品库存。调用营销服务&#xff0c;给用户发放积分和优惠券。调用通…

前端手撕题总结篇(算法篇——来自Leetcode牛客)

链表指定区域反转 找到区间&#xff08;头和为 for循环当**时&#xff09;->反转链表&#xff08;返回反转过后的头和尾&#xff09;->连接 function reverseBetween( head , m , n ) {//preEnd&cur&nextStart cur.next断开if(mn)return head;const vHeadNode…

从Excel到工时管理系统:企业如何选择更高效的工时记录工具?

还在为手工统计员工工时而头疼吗&#xff1f;月末堆积如山的Excel表格、反复核对的数据、层出不穷的差错&#xff0c;这些问题正在拖慢企业的发展步伐。8Manage工时管理系统发现&#xff0c;传统手工记录不仅耗费大量人力&#xff0c;更让宝贵的工时数据难以转化为有效的管理决…

Java设计模式之《命令模式》

目录 1、介绍 1.1、命令模式定义 1.2、对比 1.3、典型应用场景 2、命令模式的结构 2.1、组成部分&#xff1a; 2.2、整体流程 3、实现 3.1、没有命令模式 3.2、命令模式写法 4、命令模式的优缺点 前言 java设计模式分类&#xff1a; 1、介绍 1.1、命令模式定义 命…

【动态规划算法】路径问题

什么是动态规划算法动态规划&#xff08;Dynamic Programming&#xff0c;简称 DP&#xff09;是一种通过分解复杂问题为重叠子问题&#xff0c;并存储子问题的解以避免重复计算&#xff0c;从而高效求解具有特定性质&#xff08;重叠子问题、最优子结构&#xff09;问题的算法…

Java基本技术讲解

一、基础语法三要素 暂时无法在飞书文档外展示此内容 &#x1f511; 黄金法则​&#xff1a;每个变量都要声明类型&#xff01;二、程序逻辑控制&#xff08;游戏行为核心&#xff09; 条件判断&#xff1a;if-else - “岔路口选择” // 捡到金币逻辑 if (isTouching(Coin.clas…

【网络基础2】路由器的 “两扇门”:二层接口和三层接口到底有啥不一样?

目录 前言:路由器不是只有 “插网线的口” 一、先搞懂一个基础:路由器是 “网络交通枢纽” 二、二层接口:“小区内部的单元门”,只认 “住户身份证” 1. 啥是二层接口? 2. 用 “小区内部串门” 理解二层接口 步骤 1:手机打包数据,写上 “收件人身份证” 步骤 2:二…

MLIR TableGen

简介 TableGen 是一种领域特定语言&#xff08;DSL&#xff09;&#xff0c;TableGen 的设计目标是允许编写灵活的描述&#xff0c;并将记录的通用特性提取出来&#xff0c;从而减少重复代码并提高代码的可维护性。 TableGen的工作流程&#xff1a; 前端解析&#xff1a; Ta…