【WPF】影城POS的前世今生
前言
POS从16年底开始设计到现在都过去快两年了,这里我做一个简单的回顾。
技术选型
NativeUI:性能最高,开发难度最大,代表产品QQ和微信,没有基因没有技术栈。
Electron+H5:不支持xp,使用xp的电脑在影城中还存在50%以上,只能否决。
NWJS+H5:总体上比Electron差一些,但是支持xp,因为存在性能,操作体验,安装包庞大等问题,被钉钉弃用。
NativeUI+CEF+H5:hybird框架,将性能要求高的UI用C++写,变化频繁的用h5写,钉钉客户端最新采用的技术框架。网易云音乐客户端也是类似框架。也没有技术栈。
WinForm:.Net平台下的两大UI框架之一,具有开发简单,轻量,性能高等优点,但是有自定义UI难度高,微软停止更新等缺点。
WPF:.Net平台下的两大UI框架之一,具有现代化的UI界面和比较先进的MVVM编程思想。公司上代产品使用的技术,具有广泛的实践经验,读卡和打印等类库可以直接继承使用。这是最不容易采坑的技术方案。
当时公司的战略是用迅雷不及掩耳之势打下云售票这片新市场,一边要和时间赛跑,一边要保证产品质量和功能,需要开发节奏要快,狠,准,所以综上所述,最终沿用WPF技术开发新产品。
一个优秀系统架构应该是具有高可扩展性、高内聚、低耦合等特点,在经历了各版本的变更之后依然保持着清晰、灵活、稳定的系统架构。而模块化是其中一个解决方案,为了以后框架的灵活扩展和应付日益复杂的业务,模块化应该是新产品的设计方向。
业务模块
POS是给前台售票员使用的系统,业务上相对简单,大部分都是与顾客相关,可粗略分为影票,卖品,会员三大类,还有打印,读卡等硬件交互模块,另外还有登录,客屏这些功能,抽钞,赠券等归类为其他业务。

业务模块再细化,系统架构图雏形
上面粗粒度的业务分类还是难以支持系统设计,还是需要进一步的细化。在系统架构层面就是要业务模块在细化,和补全必要的组件,例如日志,数据服务等。

完全解耦的平台化
最开始想的方案是完全平台化,整个系统的核心只是作为启动器的exe,其他模块dll作为插件都可以替换的,再通过读取到内存,以反射方式加载,可以实现各个模块的热插拔。启动器和插件的关系就好像浏览器和H5页面。

这个方案可以使各个模块完全解耦,从编译的角度来说完全独立。但缺点很明显,代码冗余大,日志,打印等功能基本都一样的,修改和维护相当困难。另外各模块之间的业务都是有依赖和关联的,他们之间的通信可以采用字符串传递,再反序列得到实例。事实上这种靠口头约定的通信方式出现一丁点的误差就会造成严重的后果。综上,这种方案并不适合POS。不过可以作为一个局部平台,对外接收各种第三方开发的插件实现业务功能。
改进方案
上面灾难性的字符串通信改成各模块引用dll,实现强类型通信。作为一个UI系统需要用到各个控件,也需要做一个通用类库给各模块引用。另外,为了国际化的需要和主题更换的实现,文案资源和样式也需要独立出来。

具体实现
具体到代码实现层面,考虑到安装包的大小和第三方框架的兼容性,我决定以轻量化作为设计抉择的方向
IOC容器
上面有各式各样模块为了方便管理各个组件,Bootstrapper需要作为一个容器,担任加载和管理组件。
微软集成在.Net 4.0框架中,不需要引入第三方框架,符合客户端轻量化的要求。
可根据路径扫描和加载组件。
可以卸载和重新组合组件。
以MEF框架为基础,我做了几样工作。
定义了CataLog.xml配置文件,里面记录着每个组件的实际文件路径,在程序启动时,读取配置加载需要的组件。
设计IModule接口,如果组件需要在运行时执行任务,可以实现接口的Initialize方法。
封装MEF的容器为全局容器Global.Container,可通过容器导出其他组件的服务。
改进MEF的加载组件的方式,先把组件读取到内存的方式,再转化成Assembly加载,可以实现运行时卸载组件,更新组件。
MVVM框架
MVVM是Model-View-ViewModel的简写,是一种比较先进的设计模式,WPF本身就是一个实现MVVM模式的框架,主张数据驱动理念,但是它里面对命令,属性通知等概念的实现不是很友好,所以我找了行业上比较成熟的第三方框架做了一番对比。
MvvmLight, 是一个轻量级的MVVM框架,比较适合小程序开发,对命令,属性通知接口等有相应的实现,使用Mesage类作为消息传递。使用SimpleIoc容器。
Prism,相对于来庞然大物,适合大规模程序开发,支持模块化,组合UI,组合命令,事件聚集,支持Unity和MEF作为IOC容器。使用上非常复杂,而实际开发上很少用得上全部功能。
最后,走读MvvmLight和Prism文档和源码,取两者之长构建自己的框架。参考MvvmLight将命令,属性通知等功能在Infrastructure中实现,参考Prism的模块化思想,以接口IMdoule作为模块间加载和交互的桥梁。
控件库
为了风格统一和代码复用,需要一个控件库来开发。但是原生控件样式简陋功能少,而第三方控件比较好有ModernUI,Xceed和Telerik,前者开源,扁平化风格,功能上和原生差不多,后两者部分开源,高度封装,功能强大,不过要收费。实际上,按照视觉搞,原生和第三方控件都是不符合要求,最终还是要自建LarkUI控件库,重写样式和功能以满足视觉和交互的要求,最终集成在Infrastructure。
自动更新
新产品的迭代是非常频繁的,为了防止版本碎片化,POS需要实现强制更新,另外频繁的更新会降低用户体验,所以必须要自动更新且尽量无感,启动时检查,下载更新包替换文件后重启。

