优化策略模式,提高账薄显示的灵活性和扩展性

接着上一篇文章,账薄显示出来之后,为了提高软件的可扩展性和灵活性,我们应用策略设计模式。这不仅仅是为了提高代码的维护性,而是因为明细分类账账薄显示的后面有金额分析这个功能,从数据库后台分析及结合Java语言特性,类似数据转置,也是软件复杂度提出的一个客观优化需求。

定义策略接口

为了软件的简易性,我们采用拖拖拉拉就可形成各种界面元素的设计方式,它虽然降低的前端开发人员的难度,可以轻松应用CSS配置文件提高视图界面的灵活性,但后台的处理多了更多的规则。大的基本结构是一个控制器中同时又镶嵌多个控制器。所以,我们定义策略模式的接口如下:

/*** 为了方便扩展,抽象显示方式,目前子类应该包括总分类账和明细分类账*/
public interface ShowZhangBen {/**** @param showZongZhangKeMu  要显示的账薄科目* @param keMuController 主科目界面的控制器* @throws IOException 由于从FXML文件加载要处理异常*/void showZhangBo(KeMu showZongZhangKeMu, KeMuController keMuController) throws IOException;}

实现基本的总分类账和明细分类账的接口实现类

当下业务需要二级科目已经满足要求,所以,我们先实现这两个策略实现类。按模式惯例,在科目主控制器中增加策略成员接口属性,然后点击科目,根据点击的科目不同,去自动的调用策略类的对应实现方式。之所以将策略做为成员属性,是因为不同的策略不光是显示方式的不同,包括后台处理和其它应该会有很多扩展类都会用引用到,所以没有从形式参数方法注入,而是从相应的策略实现类中去设置科目控制器成员属性;另一个考虑的这样做的原因是:在策略实现类中,有一次控制器重新从FXML文件加载的过程,这样加策略引用交付给主控制器,更好的体现了,子控制器不仅是一个控制器,同时是一个策略的双重角色,让主界面控制器的掌控能力更加充分。

