三思系列:“声明式UI“和“命令式UI“,你的理解可能是错的

本文探讨了AndroidUI构建中的命令式和声明式方法,通过ViewAPI、XML布局文件和响应式设计的视角,分析了这两种编程风格在内容呈现和交互上的应用。作者强调了声明式UI框架的重要性,并讨论了XML布局方式被推荐的原因及其逐渐被淘汰的过程。
摘要由CSDN通过智能技术生成

甚至,接口的表现形式是一种 语言

接口被定义时,其表意即已固定,当其表意:

  • 越倾向于 现实表达 时,呈现为 声明式

  • 越倾向于 执行过程 时,呈现为 命令式

UI


User Interface 的简称,直译为用户界面

UI系统需要处理两个范畴的事情:

  • 内容呈现、反馈

  • 用户交互

另外,还需要程序 构建 出UI。

我们需要从这 三个角度 来看。

构建UI时的 命令式 和 声明式


我们在Android原有的知识领域中看这个问题。

我们知道,这部分内容设计时是遵守 OOP 的,存在一整套 View 类簇。而界面由具体的功能类组建出 视图树

我们需要讨论的,就是 视图树构建。我们知道:

ViewGroup 存在一系列 addView 方法,通过它们,最终实现 树结构

这套 接口 ,倾向于 执行过程,直接使用这套接口去构建,就是 命令式 的构建。

而在此基础上,封装了 LayoutInflater,将 xml语法 表达的 结构树 转换为 视图树, 此时我们使用的 接口 ,其表现形式是 xml语言

按照特定的规则,我们 直接描述期望的结果,这更倾向于 现实表达,这样的构建方式,就是 声明式

View 存在一系列的 布局属性,一些直接持有,一些被LayoutParams封装而间接持有。

视图树 的节点构建过程中,还需要处理 布局属性

按照刚才的讨论,我们很容易得出:

  • 直接使用 View的API 或者 LayoutParams的API,或者直接对属性赋值,可以断言是 命令式 范畴。

  • 而在布局文件中,声明对应的属性值,可以断言是 声明式 范畴

小结:本段内容,我们讨论了构建UI的两种做法。并讨论了其所属的范畴。

Android体系最基础的内容中,内容呈现&交互


在最基础的内容中,讨论 内容呈现交互 部分使用的API,是 命令式 的,还是 声明式 的,这 非常的无聊

内容呈现时的 命令式 与 声明式

View 提供的 接口 中,例如:

  • TextView#setText(Charsequence cs)

  • ImageView#setImageDrawable(Drawable d)

等,更加偏向于 执行过程

但是注意,此时 执行过程现实表达 的界限已经有点模糊了 。我们不必 牵强附会

读一下这两句话:

  • 我们通过调用相应API设置了需要显示的内容

  • 我们在布局文件中指明了视图显示时需要呈现的内容

交互时的 命令式 与 声明式

我们知道,Android View 体系中,封装了一系列 Listener,通过 接口回调,让程序可以 监听 到用户发出的 交互指令

除此之外,在 最基础内容 中,仅有简陋的 click 属性可以声明点击事件的 消费函数


此时,我们 放大着眼点 。我们处理视觉呈现和交互时,面向的两个重要对象

信息展示

| ================ |

| 内容呈现 |/

|=| |=|

| 实体 | | UI |

|=| |=|

/|\ 交互 |

| ================ |

状态变更

复制代码

这两者之间存在两条线:

  • 代表信息实体 -> UI, 这是 内容呈现 ,实质是:在UI上做 信息展示

  • UI -> 代表信息实体 ,这是 交互 ,实质是:在信息实体上做 状态变更,即变更信息

我们在实现这两条线时:

  • 如果直接利用 了倾向于 现实表达 的高阶框架封装,那这个框架就是 声明式的框架;

  • 如果仅使用 低阶view层api ,自行实现了逻辑,那就是 命令式 的编程,毕竟也没用啥框架;

评价一套 UI工具体系 是否是 声明式 的,要从这三个方面看,如果在三个方面均进行了封装,提供的 接口 都偏向于 现实表达,那是成熟完善的 声明式UI 框架。

