Android设计模式详解之外观模式

news2024/11/25 16:32:01

前言

外观模式也称门面模式,在开发过程中的运用频率非常高;

定义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行;门面模式提供一个高层次的接口,使得子系统更易于使用;

使用场景:

  • 为一个复杂子系统提供一个简单接口;外观模式可以提供一个简单统一的接口,对外隐藏子系统的具体实现、隔离变化;
  • 需要构建一个层次结构的子系统时,使用门面模式定义子系统中每层的入口点;如果子系统之间是相互依赖的,你可以让他们仅通过门面接口进行通信,从而简化它们之间的依赖关系;

UML类图:
门面模式UML
Facade:系统对外的统一接口,系统内部系统地工作;
SystemA、SystemB、SystemC:子系统接口;

外观模式比较简单,就是通过一个统一的接口对外提供服务,使得外部程序只通过一个类就可以实现系统内部的多种功能;

示例代码

这里以手机功能举例,手机集合了电话、拍照功能,通过手机就可以完成各种功能,而不是说打电话需要一个手机,拍照还需要一个相机;下面我们就使用外观模式进行实现;

  • 定义相机接口,Camera
/**
 * 相机接口
 */
interface Camera {

    /**
     * 打开相机
     */
    fun open()

    /**
     * 拍照
     */
    fun takePicture()

    /**
     * 关闭相机
     */
    fun close()
}
  • 定义相机实现类,CameraImpl
/**
 * 相机实现类,相当于子接口
 */
class CameraImpl : Camera {
    override fun open() {
        println("打开相机")
    }

    override fun takePicture() {
       println("相机拍照")
    }

    override fun close() {
        println("关闭相机")
    }
}
  • 定义电话功能接口,Phone
/**
 * 电话功能
 */
interface Phone {

    /**
     * 打电话
     */
    fun dail()

    /**
     * 挂断
     */
    fun hangup()
}
  • 定义电话功能实现类,PhoneImpl
/**
 * 电话实现类,相当于子系统
 */
class PhoneImpl : Phone {
    override fun dail() {
        println("打电话")
    }

    override fun hangup() {
        println("挂断电话")
    }
}
  • 定义手机类,Mobile
/**
 * 启动电脑,系统统一接口
 */
class Mobile {
    private val phone = PhoneImpl()
    private val camera = CameraImpl()

    /**
     * 视频通话
     */
    fun videochat() {
        println("视频通话中")
        camera.open()
        phone.dail()
    }

    /**
     * 拍照
     */
    fun takePicture() {
        camera.takePicture()
    }

    /**
     * 挂断电话
     */
    fun hangup() {
        phone.hangup()
    }


}
  • 编写测试代码
object Test {

    @JvmStatic
    fun main(args: Array<String>) {
       val mobile = Mobile()
        mobile.videochat()
        println("-----------------")
        mobile.hangup()
        println("-----------------")
        mobile.takePicture()

    }
}

代码输出结果如下:

视频通话中
打开相机
打电话
-----------------
挂断电话
-----------------
相机拍照

Android源码中的外观模式

  • ContextImpl类
class ContextImpl extends Context {

    @Override
    public void startActivity(Intent intent, Bundle options) {
		...
        mMainThread.getInstrumentation().execStartActivity(
                getOuterContext(), mMainThread.getApplicationThread(), null,
                (Activity) null, intent, -1, options);
    }

	 @Override
    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, false, mUser);
    }
    
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManager.getService().startService(
                    mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                    getOpPackageName(), getAttributionTag(), user.getIdentifier());
   				...
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }



    @Override
    public void sendBroadcast(Intent intent) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            intent.prepareToLeaveProcess(this);
            ActivityManager.getService().broadcastIntentWithFeature(
                    mMainThread.getApplicationThread(), getAttributionTag(), intent, 			resolvedType,
                    null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false,
                    false, getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}

可以看到ContextImpl封装了startActivitystartServicesendBroadcast一系列核心方法,而各个方法内部又是通过调用其它类来实现的,很明显是外观模式

  • Retrofit类,感兴趣的小伙伴可以查看Retrofit原理解析(二)

总结