小结
本文简单介绍了POS的架构,总的来说,在行业上WPF框架并没有一个标准的解决方案,所以整个设计上有比较强烈的个人喜好在里面。未来的话,也可以抽象出来作为一个WPF的标准客户端架构输出到行业去。
【WPF】影城POS的前世今生的更多相关文章
- WPF 基础到企业应用系列2——WPF前世今生
1.开篇前言 非常多时候了解一项新技术的历史和趋势往往比这项技术的本身价值还要重要.WPF作为一项新技术(已经三年多了.或者应该叫老技术了).我们都有必要了解它的来龙去脉,尤其是公司的CT ...
- 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...
- 第五篇:在SOUI中使用XML布局属性指引(pos, offset, pos2type)
窗口布局的概念 每一个UI都是由大量的界面元素构成的,在Windows编程,这些界面元素的最小单位通常称之为控件. 布局就是这些控件在主界面上的大小及相对位置. 传统的布局一般使用一个4个绝对坐标来定 ...
- WPF基础到企业应用系列6——布局全接触
本文转自:http://knightswarrior.blog.51cto.com/1792698/365351 一. 摘要 首先很高兴这个系列能得到大家的关注和支持,这段时间一直在研究Windows ...
- WPF拖放功能实现zz
写在前面:本文为即兴而作,因此难免有疏漏和词不达意的地方.在这里,非常期望您提供评论,分享您的想法和建议. 这是一篇介绍如何在WPF中实现拖放功能的短文. 首先要读者清楚的一件事情是:拖放主要分为拖放 ...
- 在uwp仿制WPF的Window
移植WPF软件到uwp时碰到用作对话框的Window有多种处理选择.我个人认为最省事的是用ContentDialog模拟Window. 比如你想把上面这个WPF窗体弄到uwp里面去 1.修改Conte ...
- 【转】【WPF】wpf 图片指针处理
我一直用GDI+做Winform 的基于指针的图片处理,这次下决心全部移到wpf上(主要是显示布局很方便)采用的图片是2512*3307 的大图 830万像素类库基于WritableBitmapEx ...
- WPF 基础到企业应用系列索引
转自:http://www.cnblogs.com/zenghongliang/archive/2010/07/09/1774141.html WPF 基础到企业应用系列索引 WPF 基础到企业应用系 ...
- WPF拖动总结[转载]
WPF拖动总结 这篇博文总结下WPF中的拖动,文章内容主要包括: 1.拖动窗口 2.拖动控件 Using Visual Studio 2.1thumb控件 2.2Drag.Drop(不连续,没有中 ...
随机推荐
- iOS 使用markdown 实现编辑和预览文本
注意要点: 1.在iOS 可以依赖UIWebview 来实现 2.丰富的UI样式依赖 html 的样式, js 调用插入markdown内容呈现出来 3.实现markdown编辑快捷键:参考githu ...
- 常用RDD
只作为我个人笔记,没有过多解释 Transfor map filter filter之后,依然有三个分区,第二个分区为空,但不会消失 flatMap reduceByKey groupByKey() ...
- 整理一些《纸书科学计算器》的小Tips
本文最开始是在2016年的文章 Win10应用<纸书科学计算器>更新啦! 发表之后撰写的,当时那篇文章收到了不少人点赞,应用在国内市场的日下载量也突然上涨,让我感到受宠若惊,这里要感谢Wp ...
- Spring事务回滚
配置事物: @Configuration /**强制使用cglib代理时就把proxy-target-class设为true.*/ @EnableTransactionManagement(proxy ...
- Web安全学习笔记之Nmap脚本使用指南
nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端.确定哪些服务运行在哪些连接端,并且推断计算机运行哪个操作系统.它是网络管理员必用的软件之一,以及用以评估网络系统安全. —— 来自百 ...
- FTP 两种工作模式
主动模式port FTP主动模式:TCP链接客户端访问FTP,客户端会开启一个大于1024的端口N访问FTP的21端口(控制端口),并通过21端口发送port命令与N+1的端口,服务端收到命令后会使用 ...
- 20145310第一周JAVA实验报告
20145310第一周JAVA实验报告 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 使用JDK和IDE编译.运行简单 ...
- 20145313张雪纯 《Java程序设计》第6周学习总结
20145313张雪纯 <Java程序设计>第6周学习总结 教材学习内容总结 将数据从来源中取出,可以使用输入串流:将数据写入目的地,可以使用输出串流. 输入串流代表对象为java.io. ...
- 【转】获取Windows系统明文密码神器
前序 电脑密码忘记了可以用本工具找回,前提是你能进入系统,例如本机保存了远程服务器登录的密码或借别人的电脑,而忘记了密码:mimikatz 2.0工具正好解决了你的问题. 工具下载 binaires ...
- 转载 URL短地址压缩算法
文章转载http://www.nowamagic.net/webdesign/webdesign_ShortUrlInTwitter.php /// <summary> /// 生成sal ...