看几个例子:

  • 直接使用 View体系的接口 构建UI、处理显示和交互,这是 命令式编程

  • 使用 LayoutInflater 工具和 xml表达的布局文件。绝大多数情况下,还需要通过映射关系,找到View对象;并进一步 根据业务逻辑 ,操作 View对象 实现内容呈现和交互逻辑。 这是 声明式构建命令式编程 处理显示和交互。这套工具并不是完善的 声明式UI开发工具

  • 使用 LayoutInflater 工具 + DataBinding工具包xml表达的布局文件DataBingding + LayoutInflater是一套完善的 声明式UI框架

  • Compose,完善的 声明式UI框架

思考:为什么当初XML布局方式受到官方推荐


很大一方面是Java语言特性的原因,最开始,都是使用Java语言编写业务逻辑,而基于Java,很难直接定义DSL

注:Java语言很难直接定义DSL 这一点我并没有做严格的调研考证,如果有谬误,请指出。

而基于Groovy等语言开发符合 DSL声明式UI框架,必然要引入Groovy,这在当时也和 主流 格格不入,虽然Google很喜欢创新。

所以,官方提出了 布局业务 分开,这样也有很多好处:

  • 业务逻辑的 模块内聚性复用度 可提升

  • 开发者可以提升专注度

  • xml树view树 之间 关系明了,借助成熟内容,快速开发出 预览工具

思考:为什么XML布局方式走在被淘汰的路上


因为使用XML布局的方式存在 先天弱点 ,它和 业务逻辑 天生生活在两个世界。

这意味着,必然存在一个 加载器 或者 转换器,在 运行时 或者 编译时,将 xml语法 所描述的 声明式布局 转换到 业务逻辑 所在的世界。

所以,并不是 DataBinding 这一 声明式UI框架 不够优秀,而是 xml 和 业务逻辑代码 之间天生的屏障不够 人道主义

而推行 kotlin first 也有一段时间了,基于kotlin,开发 DSL 工具包非常的方便。

延伸:响应式UI框架


这也是 Modern Development 中非常热门的一个词,响应式 是对特点的一种描述,方法论是:事件驱动,Event-Driven发布订阅者模式

这个概念,和前面提到的 声明式UI框架命令式UI编程 没有必然的联系,它所表达的是: 代表信息的实体UI 之间的互操作是符合 响应式 特征的。

但可以想象,要实现响应式,其接口变现特征,天然倾向于 现实表达;如果是倾向于 操作过程,可以断言其抽象程度非常低。

扣题:勘误


再看到这些说法,我们可以判断出它们存在 谬误

  • 基于xml无法实现声明式UI

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

尾声

最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

[外链图片转存中…(img-rWeBh9Y9-1713449398188)]

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-vQ1HPwXx-1713449398189)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
介绍:facebook开源了litho一个高效的声明UI框架。运行效果:使用说明:dependencies {   // ...   // Litho   compile 'com.facebook.litho:litho-core:0.2.0'   compile 'com.facebook.litho:litho-widget:0.2.0'   provided 'com.facebook.litho:litho-annotations:0.2.0'     annotationProcessor 'com.facebook.litho:litho-processor:0.2.0'      // SoLoader    compile 'com.facebook.soloader:soloader:0.2.0'     // Optional   // For debugging   debugCompile 'com.facebook.litho:litho-stetho:0.2.0'     // For integration with Fresco   debugCompile 'com.facebook.litho:litho-fresco:0.2.0'     // For testing   testCompile 'com.facebook.litho:litho-testing:0.2.0' }测试是否安装成功可以在activity中使用Litho创建一个view来测试是否安装成功。首先,初始化SoLoader。Litho依赖于SoLoader,它帮助加载由布局引擎Yoga提供的本地库。Application类适合做这件事情:[MyApplication.java] public class MyApplication extends Application {     @Override   public void onCreate() {     super.onCreate();          SoLoader.init(this, false);   } }然后把一个Litho文本控件放到一个activity中,显示“Hello World!”:[MyActivity.java] import com.facebook.litho.ComponentContext; import com.facebook.litho.LithoView;   public class MyActivity extends Activity {     @Override   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);          final ComponentContext c = new ComponentContext(this);       final LithoView lithoView = LithoView.create(       this /* context */,        Text.create(c)             .text("Hello, World!")             .textSizeDip(50)             .build());            setContentView(lithoView);   } }现在运行app应该就能看到屏幕上显示“Hello World!” 了。注:不久前翻译了一篇文章Components for Android: 一个高效的声明UI框架 ,现在判断就是说的这个库了,那个时候还没开源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值