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

软件工程学习日志2025.11.17

今天的学习重点是设计模式中的享元模式,结合“围棋软件”的实验需求,完成了从需求分析、代码实现到类图绘制的全流程。过程中在Mermaid类图生成上踩了不少坑,最终摸索出兼容且逻辑正确的方案,特此记录整个过程,方便后续回顾。
一、实验需求拆解
本次实验要求设计一款围棋软件,核心约束是:系统中仅存在一个白棋对象和一个黑棋对象,却能在棋盘不同位置重复显示。同时需满足:

  1. 用享元模式实现对象复用(核心);
  2. 享元工厂类需结合单例模式和简单工厂模式;
  3. 提交完整的类图和源代码;
  4. 遵循编程规范。
    核心设计思路
  • 享元模式核心:区分“内部状态”(可共享,如棋子颜色)和“外部状态”(不可共享,如棋子位置);
  • 内部状态:黑棋/白棋的颜色,仅需各创建一个实例;
  • 外部状态:棋子在棋盘的坐标,通过独立类封装,每次显示时动态传入;
  • 工厂类:单例确保全局唯一,简单工厂负责创建和缓存享元对象。
    二、代码实现
  1. 外部状态类:Position(存储棋子坐标)
    public class Position {
    private int x;
    private int y;

    public Position(int x, int y) {
    this.x = x;
    this.y = y;
    }

    public int getX() {
    return x;
    }

    public int getY() {
    return y;
    }
    }

  2. 抽象享元类:Chess(定义棋子行为)
    public abstract class Chess {
    // 内部状态:棋子颜色(可共享)
    protected String color;

    public Chess(String color) {
    this.color = color;
    }

    // 抽象方法:结合外部状态(位置)显示棋子
    public abstract void display(Position pos);
    }

  3. 具体享元类:BlackChess/WhiteChess(实际棋子实例)
    public class BlackChess extends Chess {
    public BlackChess() {
    super("黑色");
    }

    @Override
    public void display(Position pos) {
    System.out.println("[" + color + "棋子] 落在位置:(" + pos.getX() + "," + pos.getY() + ")");
    }
    }

public class WhiteChess extends Chess {
public WhiteChess() {
super("白色");
}

@Override
public void display(Position pos) {System.out.println("[" + color + "棋子] 落在位置:(" + pos.getX() + "," + pos.getY() + ")");
}

}
4. 享元工厂类:ChessFactory(单例+简单工厂)
import java.util.HashMap;
import java.util.Map;

