设计模式:外观模式(Facade pattern)

发布于 2025-04-15 15:35:08 字数 3413 浏览 8 评论 0

外观模式是一个极其好用的设计模式,我们可以借助外观模式封装并隐藏复杂的底层实现代码,只暴露出简洁易用的上层接口。这样做的好处,不但可以使代码更加简洁、易于使用,而且也更容易对外观背后的复杂代码进行重构。

优化前的代码

一开始我们使用的是内置模块 urllib 实现 HTTP 请求:

import urllib.request


def get_github_root_rest_api():
    return urllib.request.urlopen('https://api.github.com') \
                         .read().decode('utf8')


def get_github_issues(username, *args):
    url = 'https://api.github.com/search/issues'
    query = f'{"+".join(args)}+user:{username}'
    return urllib.request.urlopen(f'{url}?q={query}') \
                         .read().decode('utf8')


print('\nGitHub Root REST API\n')
print(get_github_root_rest_api())

print("\nJasonWu73's Issues\n")
print(get_github_issues('JasonWu73', 'MySQL', 'Docker'))

后来我们升级 API,使用了 requests 模块:

import requests


def get_github_root_rest_api():
    return requests.get('https://api.github.com').json()


def get_github_issues(username, *args):
    url = 'https://api.github.com/search/issues'
    query = f'{"+".join(args)}+user:{username}'
    return requests.get(f'{url}?q={query}').json()


print('\nGitHub Root REST API\n')
print(get_github_root_rest_api())

print("\nJasonWu73's Issues\n")
print(get_github_issues('JasonWu73', 'MySQL', 'Docker'))

对于上面的代码,当我们修改了使用的底层 API 时,所有使用了原 API 的方法都要进行相关调整,此外由于我们将底层 API 的调用细节都写在了功能代码中,这也加重了我们功能代码的复杂性。

优化后的代码

下面,我们采用外观模式重构以上代码:

import urllib.request


def fetch_github_data(url, params):
    if params is not None:
        url = (
            f'{url}?q={"+".join(params["keywords"])}'
            f'+user:{params["username"]}')
    return urllib.request.urlopen(url).read().decode('utf8')


def get_github_root_rest_api():
    return fetch_github_data('https://api.github.com', None)


def get_github_issues(username, *args):
    return fetch_github_data('https://api.github.com/search/issues', {
        'username': username,
        'keywords': args
    })


print('\nGitHub Root REST API\n')
print(get_github_root_rest_api())

print("\nJasonWu73's Issues\n")
print(get_github_issues('JasonWu73', 'MySQL', 'Docker'))

之后,当我们升级 API,使用 requests 模块替换 urllib 模块时,只需要修改 fetch_github_data 方法即可:

import requests


def fetch_github_data(url, params):
    if params is not None:
        url = (
            f'{url}?q={"+".join(params["keywords"])}'
            f'+user:{params["username"]}')
    return requests.get(url).json()


def get_github_root_rest_api():
    return fetch_github_data('https://api.github.com', None)


def get_github_issues(username, *args):
    return fetch_github_data('https://api.github.com/search/issues', {
        'username': username,
        'keywords': args
    })


print('\nGitHub Root REST API\n')
print(get_github_root_rest_api())

print("\nJasonWu73's Issues\n")
print(get_github_issues('JasonWu73', 'MySQL', 'Docker'))

参考链接

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

天赋异禀

暂无简介

文章
评论
30 人气
更多

推荐作者

小镇女孩

文章 0 评论 0

文江

文章 0 评论 0

Tomcat

文章 0 评论 0

嘦怹

文章 0 评论 0

渃风

文章 0 评论 0

ʕ◔ϖ◔ʔ

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文