当前位置:网站首页>win10 uwp MVVM 语义耦合
win10 uwp MVVM 语义耦合
2022-08-04 18:37:00 【林德熙】
最近在我写的框架,小伙伴告诉我,可能有语义耦合,那么本文就来告诉大家,为什么会出现语言耦合
之前我写了一个轻量的框架,参见win10 uwp MVVM 轻量框架 。在使用的过程,发现了这个框架可以让开发者写出语义耦合的代码。
在开始讲框架之前,先让我告诉大家,什么是语义耦合。
例如有一个框架,在框架的代码都没有任何的耦合,如 View 的界面和 ViewModel 是分开在两个工程,而且只有 View 引用 ViewModel ,这样从静态的代码分析可以说,ViewModel 没有耦合 View 。但这是不是真的就没有耦合?实际上可能还是有语义的耦合。
在小伙伴使用框架,但是对 MVVM 的理解不是很深的时候,就容易写出下面的代码
ViewModel:
发送 刷新 列表消息
View
处理 刷新列表消息
这时,因为 ViewModel 写出了刷新列表的消息,所以刷新列表这个界面相关的消息就耦合了界面。也就是在 ViewModel 是处理了部分的界面的逻辑。
在很多的代码,包括继龙大神的、于大神的代码,发现了在 ViewModel 使用了 Visibility 的属性,需要知道 Visibility 是界面的属性,如果界面绑定了 Visibility 那么 ViewModel 就需要对 Visibility 处理。这时的界面是需要写 ViewModel 的开发者知道的。这时界面修改的话,例如原来在条件下需要 Visibility 隐藏的代码就需要修改为不隐藏。这时修改界面就需要修改 ViewModel 。
如果在 ViewModel 耦合了界面的控制,那么为什么需要 ViewModel ? 实际上的 ViewModel 是抽象页面,所以不能对 ViewModel 添加对界面控制的代码。在太子的博客语义耦合已经有说到关于 Message 耦合的问题。同样也给出一些解决方法。
下面我来告诉大家一些比较好的处理方法。
在几乎所有主流的 MVVM 框架,都提供了 Message 给 ViewModel 和 View 通信。而且在我的框架用了 Message,所以对 Message 是比较难写的一点。如果限制很多,那么很多开发者就不会使用,解决这个框架不好用。如果给的功能太多,那么容易出现语义耦合,而且使用这个功能做框架设计没有提供的功能。
需要和大家分享一个故事,为什么 微软 把Action 的参数提供了 16 个?因为他需要考虑全世界所有的开发者。但是一般的开发者建议使用的参数只有两个,但是在一个足够通用的框架,是需要做到对少数的开发者也可以使用。所以不要认为只要框架提供了,就可以使用。一个好的开发者会去阅读框架的文档,然后使用框架开发者希望使用的方式开发。但是一个好的框架是开发者不需要去读文档,看到了框架就会使用。这是矛盾的,但是和框架开发者的能力有关。微软框架大部分都是很好的,但是也有一些代码写的很差。最近我在写高性能笔的时候就发现了他的代码的问题,已经帮他修复了,但是现在微软几乎不做 .net Framework 了,把他的很多代码都放在 .net core ,然后就经常看到有大神修改了算法,提高了性能。
回到问题,如何在开发中解决 MVVM 的语言耦合,实际上这不是一个技术问题。建议的方法是让开发者的代码经过审查,现在在开发的时候,所有的代码都需要提MR,在来源的开发中,也是需要提MR,这样就可以容易发现在代码中存在的语义耦合。现在通过工具是难以发现的。
如果发现了存在语义耦合,那么如何解决?
这个需要分析一下,一般做法是让具体的命名写为抽象。如上面的代码,从ViewModel 告诉 View 刷新列表,为什么需要 ViewModel 知道 View 需要刷新列表,他可以使用一个抽象的命名,例如告诉 View 现在更新了数据。于是 View 根据ViewModel 的消息进行刷新列表,这样就不会出现 ViewModel 的语言耦合。
但是很多的代码都可以使用状态来获得刷新和修改,所以这时就不需要使用消息。
另一个建议是最好不要在 ViewModel 定义界面的控制的方法,例如 Visibility ,不可以让ViewModel 去控制 View 。在微软提出的就说到,ViewModel 是驱动数据,所以 ViewModel 只是转发数据,这样才可以减少耦合。
一个项目使用了框架会比不使用框架的可维护要好很多,即使使用的时候存在一些问题,但是也比不使用好。
边栏推荐
- Matlab drawing 1
- After EasyCVR is locally connected to the national standard device to map the public network, the local device cannot play and cascade the solution
- HCIP-R&S By Wakin自用笔记(1)企业网络高级解决方案
- 什么是网站监控,网站监控软件有什么用?
- Scala105-Spark.sql中collect_list用法
- Go language Go language, understand Go language file operation in one article
- 报道称任天堂在2023年3月前不会推出任何新硬件产品
- Babbitt | Metaverse daily must-read: Weibo animation will recruit all kinds of virtual idols around the world and provide support for them...
- Day018 继承
- 开篇-开启全新的.NET现代应用开发体验
猜你喜欢
A group of friends asked for help, but the needs that were not solved in a week were solved in 3 minutes?
DHCP&OSPF combined experimental demonstration (Huawei routing and switching equipment configuration)
【STM32】入门(五):串口TTL、RS232、RS485
开篇-开启全新的.NET现代应用开发体验
链表的经典入门LeetCode题目
【杰神说说】物联大师2.0版本预告
Flink / Scala - 使用 RedisSink 存储数据
CPU突然飙高系统反应慢,是怎么导致的?有什么办法排查?
limux入门3—磁盘与分区管理
2019 Haidian District Youth Programming Challenge Activity Elementary Group Rematch Test Questions Detailed Answers
随机推荐
LVS+NAT 负载均衡群集,NAT模式部署
群友求助,一周没有搞定的需求,3分钟就解决了?
防火墙基础之防火墙做出口设备安全防护
EuROC 数据集格式及相关代码
测试工程师如何突破职业瓶颈?
Understanding of margin collapse and coincidence
图解LeetCode——899. 有序队列(难度:困难)
合宙Cat1 4G模块Air724UG配置RNDIS网卡或PPP拨号,通过RNDIS网卡使开发板上网(以RV1126/1109开发板为例)
22/8/4 记忆化搜索+博弈论
【杰神说说】物联大师2.0版本预告
Flask framework implementations registered encryption, a Flask enterprise class learning 】 【
Enterprise survey correlation analysis case
CAN光纤转换器CAN光端机解决消防火灾报警
Google Earth Engine APP——一键在线查看全球1984-至今年的影像同时加载一个影像分析
Short-term reliability and economic evaluation of resilient microgrids under incentive-based demand response programs (Matlab code implementation)
在线生成接口文档
LVS+Keepalived群集
curl命令的那些事
【注册荣耀开发者】赢【荣耀70】手机
如何进行自动化测试?