public class ChessFactory {
// 单例模式:饿汉式(线程安全)
private static final ChessFactory instance = new ChessFactory();

// 缓存容器:存储颜色-棋子的映射
private Map<String, Chess> chessMap;// 私有构造:初始化缓存,预创建黑棋和白棋实例
private ChessFactory() {chessMap = new HashMap<>();chessMap.put("black", new BlackChess());chessMap.put("white", new WhiteChess());
}// 获取单例工厂实例
public static ChessFactory getInstance() {return instance;
}// 简单工厂方法:根据颜色获取棋子实例(复用缓存)
public Chess getChess(String color) {String key = color.toLowerCase();if (!"black".equals(key) && !"white".equals(key)) {throw new IllegalArgumentException("仅支持黑色(black)和白色(white)棋子");}return chessMap.get(key);
}

}
5. 测试类:验证效果
public class ChessTest {
public static void main(String[] args) {
// 获取单例工厂
ChessFactory factory = ChessFactory.getInstance();

    // 多次获取黑棋/白棋,验证实例唯一性Chess black1 = factory.getChess("black");Chess black2 = factory.getChess("black");Chess white1 = factory.getChess("white");Chess white2 = factory.getChess("white");System.out.println("黑棋实例是否唯一:" + (black1 == black2)); // trueSystem.out.println("白棋实例是否唯一:" + (white1 == white2)); // true// 显示棋子在不同位置(复用实例,仅传递外部状态)black1.display(new Position(3, 3));black2.display(new Position(5, 5));white1.display(new Position(4, 4));white2.display(new Position(6, 6));
}

}
三、类图绘制:踩坑与最终方案

  1. 初始踩坑经历
    实验要求提交类图,最初尝试用Mermaid绘制时,多次生成失败,问题集中在:
  • 泛型格式不兼容(如Map<String, Chess>改为Map后解决);
  • 抽象类关键字abstract导致解析失败(最终去掉关键字,通过继承关系隐含抽象性);
  • 关系符号错误(曾误将ChessFactoryChess设为继承关系ChessFactory <|-- Chess,实际应为关联关系)。
  1. 类图
    classDiagram
    class Position {
    int x
    int y
    Position(int x, int y)
    getX()
    getY()
    }

    class Chess {
    String color
    Chess(String color)
    display(Position pos)
    }

    class BlackChess {
    BlackChess()
    display(Position pos)
    }

    class WhiteChess {
    WhiteChess()
    display(Position pos)
    }

    class ChessFactory {
    ChessFactory instance
    Map chessMap
    ChessFactory()
    getInstance()
    getChess(String color)
    }

    // 继承关系:具体享元继承抽象享元
    Chess <|-- BlackChess
    Chess <|-- WhiteChess

    // 关联关系:工厂缓存享元对象
    ChessFactory -- Chess

  2. 类图逻辑说明

  • 继承关系:BlackChessWhiteChess继承自Chess,符合享元模式“具体享元实现抽象享元”的结构;
  • 关联关系:ChessFactoryChess通过实线连接,表示工厂持有并缓存棋子实例;
  • 无复杂语法:去掉所有可能引发解析的关键字和标注,确保在任何Mermaid工具中都能生成成功。
    四、生成验证步骤
  1. 打开Mermaid官方在线编辑器(https://mermaid.live);
  2. 粘贴上述类图代码,右侧实时生成可视化类图;
  3. 点击顶部「Export」导出为PNG/JPG格式,即可用于实验提交。
    五、学习总结
  4. 享元模式的核心是“复用对象、分离内外状态”,适用于需要大量重复对象的场景(如围棋、文字处理软件中的字符);
  5. 工厂类结合单例+简单工厂,既能保证全局唯一的创建入口,又能通过缓存实现对象复用;
  6. Mermaid类图绘制需优先使用基础语法,避免过度依赖高级特性,确保兼容性;
  7. 类图的逻辑正确性至关重要,继承(is-a)和关联(has-a)关系不能混淆。
http://www.jsqmd.com/news/43026/

相关文章:

  • CSP2025 游记 + whk 期中
  • 论文速读 | 2025年11月
  • 2025-11-17
  • 九成九新自用C#入门文档
  • 商场展览车生产厂家十大排名及选购推荐,航利通达网红礼盒拖车公司,透明车厢生产厂家,车载展柜公司十大权威排行,商场展览车公司十大排名
  • Flask+Celery+Blueprint
  • 102302109-胡贝贝-作业3
  • hadoop linux 安装
  • 2025最新展柜设计公司推荐,展柜制作公司,展台源头厂家,烤漆展柜十大品牌推荐榜,家纺柜台供应厂家十大排行榜:梵之宇装饰推荐
  • 团队技术资产建设:从散兵游勇到标准化作战
  • 2025年11月学习机榜单:打破智商税偏见,十大提分机型实证推荐
  • 解决罗技M590右键必须用力才能使用的问题
  • 悼念故友
  • 题解:uoj632【UR #21】挑战最大团
  • [CSP-S 2025] 员工招聘 / employ
  • 20232410 2025-2026-1 《网络与系统攻防技术》实验六实验报告
  • 2025上海商铺办公室装修公司推荐指南:业态适配与TOP10实力榜
  • FastAPI Test Project
  • React Scheduler(调度器)
  • 2025年11月学习机榜单:双线提分机型领衔,十大高性价比之选
  • Day41(11)-F:\硕士阶段\Java\课程代码\后端\web-ai-code\web-ai-project02\tlias-web-management
  • vue2和vue3声明式和命令时的区别
  • WPS office 2023专业增强版 无限用v12.8 永久激活下载及安装使用教程
  • 3D Dynamic Scene Graph - MKT
  • 3D 文件类型,怎么在线查看编辑STL/AMF/OBJ/stp/fbx/ply转换
  • 022304105叶骋恺数据采集第三次作业
  • AI故事生成平台 -
  • nginx rewrite 状态码区别
  • GS4:首个泛化高斯溅射语义SLAM框架,十倍效率三维建图 - MKT
  • 2025 ICPC 南京区域赛 CFGIJ