Flutter的响应式编程

我们可能都听说过响应式编程这个名词,但什么是响应式编程呢?我们先看看维基百科上的定义:

Flutter的响应式编程_第1张图片

这里面有很多的名词,像declarative programming paradigm(声明式编程范式),imperative programming paradigm(指令式编程范式),data stream(数据流),propagation of change(变化的传播,很多文章翻译成传播变化,在没有英文原文的时候真不知道是啥意思)等。也举了一个很简单明了的例子,意思就是说我们的代码要使得当自变量变了以后,因变量自动的变化,而不用再额外写代码去改变因变量。响应式编程其实是一种编程思想,一种编程范式,一种编程哲学。要完全理解它,还是需要一些思考的。本文的重点在propagation of change上。

我们先用Android开发的例子形象的描述一下什么是指令式编程。假设我们有一个页面,需要去服务器上拉取一些信息,然后展示出来。我们需要怎么做呢?

public class TestActivity extends Activity implements View.OnClickListener {

    TextView mTitle;
    TextView mDescription;
    Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        mTitle = findViewById(R.id.title);
        mDescription = findViewById(R.id.description);
        mButton = findViewById(R.id.button);
        mButton.setOnClickListener(this);

        mTitle.setText("Hello");

        fetchDataFromServer();
    }

    private void fetchDataFromServer() {
        HttpResponse resp = ...;
        String desc = resp.get...;
        mDescription.setText(desc);
    }

    @Override
    public void onClick(View v) {
        if (v == mButton) {
            mDescription.setText("");
        }
    }
}

1、我们首先需要在onCreate里去指定UI布局文件,然后通过findViewById将所有后面需要使用到的view搜索出来,并保存它们的引用

2、对于不依赖服务端数据的本地静态内容,我们可以直接给他设值,比如通过mTitle.setText("Hello")设个标题

3、发起网络请求去服务端拉取数据

4、网络请求返回后,直接操作各个view,给其设值,比如mDescription.setText(desc)

5、用户点击某个按钮

6、响应点击事件,直接操作各个view,改变其值,比如mDescription.setText("")

这是一个很典型的Android页面的编写,在这个过程中,有3个场景,我们通过写额外的代码,修改了UI。这是典型的命令式编程范式。

那么Flutter是怎么做的呢?Flutter文档里有一句话概括了一下:

By managing state in this way, you don’t need to write separate code for creating and updating child widgets. Instead, you simply implement the build function, which handles both situations.

import 'dart:io';

import 'package:flutter/material.dart';

class TestWidget extends StatefulWidget {

  @override
  State createState() => TestWidgetState();

}

class TestWidgetState extends State {

  String _description;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hello'),
      ),
      body: Center(
        child: Text(_description),
      ),
      floatingActionButton: FloatingActionButton(
          child: Icon(Icons.sentiment_very_satisfied), onPressed: changeDescription),
    );
  }

  @override
  void initState() {
    super.initState();
    fetchDataFromServer();
  }

  void fetchDataFromServer() {
    HttpResponse resp = ...;
    setState(() {
      _description = resp.get...;
    });
  }
  
  void changeDescription() {
    setState(() {
      _description = '';
    });
  }

}

从Flutter的代码里我们可以看到,UI的展示完全由build函数决定,所以像Android分散到各处的修改UI的代码被收敛到了一处,而build函数用state数据决定怎么构造UI。当state变化之后,只需要通过setState函数通知框架即可,框架则立即自动的更新UI,而不需要额外写代码去更新UI,这便是典型的响应式编程范式了。

 

References:

https://en.wikipedia.org/wiki/Reactive_programming

https://medium.com/@jasonyuh/%E5%85%B3%E4%BA%8Ereactive-programming-24a2cf28fffa

 

你可能感兴趣的:(Flutter,响应式编程,Flutter)