具体的实现过程代码如下:

  /*** 显示总分类账* @return 显示面板*/@Overridepublic void showZhangBo(KeMu showZongZhangKeMu, KeMuController keMuController) throws IOException {if (showZongZhangKeMu != null && showZongZhangKeMu.getKeMuLevel().equals("1"))        //总分类账{keMuController.setStrategyShowZhangBen(new ZhangBenController());}else if (showZongZhangKeMu != null && showZongZhangKeMu.getKeMuLevel().equals("2")) {keMuController.setStrategyShowZhangBen(new MingXiZhangController());keMuController.getStrategyShowZhangBen().showZhangBo(showZongZhangKeMu,keMuController);return;}FXMLLoader loader2 = new FXMLLoader();InputStream in = ZhangBenController.class.getResourceAsStream("/zhangBen/zhangBen.fxml");loader2.setBuilderFactory(new JavaFXBuilderFactory());loader2.setLocation(ZhangBenController.class.getResource("/zhangBen/zhangBen.fxml"));AnchorPane page;try {page = (AnchorPane) loader2.load(in);keMuController.setStrategyShowZhangBen(loader2.getController());} finally {in.close();}/*** 控制器自转移*/lbeZhangbBoName=((ZhangBenController)keMuController.getStrategyShowZhangBen()).getLbeZhangbBoName();lvZongZhang=((ZhangBenController)keMuController.getStrategyShowZhangBen()).lvZongZhang;apZongZhang=((ZhangBenController)keMuController.getStrategyShowZhangBen()).apZongZhang;apZongZhangBo=((ZhangBenController)keMuController.getStrategyShowZhangBen()).apZongZhangBo;setShowKeMu(showZongZhangKeMu);lbeZhangbBoName.setText(showKeMu.getKeMuName()+"总分类账");List<ZongZhang> listData= getDataFromSpiZongZhang(showKeMu.getStrDbId());data = FXCollections.observableArrayList(listData);//给表格加上行数 2022-08-25TableColumn idCol = new TableColumn();idCol.setText("日期");idCol.setCellValueFactory(new PropertyValueFactory("recordDate"));//  idCol.setVisible(false);TableColumn taskIdCol = new TableColumn();taskIdCol.setText("凭证号数");taskIdCol.setCellValueFactory(new PropertyValueFactory("strPingZhengNo"));TableColumn costNameCol = new TableColumn();costNameCol.setText("摘要");costNameCol.setCellValueFactory(new PropertyValueFactory("strZhaiYao"));TableColumn thisAmountCol = new TableColumn();thisAmountCol.setText("√");thisAmountCol.setMinWidth(200);thisAmountCol.setCellValueFactory(new PropertyValueFactory("strCheckFlag"));TableColumn taskDateCol = new TableColumn();taskDateCol.setText("借方");taskDateCol.setMinWidth(200);taskDateCol.setCellValueFactory(new PropertyValueFactory("strJieFangAmount"));TableColumn employeeCol = new TableColumn();employeeCol.setText("贷方");employeeCol.setMinWidth(200);employeeCol.setCellValueFactory(new PropertyValueFactory("strDaiFangAmount"));TableColumn operDateCol = new TableColumn();operDateCol.setText("借或贷");operDateCol.setMinWidth(200);operDateCol.setCellValueFactory(new PropertyValueFactory("strAmountDirect"));TableColumn yuErCol = new TableColumn();operDateCol.setText("余额");operDateCol.setMinWidth(200);operDateCol.setCellValueFactory(new PropertyValueFactory("strYuAmount"));// final TableView tableView = new TableView();lvZongZhang.getColumns().clear();lvZongZhang.setItems(data);lvZongZhang.getColumns().addAll(idCol, taskIdCol, costNameCol, thisAmountCol, taskDateCol, employeeCol, operDateCol,yuErCol);apZongZhangBo.getChildren().remove(lvZongZhang);apZongZhangBo.getChildren().add(lvZongZhang);setKeMuController(keMuController);keMuController.showDetailAnchorPaneView(apZongZhangBo);}

之所以将科目层级和科目账薄类型的判断下移到策略实现类中,通过策略路由的方式去处理,为了在主界面控制器中增加新的策略时减少或没有代码的修改,虽然你增加了一点点代码,换来了主界面程序的扩展性,这可以根据自己需要决定,你认为直接在主界面中去判断然后确定策略类,这种效率更高,那也是可以的。眼下我追求的只是扩展性和健壮能性,相应的明细分类账的实现类如下:

 /*** 显示总分类账* @return 显示面板*/@Overridepublic void showZhangBo(KeMu showZongZhangKeMu, KeMuController keMuController) throws IOException {// 使用 Context 来查看当它改变策略 Strategy 时的行为变化。if (showZongZhangKeMu != null && showZongZhangKeMu.getKeMuLevel().equals("1"))        //总分类账{keMuController.setStrategyShowZhangBen(new ZhangBenController());keMuController.getStrategyShowZhangBen().showZhangBo(showZongZhangKeMu,keMuController);return;}else if (showZongZhangKeMu != null && showZongZhangKeMu.getKeMuLevel().equals("2")) {keMuController.setStrategyShowZhangBen(new MingXiZhangController());showZongZhangKeMu = keMuController.convertChooseToParentKeMu(showZongZhangKeMu);}FXMLLoader loader2 = new FXMLLoader();InputStream in = MingXiZhangController.class.getResourceAsStream("/zhangBen/mingXiZhang.fxml");loader2.setBuilderFactory(new JavaFXBuilderFactory());loader2.setLocation(MingXiZhangController.class.getResource("/zhangBen/mingXiZhang.fxml"));AnchorPane page;try {page = (AnchorPane) loader2.load(in);keMuController.setStrategyShowZhangBen(loader2.getController());} finally {in.close();}/*** 控制器自转移*/lbeZhangbBoName=((MingXiZhangController)keMuController.getStrategyShowZhangBen()).getLbeZhangbBoName();apZongZhangBo=((MingXiZhangController)keMuController.getStrategyShowZhangBen()).apZongZhangBo;lvMingXiZhang=((MingXiZhangController)keMuController.getStrategyShowZhangBen()).lvMingXiZhang;apMingXiZhang=((MingXiZhangController)keMuController.getStrategyShowZhangBen()).apMingXiZhang;setShowKeMu(showZongZhangKeMu);lbeZhangbBoName.setText(showKeMu.getKeMuName()+"明细账");List<MingXiZhang> listData= getDataFromSpiMingXiZhang(showKeMu.getStrDbId());data = FXCollections.observableArrayList(listData);//给表格加上行数 2022-08-25TableColumn idCol = new TableColumn();idCol.setText("日期");idCol.setCellValueFactory(new PropertyValueFactory("recordDate"));//  idCol.setVisible(false);TableColumn taskIdCol = new TableColumn();taskIdCol.setText("凭证号数");taskIdCol.setCellValueFactory(new PropertyValueFactory("strPingZhengNo"));TableColumn costNameCol = new TableColumn();costNameCol.setText("摘要");costNameCol.setCellValueFactory(new PropertyValueFactory("strZhaiYao"));TableColumn taskDateCol = new TableColumn();taskDateCol.setText("借方");taskDateCol.setMinWidth(200);taskDateCol.setCellValueFactory(new PropertyValueFactory("strJieFangAmount"));TableColumn daiFangCol = new TableColumn();daiFangCol.setText("贷方");daiFangCol.setMinWidth(200);daiFangCol.setCellValueFactory(new PropertyValueFactory("strDaiFangAmount"));TableColumn directCol = new TableColumn();directCol.setText("借或贷");directCol.setMinWidth(20);directCol.setCellValueFactory(new PropertyValueFactory("strAmountDirect"));TableColumn yuErCol = new TableColumn();yuErCol.setText("余额");yuErCol.setMinWidth(200);yuErCol.setCellValueFactory(new PropertyValueFactory("strYuAmount"));TableColumn[] AmountCol = new TableColumn[13];for(int i=0;i<13;i++){AmountCol[i]=new TableColumn();AmountCol[i].setText("金额分析"+String.valueOf(i+1));AmountCol[i].setMinWidth(200);AmountCol[i].setCellValueFactory(new PropertyValueFactory("amountFenXi"+String.valueOf(i+1)));}// final TableView tableView = new TableView();lvMingXiZhang.getColumns().clear();lvMingXiZhang.setItems(data);lvMingXiZhang.getColumns().addAll(idCol, taskIdCol, costNameCol, taskDateCol, daiFangCol, directCol,yuErCol);for (int i=0;i<AmountCol.length;i++){lvMingXiZhang.getColumns().add(AmountCol[i]);}apZongZhangBo.getChildren().remove(lvMingXiZhang);apZongZhangBo.getChildren().add(lvMingXiZhang);setKeMuController(keMuController);keMuController.showDetailAnchorPaneView(apZongZhangBo);}

至此,基本功能完成。

策略模式环境角色的客户端调用

        这儿策略模式环境角色的特别之处在于它本身可能是通过FXML文件加载进去的类,大概率情况如下,所以我们不用在意从构造方法中去注入策略接口去赋值,通过get和set方法是最佳途径,这儿的代码就比较简单了,不过也要注意捕捉异常,代码如下:

  @Overridepublic void changed(ObservableValue<? extends TreeItem<KeMu>> observable, TreeItem<KeMu> oldValue, TreeItem<KeMu> newValue) {System.out.println("选择的新值是:" + newValue.getValue());KeMu chooseKeMu = newValue.getValue();try {keMuController.getStrategyShowZhangBen().showZhangBo(chooseKeMu, keMuController);} catch (IOException e) {throw new RuntimeException(e);}}

完成后,运行程序,效果如下图。至此,账薄的基本显示功能完成了,这只是相当于买回来两个账薄,价值也就是二三十无人民币,大量的工作才刚刚开始,让我们逐笔开始记录吧。

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

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

相关文章

2024幻兽帕鲁服务器创建教程_阿里PK腾讯超简单

幻兽帕鲁官方服务器不稳定&#xff1f;自己搭建幻兽帕鲁服务器&#xff0c;低延迟、稳定不卡&#xff0c;目前阿里云和腾讯云均推出幻兽帕鲁专用服务器&#xff0c;腾讯云直接提供幻兽帕鲁镜像系统&#xff0c;阿里云通过计算巢服务&#xff0c;均可以一键部署&#xff0c;鼠标…

vscode 提取扩展时出错。XHR failed

检查 vscode 设置中的代理服务器&#xff0c;位置如下图 清空 vocode 中的 Proxy&#xff0c;我黄线框的部分&#xff0c;内容清空。 检查电脑系统环境变量&#xff0c;是否设置了 http_proxy 和 https_proxy&#xff0c;如果有设置&#xff0c;则删除这两项&#xff0c;下载完…

《区块链公链数据分析简易速速上手小册》第4章:交易数据分析(2024 最新版)

文章目录 4.1 解析交易输入和输出4.1.1 基础知识4.1.2 重点案例&#xff1a;追踪比特币交易4.1.3 拓展案例 1&#xff1a;以太坊交易的输入输出解析拓展案例1&#xff1a;以太坊交易的输入输出解析步骤1: 连接到以太坊网络步骤2: 获取交易数据步骤3: 解析交易输入结论 4.1.4 拓…

Uipath 调用Python 脚本程序详解

Python 活动概述 UiPath.Python.Activities 是一个新的活动包&#xff0c;创建它是为了支持直接从工作流运行 Python 脚本和方法。 其包含以下活动&#xff1a; Python 作用域(Python Scope) - 为 Python 活动提供作用域的容器。 加载 Python 脚本(Load Python Script) - 将 P…

中国电子学会2023年12月份青少年软件编程Scratch图形化等级考试试卷四级真题(含答案)

2023-12 Scratch四级真题 分数&#xff1a;100 题数&#xff1a;24 分数&#xff1a;60min 一、单选题(共10题&#xff0c;共30分) 1.运行下列程序&#xff0c;输入“abcdef”&#xff0c;程序结束后&#xff0c;变量“字符串”是&#xff1f;&#xff08;B&#xff09;(3…

代码随想录刷题笔记 DAY 26 | 组合总和 No.39 | 组合求和 II No.40 | 分割回文串 No.131

文章目录 Day 2501. 组合总和&#xff08;No. 39&#xff09;1.1 题目1.2 笔记1.3 代码 02. 组合求和 II&#xff08;No. 40&#xff09;2.1 题目2.2 笔记2.3 代码 03. 分割回文串&#xff08;No. 131&#xff09;3.1 题目3.2 笔记3.3 代码 Day 25 01. 组合总和&#xff08;No…

Java入门高频考查基础知识9(银盛15问万字参考答案)

JAVA刷题专栏&#xff1a;http://t.csdnimg.cn/9qscL 目录 一、Springcloud的工作原理 三、注册中心心跳是几秒 四、消费者是如何发现服务提供者的 五、多个消费者调⽤用同⼀接口&#xff0c;eruka默认的分配⽅式是什么 六、springboot常用注解&#xff0c;及其实现 七、…

ClickHouse--10--临时表、视图

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.临时表1.1 特征1.2 创建一个临时表 2.视图2.1 普通视图2.2 物化视图 1.临时表 1.1 特征 ClickHouse 支持临时表&#xff0c;临时表具备以下特征&#xff1a; 当…

【JAVA WEB】JavaScript(WebAPI)--DOM基本概念 获取元素 点击事件 键盘事件

目录 什么是WebAPI DOM的基本概念 DOM是什么 DOM树 获取元素 querySelector querySelectorAll 事件 事件初识 基本概念 事件三要素 点击事件 键盘事件 什么是WebAPI 前端学习的 JS 分成三个大的部分 ECMAScript&#xff1a;基础语法部分DOM API&#xff1a;操作…

鸿蒙开发系列教程(十九)--页面内动画(2)

组件内转场动画 组件的插入、删除过程即为组件本身的转场过程&#xff0c;组件的插入、删除动画称为组件内转场动画。通过组件内转场动画&#xff0c;可定义组件出现、消失的效果。 transition(value: TransitionOptions) 参数可以定义平移、透明度、旋转、缩放这几种转场样…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第一套(完善程序题)

CCF认证CSP-J入门组模拟测试题第一套 三、完善程序题 第一题 九宫格 请完善下面的程序,将1~9个数字分别填人3x3的九宫格中,第一行的三个数字组成一个三位数。要使第二行的三位数是第一行的2倍,第三行的三位数是第一行的3倍且每个格子里的数字都不能重复,现在要求输出所有的填…

视觉slam十四讲学习笔记(四)相机与图像

理解理解针孔相机的模型、内参与径向畸变参数。理解一个空间点是如何投影到相机成像平面的。掌握OpenCV的图像存储与表达方式。学会基本的摄像头标定方法。 目录 前言 一、相机模型 1 针孔相机模型 2 畸变 单目相机的成像过程 3 双目相机模型 4 RGB-D 相机模型 二、图像…

【JavaEE】网络原理: UDP协议和TCP协议的相关内容

目录 1. 应用层 2. 传输层 2.1 端口号 2.2 UDP协议 2.3 TCP协议 1.确认应答 2.超时重传 3.连接管理 三次握手 四次挥手 状态转换 4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答 9.面向字节流 粘包问题 10.异常情况 网络通信中, 协议是一个非常重…

第二十九回 施恩三入死囚牢 武松大闹飞云浦-分布式版本控制系统Git使用

武松要蒋门神答应三件事&#xff1a;离开快活林、东西都归还施恩&#xff0c;公开对施恩赔礼道歉&#xff0c;不许在孟州住。蒋门神不得已都答应了&#xff0c;灰溜溜地离开了孟州城。 一个月之后&#xff0c;天气转凉&#xff0c;张都监调武松到孟州城&#xff0c;做了他的亲…

统计图饼图绘制方法(C语言)

统计图饼图绘制方法&#xff08;C语言&#xff09; 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图绘制较难。今值此介绍饼图的绘制方法。 本方法采用C语言的最基本功能&#xff1a; &#xff08; 1.&#xff09…

数据结构在JavaScript中的体现

一.概述 数据结构是计算机中存储、组织数据的方式。通常情况下&#xff0c;精心选择的数据结构可以带来最优效率的算法&#xff0c;其实算法并不是一个很高级的东西&#xff0c;它充斥在每一种代码组织方式中&#xff1b;而且各种语言关于数据结构方面的内容都是大同小异的&…

【复现】某某ERP 信息泄露漏洞_49

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 该ERP基于SpringBoot框架和SaaS模式&#xff0c;立志为中小企业提供开源好用的ERP软件&#xff0c;目前专注进销存财务生产功能。…

七天入门大模型 :LLM大模型基础知识最全汇总

七天入门LLM大模型学习 旨在帮助初学者理解和学习LLM的基础概念和实践。 未来七天&#xff0c;我将每天为大家推出一篇课程内容&#xff0c;感兴趣的小伙伴们可关注我们 文章目录 技术交流群用通俗易懂方式讲解系列基础模型研究模型定制新范式LLM类型介绍多模态模型Agent模型C…

【MySQL】待修改

外键约束 含义 外键&#xff1a;用来让两张表的数据之间建立连接&#xff0c;从而保证数据的完整性和一致性。 员工表emp&#xff08;子表&#xff09; idnameagejobsalaryentrydatemanageriddept_id1金庸66总裁200002000-01-01null52张无忌20项目经理125002005-12-05113杨…

lv15 平台总线驱动开发——ID匹配 3

一、ID匹配之框架代码 id匹配&#xff08;可想象成八字匹配&#xff09;&#xff1a;一个驱动可以对应多个设备 ------优先级次低&#xff08;上一章名称匹配只能1对1&#xff09; 注意事项&#xff1a; device模块中&#xff0c;id的name成员必须与struct platform_device中…