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

适用于WPF的设计模式

适用于WPF的设计模式

讨论“XAML能不能写逻辑代码”这个问题。我发现这是个有歧义的问题。这个问题可以有两种意思:
XAML能不能用来写逻辑代码?
XAML文件里能不能包含逻辑代码?
对于第一种意思——XAML是一种声明性语言,就是用来声明UI元素的,不能用来写逻辑代码;
对于第二种意思——XAML文件中可以使用<x:Code>标签,来嵌入一些C#或VB写的逻辑代码,也就是把code-behind的代码挪到了XAML文件里。但请注意:逻辑代码仍然是用C#或VB写的(即与上面一种解释不冲突)。

第二件,也是聊天的时候想到的。
以前很少关注程序员们应该读什么样的书,昨天和我一位已经移民澳洲的朋友吃饭,提到中国学生和欧美学生的差距,在这位朋友看来,中国学生的专业知识要比欧美的学生强,但基础知识偏弱。表象就是:中国学生就业起点高(但被人数太多给抵销掉了)但后期积累速度慢。
基础知识弱的具体一个表现就是,中国学生的母语写作能力平均水平比较低(我想这也包括我在内)——是不是因为忙着学外语搞的就不得而知了。
平时在我面试的时候也能感受到这一点,但重点能感觉到学生的哲学和逻辑方面缺少必要的积累(尽管我积累的也不多)。所以,最后与草小弟达成共识——程序员应该多读一些图书馆里的A类(可不是Adult的A哦!)和B类书籍。

2. XAML有哪些优点

前面一节已经向我们透露了XAML的几个优点:
• XAML可以设计出专业的UI和动画——好用
• XAML不需要专业的编程知识,它简单易懂、结构清晰——易学
• XAML使设计师能直接参与软件开发,随时沟通、无需二次转化——高效
然而,XAML这位翩翩君子的才华可远不止这些。
自 从应用程序从命令行界面(Console User Interface,CUI,这本书的读者还有用过DOS的吗?就是那东西)升级为图形用户界面(Graphic User Interface,GUI)后,程序员们就一直追求将视图(View,也就是UI)与逻辑代码的分离。以往的开发模式中,程序员很难保证用来实现UI的 代码完全不与用来实现程序逻辑的代码纠缠在一起。UI代码与逻辑代码纠缠在一起称为UI与逻辑的紧耦合,它往往带来以下的后果:
• 无论是软件的功能还是UI设计有所变化或者是出了bug,都将导致大量代码的修改。
• 会让逻辑代码更加难以理解——修改往往比重写更困难,因为在修改之前必须先读懂。
• 重用逻辑代码变成了Mission Impossible
XAML 另一个巨大的优点就是:它帮助开发团队真正实现了UI与逻辑的剥离。
XAML是一种单纯的声明型语言,也就是说,它只能用来声明一些UI元素、绘制UI和 动画(在XAML里实现动画是不需要编程的),根本无法在其中加入程序逻辑,这就强制地把逻辑代码从UI代码中赶走了。这样,与UI相关的元素统统集中在 程序的UI层、与逻辑相关的代码统统集中在程序逻辑层,形成了一种“高内聚-低耦合”的结构。形成这种结构后,无论是对UI进行较大改动还是打算重用底层 逻辑,都不会花费太大力气。这就好比有一天你给A客户做了一个橘子,A客户很喜欢;A客户把你的产品介绍给了B客户,B客户很喜欢橘子味道,但希望它看上 去像个香蕉——这时候,你只需要把橘子皮撕下来 、换一套香蕉皮即可——只需很少的成本就可以获得与先前一样大的收益。(对于软件的“换肤”行为,WPF提供了丰富的Template功能,将在后面详 述。)

小序:
当梦想突然有一天变成现实的时候,我们会有什么样的感觉?惊喜自然是少不了的。惊喜过后呢?剩下的就是要接受现实了——就像小鬼当家里的小家伙。

