Posts 设计模式-回调机制
Post
Cancel

设计模式-回调机制

概念解析

回调机制,回调指的是:把函数作为参数,传递给另一个函数,延迟到另一个函数的某个时刻执行的过程为回调,本质上是函数式的一种体现。如果语言只支持面向对象编程,则可以使用策略模式来实现回调机制。 优点:

  • 避免重复代码
  • 增强代码可维护性
  • 有更多定制功能

缺点:

  • 避免“回调地狱”:多重的回调函数调用

常用场景:

  • 第三方库和框架中
  • 异步执行(例如读文件、发送HTTP请求等)

设计模板

回调机制的代码框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
def callback(*args, **kwargs):
    """回调函数"""
    # todo 函数体的实现


def otherFun(fun, *args, **kwargs):
    """高阶函数:也叫包含函数"""
    # todo 函数体的实现


# 函数的调用方式
otherFun(callable)

实例分析

场景说明:提供HTTP的异步下载功能,所谓异步:前一个任务还没有执行完毕,就可以执行后一个任务(前一个任务执行后会收到一个通知):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import requests
from threading import Thread


class DownloadThread(Thread):
    """下载文件的线程"""

    # 每次写文件的缓存大小
    CHUNK_SIZE = 1024 * 512

    def __init__(self, filename, url, save_path, callback_progress, callback_finished):
        super().__init__()
        self.__filename = filename
        self.__url = url
        self.__save_path = save_path
        self.__callback_progress = callback_progress
        self.__callback_finished = callback_finished

    def run(self):
        readsize = 0
        r = requests.get(self.__url, stream=True)
        totalsize = int(r.headers.get('Content-Length'))
        print("[下载%s]文件大小:%d" % (self.__filename, totalsize))
        with open(self.__save_path, "wb") as file:
            for chunk in r.iter_content(chunk_size = self.CHUNK_SIZE):
                if chunk:
                    file.write(chunk)
                    readsize += self.CHUNK_SIZE
                    self.__callback_progress(self.__filename, readsize, totalsize)
        self.__callback_finished(self.__filename)


def test_download():
    def download_progress(filename, readsize, totalsize):
        # 定义显示下载进度的回调函数
        percent = (readsize / totalsize) * 100
        print("[下载%s] 下载进度:%.2f%%" % (filename, percent))

    def download_finished(filename):
        # 定义下载完成后的回调函数
        print("[下载%s] 文件下载完成!" % filename)

    print("开始下载TestForDownload1.pdf...")
    downloadurl1 = "http://xxxx.pdf"
    download1 = DownloadThread("TestForDownload1", downloadurl1, "./download/1.pdf", download_progress, download_finished)
    download1.start()

    print("开始下载TestForDownload2.pdf...")
    downloadurl2 = "http://yyyy.pdf"
    download2 = DownloadThread("TestForDownload2", downloadurl2, "./download/2.pdf", download_progress, download_finished)
    download2.start()

    print("执行其他的任务...")
This post is licensed under CC BY 4.0 by the author.

设计模式-对象池技术

设计模式-MVC模式