优点:

  • 对客户程序隐藏子系统的细节,减少客户端对于子系统的耦合,能够拥抱变化;
  • 外观类对子系统的接口封装,使得系统更易于使用;

缺点:

  • 外观类接口膨胀,由于子系统的接口都有外观类统一对外暴露,使得外观类API接口较多,在一定程度上增加了用户使用成本;
  • 外观类没有遵循开闭原则,当业务出现变更时,需要直接修改外观类;

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

6.3 Docker

目录 6.3.1 Docker概述 6.3.1.1 什么是Docker 6.3.1.2 Docker组成 6.3.2 Docker的安装 6.3.2.1 下载Docker依赖的环境 6.3.2.2 指定Docker镜像源 6.3.2.3 安装Docker 6.3.2.4 启动Docker并测试 6.3.3 Docker的中央仓库 6.3.4 Docker操作 6.3.4.1 镜像操作 6.3.4.…

从url获取参数并转为对象

const getParameters URL > JSON.parse({"${decodeURI(URL.split("?")[1]).replace(/"/g, \\").replace(/&/g, ",").replace(//g, ":")}"})getParameters("https://www.google.com.hk/search?qjsmd&neww…

【深度学习】李宏毅2021/2022春深度学习课程笔记 - Self-supervised Learning(自监督式学习)

文章目录一、芝麻街与进击的巨人二、Self-supervised Learning三、BERT3.1 Masking Input3.2 Next Sentence Prediction3.3 GLUE 任务集3.4 How to use BERT3.4.1 Case13.4.2 Case23.4.3 Case33.4.4 Case43.5 Training BERT is challenging!3.6 Pre-Training a Seq2Seq Model3.…

ERP是什么意思?

“ERP到底是一个怎么样的存在&#xff1f;为何有那么多的方面&#xff1f;如何学习&#xff1f;” 本文从ERP起源讲起&#xff0c;结合制造业离散制造与流程制造的ERP系统区别&#xff0c;详解ERP概念。 文章有点长&#xff0c;但如果你耐心看完&#xff0c;相信你会对ERP有一…

elasticsearch 基本语法(常见的RESTFUL API)

一 . ES的基本语法 文章目录一 . ES的基本语法1.Query String 语法2.Query DSL 语法3. Full-text queries 全文检索4. Phrase search 短语搜索5.Query and filter 查询和过滤6. Compound queries 查询7.HighLight search(高亮显示)测试数据内容&#xff1a;PUT /product/_doc/1…

科研试剂 Dextran-DBCO;葡聚糖-二苯并环辛烯;生物可降解高分子聚合物

DBCO修饰的葡聚糖聚 Dextran-DBCO 葡聚糖-二苯并环辛烯 名称&#xff1a;DBCO修饰葡聚糖 英文名称&#xff1a;Dextran-DBCO 外观状态&#xff1a;白色粉末 溶剂&#xff1a;DMSO等常规有机溶剂。 性状&#xff1a;基于不同的分子量&#xff0c;呈白色/类白色固体粉末&…

python爬虫(一)

一、理论 &#xff08;1&#xff09;URL管理器&#xff1a;网页之间的链接很复杂&#xff0c;a指向b&#xff0c;b指向a&#xff0c;如果不对其进行管理则可能导致重复爬取、循环爬取&#xff0c;因此单独用该模块进行管理。URL管理器有两个功能&#xff0c;分别是URL队列管理&…

神策营销云平台化应用实践

营销云是一个业务系统&#xff0c;需要贴合客户的实际业务场景&#xff0c;以平台化 分层设计撬动场景发挥价值主张。本文将详细介绍神策营销云在数字化转型浪潮中的沉淀。点击文末“阅读原文”立即观看完整版演讲回放。一、神策营销云产品理念“营销云是一个业务系统”&#…

规范有效的需求变更管理,分7步走。

1、建立需求基线 需要提前建立需求基线&#xff0c;需求基线是需求变更的依据&#xff0c;并需制定双方皆认可的需求变更流程。 需对用户需求进行明确分析&#xff0c;颗粒度越小越好。基准文件定位范围越详细&#xff0c;双方对需求越清晰&#xff0c;用户交流顺畅&#xff0c…

Go语言context包源码剖析

context包的作用 context包是在go1.7版本中引入到标准库中的 context可以用来在goroutine之间传递上下文信息&#xff0c;相同的context可以传递给运行在不同goroutine中的函数&#xff0c;上下文对于多个goroutine同时使用是安全的&#xff0c;context包定义了上下文类型&am…

两数之和【每日一题】

⭐前言⭐ ※※※大家好&#xff01;我是同学〖森〗&#xff0c;一名计算机爱好者&#xff0c;今天让我们进入刷题模式。若有错误&#xff0c;请多多指教。更多有趣的代码请移步Gitee &#x1f44d; 点赞 ⭐ 收藏 &#x1f4dd;留言 都是我创作的最大的动力&#xff01; 合抱之木…

MySQL数据库自动补全工具

MySQL数据库操作起来命令较多&#xff0c;默认无法使用tab键进行补全&#xff0c;所以可以安装一些实用的工具进行日常的操作 方式一&#xff1a;临时使用自动补全功能 mysql -u root -p --auto-rehash 方式二&#xff1a;永久使用自动补全功能 vi /etc/my.cnf [mysql] a…

Qt扫盲-QSqlDatabase理论总结

QSqlDatabase理论总结一、概述二、使用1. 连接数据库2. 数据库驱动3. 自定义数据驱动使用4. 注意事项三、常用的功能一、概述 QSqlDatabase类提供了通过连接访问数据库的接口。QSqlDatabase的一个实例表示一个数据库连接对象。该连接是通过Qt支持的数据库驱动程序来对数据库的…

再学C语言26:分支和跳转——goto语句

goto语句包括两个部分&#xff1a;goto和一个标签名称 goto point1; 为使goto语句工作&#xff0c;程序中必须包含由point1标签定位的其他语句 point1: printf("hello world! \n"); // 标签 冒号 一条语句 示例代码&#xff1a; /* test of goto */ #include &…

高一数学试题-2022年秋期末试卷

一、选择题 已知集合A{x∈N∣−2<x<52}A \{x \in \mathbf{N}| -2 < x < \frac{5}{2}\}A{x∈N∣−2<x<25​}&#xff0c;B{−2,−1,0,1,2,4}B \{-2, -1, 0, 1, 2, 4\}B{−2,−1,0,1,2,4}&#xff0c;则A∩BA \cap BA∩B A. {−1,0,1,2}\{-1, 0, 1, 2\}{−…

什么是AI预训练模型?

什么是预训练模型? 预训练 AI 模型是一种深度学习模型&#xff0c;在大型数据集上进行训练以完成特定任务&#xff0c;它可以按原样使用或定制以满足多个行业的应用需求。 想象一下&#xff0c;试图教一个蹒跚学步的孩子什么是独角兽。 一个好的起点可能是展示该生物的子图像…

[NOIP2017 提高组] 奶酪(C++,并查集)

题目背景 NOIP2017 提高组 D2T1 题目描述 现有一块大奶酪&#xff0c;它的高度为 hhh&#xff0c;它的长度和宽度我们可以认为是无限大的&#xff0c;奶酪中间有许多半径相同的球形空洞。我们可以在这块奶酪中建立空间坐标系&#xff0c;在坐标系中&#xff0c;奶酪的下表面…

用纯C实现单链表

前言 什么是单链表&#xff1f;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。链表的创建 需要创建一个小项目工程 创建三个文件 ⭐SListNode.h放单链表的头文件&#xff0c;函数声明 ⭐SListNode.c放单…

springcloud之Gateway服务网关

1.Gateway服务网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;该项目是基于 Spring 5.0&#xff0c;Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关&#xff0c;它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式…

游戏行业(北区)客户沙龙丨阿里云用户组北京站

2022 年 8 月 30 日&#xff0c;阿里云在北京举办了第 9 场阿里云用户组&#xff08;AUG&#xff09;活动&#xff0c;活动主题为“游戏行业&#xff08;北区&#xff09;客户沙龙”吸引了众多技术从业者及企业管理者来到现场交流分享。 通过本次活动&#xff0c;参会企业在不同…