正文:
有朝一日能把软件的UI设计和逻辑设计分开,这是多年来程序开发人员的梦想。如今,这个梦想被XAML+C#实现了,大家都很开心。开心过后,问题来了——Binding与依赖属性再好使、路由事件和命令再灵活,如果不加约束地乱用和过度使用,一样会导致软件架构的不稳固以及招致维护、测试和调试方面的麻烦。

那么,怎样才能用好WPF带来的结构上的新特性呢?我们需要做的,不是从头开始创造一个新模式,而是需要把WPF的新特性揉合进现有的、成熟的开发框架中去。下面,让我们开始WPF开发框架的演进之旅!

MVC时代
现有的开发框架林林总总,但万变不离其宗,这个“宗”指的就是最为经典的MVC模式。插一句,有一次面试一位候选人,当我问及这个模式的时候,这位兄台干脆地回答到:“MCV!”,于是我就让他“展开”讲讲了:p

MVC框架出现的年代比较早,生成软件UI和逻辑用的是同一种语言(比如C++/Java/Delphi),灵活性基本上是局限在对于同一块数据(由Model暴露出来)使用不同的视图(View,也就是UI)展现给用户。

MVP时代
随着互联网的发展,程序不再是一个个只能跑在特定操作系统上的代码块,成千上万的用户希望使用相同的程序共享相同的数据。操作系统平台一时半会是统一不起来了,A厂商程序跨到B厂商平台上的那只脚也往往被B厂商穿上一只小鞋。万般无奈下,开发人员只好诉诸于所有操作系统平台的交集——浏览器——赶鸭子上驾般地做起了程序的宿主;HTML也没被放过,本来用于简单呈现页面的标签语言却被CSS、JavaScript、XML等等武装到了牙齿。

Anyway,程序可以跑在浏览器里了,需要开发人员重新把程序开发一遍吗?

人们发现,无论程序的前端(UI部分)跑在哪里,它的后台逻辑是不会改变的。于是人们开始想:我怎样才能把UI和逻辑解耦并对逻辑层加以复用呢?必需要在设计或者重构的时候考虑上这一点才可以。

  • 于是,在MVC的基础上,人们向前推进了一步——MVP模式诞生了(有玩儿文字游戏的嫌疑哦!)。Interface这个词被译成“接口”之后就丢了些原本的意思。如果还把当译成“界面”,那么这个意思就能找回来了——现实世界也是这样,当物体受到接力的时候,凡是有界面的地方就是最容易被撕下来的地方。因此,interface这个词在译成中文时,“接口”传达的是其可以作为公共约束(契约)的一层意思;“界面”则能传达解耦的一层意思。

  • 在MVP模式中,为了让UI层能够从逻辑层上“撕”下来,设计师们在UI层与逻辑层之间加了一层interface。无论是UI开发人员还是数据开发人员,都要尊重这个契约、按照它进行设计和开发。这样,理想状态下无论是Web
    UI还是Window UI就都可以使用同一套数据逻辑了。

MVVM时代

现在,WPF来了,它带来了3D、动画、音频视频……这导致了UI的变化将更加细节化、可定制化。同时,在技术层面,WPF也带来了诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。我们怎样才能立足于原有MVP框架、把WPF的新特性揉合进去,以应对客户复杂的需求呢?

图说MVP与MVVM

MVC模式大都已经非常熟悉了,咱就不说了。让我们看看它的升级版——MVP
在这里插入图片描述

从这张图上我们可以看出如下几点:

  1. IView这个interface层帮助我们把各类UI与逻辑层解耦
  2. IView这层同时也为自动化测试提供了入口(从UI层进入自动化测试,太麻烦了)
  3. 传统的、由WinForm/Web Form/MFC等编写的UI是通过事件(本质是Windows 消息)与IView层沟通的。
  4. WPF与IView层的沟通,最佳的手段是使用Binding,当然,也可以使用事件
  5. Presenter层要实现IView,多态机制可以保证运行时UI层显示恰当的数据。比如Binding,在程序中,你可能看到Binding的Source是某个interface类型的变量——实际上,这个interface变量引用着的对象才是真正的数据源
  6. 可有可无的Control……有的话,就当是留个纪念吧,原版的MVP图里是没有Control的,Control被Presenter取代
  7. 这里的Presenter有点歧义之虞,就我个人而言,感觉Presenter是UI里的东西。

