title author date CreateTime categories
win10 uwp MVVM 语义耦合
lindexi
2018-08-10 19:16:53 +0800
2018-2-13 17:23:3 +0800
Win10 UWP

最近在我写的框架,小伙伴告诉我,可能有语义耦合,那么本文就来告诉大家,为什么会出现语言耦合

之前我写了一个轻量的框架,参见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 只是转发数据,这样才可以减少耦合。

一个项目使用了框架会比不使用框架的可维护要好很多,即使使用的时候存在一些问题,但是也比不使用好。

参见:语义耦合(Semantic Coupling) - walterlv

2018-8-10-win10-uwp-MVVM-语义耦合的更多相关文章

  1. win10 uwp MVVM 轻量框架

    如果在开发过程,遇到多个页面之间,需要传输信息,那么可能遇到设计的问题.如果因为一个页面内包含多个子页面和多个子页面之间的通信问题找不到一个好的解决方法,那么请看本文.如果因为ViewModel代码越 ...

  2. win10 uwp MVVM入门

    MVVM 是一个强大的架构,基本从 WPF 开始,wr(我说的就是微软)就提倡使用 MVVM.它可以将界面和后台分离,让开发人员可以不关心界面是怎样,全心投入到后台代码编写中. 然后在编写完后台代码后 ...

  3. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  4. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  5. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

  6. Win10 UWP开发实现Bing翻译

    微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...

  7. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  8. Win10 UWP应用发布流程

    简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...

  9. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  10. win10 uwp 获得元素绝对坐标

    有时候需要获得一个元素,相对窗口的坐标,在修改他的位置可以使用. 那么 UWP 如何获得元素坐标? 我提供了一个方法,可以获得元素的坐标. 首先需要获得元素,如果没有获得元素,那么如何得到他的坐标? ...

随机推荐

  1. day39-Spring 05-Spring的AOP:不带有切点的切面

    Spring底层的代理的实现: 不带切点的切面是对类里面的所有的方法都进行拦截. 做Spring AOP的开发需要两个包:一个是AOP的包,一个是AOP联盟的包(因为规范是由AOP联盟提出来的). 用 ...

  2. 【水滴石穿】AB-B-Clone

    地址: 源码 运行效果 无别的效果,代码如下 //index.js /** * @format * @lint-ignore-every XPLATJSCOPYRIGHT1 */ import {Ap ...

  3. 如何在Liferay 7中创建一个简单的JSF Portlet

    这个将在Liferay IDE 3.1 M3的发布版中提供创建的选项,但是你也可以通过命令行来创建. 1.这是Liferay JSF团队的官网:http://liferayfaces.org/ 你能在 ...

  4. php的一些误解

    1.php函数和方法是不用的:类的方法可以设定访问权限,需要通过对象或者类来调用:函数是公共的,都可以使用.

  5. 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    题目描述 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取一些原子,排成 ...

  6. day19 django继续

    上节回顾 django - 路由系统:url.py - 视图函数:views.py - 模板引擎渲染 - HttpResonse(字符串) - render(request,'index.html') ...

  7. AT2377 Blue and Red Tree

    AT2377 Blue and Red Tree 法一:正推 红色的边在蓝色的树上覆盖,一定每次选择的是覆盖次数为1的边的覆盖这条边的红色边连出来 覆盖次数可以树剖找到 这条红色边,可以开始的时候每个 ...

  8. Java面向对象----封装概念

    封装 信息隐藏,隐藏对象的细节 访问修饰符 public private protected 默认 属性封装的实现 方法封装的目的(隐藏方法实现细节) package com.tanlei.newer ...

  9. c++第四次作业:继承

    继承与派生 基本概念和语法 概念 继承与派生是同一过程从不同角度看 保持已有的特性而构造新类的过程称为继承. 在已有类的基础上新增自己的特性而产生新类的过程为派生. 被继承的已有类称为基类(父类) 派 ...

  10. CTR+A组合键 以及终止按键事件传递

    Key UP 或Down 事件中 实现CTR+A全选 if ( Control.ModifierKeys==Keys.Control && e.KeyCode == Keys.A)   ...