我们再来看MVVM
在这里插入图片描述

同样有几点注意:

  1. 当我们只关注MVP模式与WPF结合的应用方式时,MVP就变成了MVVM。
  2. 借鉴MVP的IView层,养成习惯。原版MVVM图里是没有这层的,但我会在程序里加上这层。
  3. View Model听起来比Presenter要贴切得多
  4. 我会把一些跟事件、命令相关的东西放在Controler里

相关文章:

适用于WPF的设计模式

适用于WPF的设计模式 讨论“XAML能不能写逻辑代码”这个问题。我发现这是个有歧义的问题。这个问题可以有两种意思&#xff1a; XAML能不能用来写逻辑代码&#xff1f; XAML文件里能不能包含逻辑代码&#xff1f; 对于第一种意思——XAML是一种声明性语言&#xff0c;就是用来…...

C++与多态

多态的本质是允许对象以其实际类型的行为方式来操作&#xff0c;而不仅仅是其静态类型所声明的方式。 多态是面向对象编程中的一种核心概念&#xff0c;它允许对象根据其具体类型执行相应的操作&#xff0c;而不是其声明的类型。我们可以使用一个经典的动物的例子来说明这一点。…...

ios 对话框UIAlertController放 tableview

//强弱引用 #define kWeakSelf(type)__weak typeof(type)weak##type type; -(void) showUIAlertTable {kWeakSelf(self)UIAlertController *alert [UIAlertController alertControllerWithTitle:NSLocalizedString("select_stu", nil) message:nil prefer…...

警告:新版Outlook会向微软发送密码、邮件和其他数据

新的免费Outlook会将敏感数据发送给 Microsoft。 在没有通知或询问的情况下&#xff0c;Microsoft 授予自己对新 Outlook 用户的 IMAP 和 SMTP 访问数据的完全访问权限。也就是说&#xff0c;当用户设置 IMAP 帐户时&#xff0c;新的 Outlook 会将访问数据和服务器信息发送给 …...

数据结构C语言--基础实验

实验1 线性表的顺序实现 1.&#xff01;顺序表的倒置 /**********************************/ /*文件名称&#xff1a;lab1-01.c */ /**********************************/ /*基于sequlist.h中定义的顺序表&#xff0c;编写算法函数reverse(sequence_list *L)&…...

wireshark抓包并进行Eigrp网络协议分析

路由协议 Eigrp ​ EIGRP:Enhanced Interior Gateway Routing Protocol 即 增强内部网关路由协议。也翻译为 加强型内部网关路由协议。 EIGRP是Cisco公司的私有协议&#xff08;2013年已经公有化&#xff09;。 EIGRP结合了链路状态和距离矢量型路由选择协议的Cisco专用协议&a…...

力扣刷题-二叉树-二叉树的层序遍历(相关题目总结)

思路 层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。 需要借用一个辅助数据结构即队列来实现&#xff0c;队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的…...

fundamental notes in 3D math

平面方程 a x b y c z d axbycz d axbyczd, 法向量 a , b , c a,b,c a,b,c, 点到平面的距离为 d / s q r t ( a 2 b 2 c 2 ) d / sqrt(a^2 b^2 c^2) d/sqrt(a2b2c2) , 距离可为正, 为负, 为正表示跟法向量方向一致, 为负表示相反 点 ( x o , y o , z o ) (x_o, y_o, z…...

【Java 进阶篇】JQuery DOM操作:舞动网页的属性魔法

在前端的舞台上&#xff0c;属性操作是我们与HTML元素进行互动的关键步骤之一。而JQuery&#xff0c;这位前端开发的巫师&#xff0c;通过简洁而强大的语法&#xff0c;为我们提供了便捷的属性操作工具。在这篇博客中&#xff0c;我们将深入研究JQuery DOM操作中的属性操作&…...

腾讯云5年云服务器还有吗?腾讯云5年时长服务器入口在哪?

如果你是一名企业家或者是一个热衷于数字化转型的创业者&#xff0c;那么腾讯云最近推出的一项优惠活动绝对不会让你无动于衷。现在&#xff0c;腾讯云正在大力推广一项5年特价云服务器活动&#xff0c;只需要花费3879元&#xff0c;你就可以享受到腾讯云提供的优质服务。 腾讯…...

odoo在iot领域的发展情况

Odoo 是一个全面的集成商业管理软件套装&#xff0c;主要提供企业资源规划 (ERP)、客户关系管理 (CRM)、电子商务、会计、库存管理等功能。在 IoT&#xff08;物联网&#xff09;领域&#xff0c;Odoo 侧重于通过提供一个中心化的平台来整合多方面的业务流程&#xff0c;包括生…...

Paas-云原生-容器-编排-持续部署

了解云原生 云原生架构让企业的基础设施,从简单的资源池化,转向以应用为中心,为应用赋能的敏捷、自运维、安全的云原生基础设施。以应用为中心的云原生基础设置,可以支持多种类型的应用,如微服务应用,中间件应用和AI 应用;可以提升应用交付效率,简化应用管理的复杂度;…...

sass 生成辅助色

背景 一个按钮往往有 4 个状态。 默认状态hover鼠标按下禁用状态 为了表示这 4 个状态&#xff0c;需要设置 4 个颜色来提示用户。 按钮类型一般有 5 个&#xff1a; 以 primary 类型按钮为例&#xff0c;设置它不同状态下的颜色&#xff1a; <button class"btn…...

DevEco Studio开发工具下载、安装(HarmonyOS开发)_For Mac

一、说明 初学HarmonyOS开发&#xff0c;DevEco Studio开发工具的安装和使用是必须的。 &#xff08;注&#xff1a;不多废话&#xff0c;跟着下面流程操作下载、安装DevEco Studio即可。&#xff09; 二、下载DevEco Studio 1.官网下载地址&#xff1a; https://developer.…...

按键精灵中的字符串常用的场景

在使用按键精灵编写脚本时&#xff0c;与字符串有关的场景有以下几种&#xff1a; 1. 用时间字符串记录脚本使用截止使用时间 Dim localTime "2023-11-12 00:15:14" Dim networkTime GetNetworkTime() TracePrint networkTime If networkTime > localTime The…...

python数据结构与算法-01_抽象数据类型和面向对象编程

Python 一切皆对象 举个例子&#xff0c;在 python 中我们经常使用的 list l list() # 实例化一个 list 对象 l l.append(1) # 调用 l 的 append 方法 l.append(2) l.remove(1) print(len(l)) # 调用对象的 __len__ 方法在后面实现新的数据类型时&#xff0c;我们将…...

纯手写 模态框、消息弹框、呼吸灯

在有些做某些网页中&#xff0c;应用不想引用一些前端框架&#xff0c;对于一些比较常用的插件可以纯手写实现 1、模态框 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Water Ripple Effect</title> <style…...

windows安装composer并更换国内镜像

第一步、官网下载 下载地址 Composer安装https://getcomposer.org/Composer-Setup.exe第二步、双击安装即可 第三步选择 php安装路径并配置path 第四步、 composer -v查看安装是否成功&#xff0c;出现成功界面 第五步、查看镜像地址并更换&#xff08;composer国内可能较慢…...

c++ basic_string 和string区别

在C中&#xff0c;basic_string 是一个模板类&#xff0c;而 string 是 basic_string 的一个具体实例化&#xff0c;即 basic_string<char>。basic_string 模板类被设计为支持多种字符类型&#xff0c;而 string 是其中一种特定字符类型的字符串类。 具体来说&#xff0…...

怎么在uni-app中使用Vuex 简单demo,通俗易懂(第二篇)

Vuex是Vue.js的官方状态管理库&#xff0c;可以帮助我们更好地管理和维护复杂状态和数据共享。在Vuex中&#xff0c;整个应用的状态被集中到一个单一的状态树中&#xff0c;这个状态树包含了所有的共享状态和数据。通过状态管理模块、getter、mutation、action等机制&#xff0…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...