示例

OKHttp网络请求:

FormBody formBody = new FormBody.Builder().add("pay_fee", String.valueOf(product.getProductPrice())).add("product_name", String.valueOf(product.getProductName())).add("access_token", "").build();Request request = new Request.Builder().post(formBody).url(createOrderURL).build();OkHttpClient okHttpClient = new OkHttpClient();
Call call = okHttpClient.newCall(request);
call.enqueue(null);

Glide的图片加载:

Glide.with(this).load(sampledPhotoPath).asBitmap().format(DecodeFormat.ALWAYS_ARGB_8888).skipMemoryCache(true).transform(new FilterEffectBitmapTransformation(this,mFilterInfo, sampledPhotoPath)).into(mBinding.appBeautyFilterMarkPhotoIv);

调用上面的代码的感觉“爽”,接口简单,方便的网络请求,方便的图片加载。从上面的代码代码看出接口的定义非常易用。我们该怎么写出如此简单易用的接口?下面我们一起探讨一下。

从上面代码可以看出配置的时候的使用了.的一步步的连接起来,其实这种方式采用了Builder模式,使得接入的时候非常方便,而且代码很清晰。

OKHttp结构图:

OKHttp的接口

  • 对外接口

    • OkHttpClient, Builder用于全局的请求配置和作为Call的工厂方法
    • Request,Builder, RequestBody用于构建请求数据
    • Call可执行的网络请求
  • 底层接口执行网络请求,比如Dispather请求分发,Interceptor,Chain等类被上层接口封装,不暴露给client。

Glide的结构图:

Glide的接口:

  • 对外接口:

    • Glide,RequestManager,GenericRequestBuilder封装了底层接口
  • 底层接口是实际的图片加载。基本不暴露给client使用,除非涉及到了相关的配置。

其实上面的对外接口的设计用到了一种设计模式Facade模式。此模式封装子系统,向外提供了更高层的接口主要有以下几个好处:

  • 提高了对外接口的易用性,降低了接入成本
  • 子系统的不想暴露的接口可以隐藏,更好的体现了面向对象的思想。
  • 子系统做兼容,或者是代码重构,亦或是流程修改,只要高层接口不改变,不会影响到client。

从上面我们得出了提高对外接口的易用性的常用的设计方式

  • Builder模式用于配置
  • Facade模式封装子系统来提供对外的高层接口

下面我们就简单介绍一下如何使用这两种设计模式。

设计模式

Builder模式

基础知识,可参考 刘伟的博客。

建造者模式(一)

建造者模式(二)

建造者模式(三)

这个模式在对外接口设计中一般用于配置或者构建复杂对象。

比如OKHttp里的配置:

OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).build();

为了简化这里只是列举了部分信息。

public static final class Builder {int connectTimeout;int readTimeout;public Builder() {connectTimeout = 10_000;readTimeout = 10_000;}Builder(OkHttpClient okHttpClient) {this.connectTimeout = okHttpClient.connectTimeout;this.readTimeout = okHttpClient.readTimeout;}public Builder connectTimeout(long timeout, TimeUnit unit) {connectTimeout = checkDuration("timeout", timeout, unit);return this;}public Builder readTimeout(long timeout, TimeUnit unit) {readTimeout = checkDuration("timeout", timeout, unit);return this;}public OkHttpClient build() {return new OkHttpClient(this);}
}
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {final int connectTimeout;final int readTimeout;public OkHttpClient() {this(new Builder());}OkHttpClient(Builder builder) {this.connectTimeout = builder.connectTimeout;this.readTimeout = builder.readTimeout;}public int connectTimeoutMillis() {return connectTimeout;}public int readTimeoutMillis() {return readTimeout;}}
  • Builder构建OkHttpClient的时候,客户端可以配置信息,然后调用build就可以构建成功。
  • Builder构建OKHttpClient的时候,readTimeout接口或者connectTimeout接口返回Builder对象,这样的客户端调用的时候只需要用.来连接相关的方法,更加方便。

大家也可以查看GenericRequestBuilder如何构建Request的,或者Android的Intent的类,来了解Builder的使用。

实现的技巧:

  • 实现的时候必要参数可以在构造函数中传递,其他的使用接口设置
  • Builder的类返回的函数可以返回当前的对象,以此可以使用调用的.的符号记性连接。

Facade设计模式

为子系统的一组接口提供一个一致的界面,Facade模式定义了一些高层接口,这些接口使得子系统更加容易使用。

下面以我以前做的游戏联运的SDK为例。

对外提供接口这里使用了Facade模式,

  • MTOnlieGameSDK为主要的对外的高层接口类。
  • MTOnlieGameSDK封装了其他子系统,MTAccountManager,MTPayManager
  • 同时MTAccountManager,MTPayManager也使用了Facade模式,MTAccountManager封装帐号SDK,MTPayManager封装了与支付APK的通信。

Notice:

  1. 封装了子系统对外的接口得到简化,提高了对外接口的易用性。
  2. 使用Facade模式封装更高层的接口,避免了不必要的接口的暴露,同时子系统与客户端代码分离,提高了代码的独立性。比如更改MTAccountManager的实现不会影响到client的代码修改。

此外在层次结构接口中引入Facade模式封装每个层级,可以简化层级之间的依赖。

其他问题

  • 接口的暴露,不需要的接口尽量不暴露用户。
  • 参数的数量的问题,一方面尽量减少参数,一般参数3个左右为宜,多了可以使用封装成类进行传递。
  • 参数依赖抽象类,比如Activity和Context的使用,能使用Context尽量不要使用Activity等等。也就是尽量使用接口而不是具体类。
  • 工厂方法或者抽象工厂来创建对象。比如OKHttp的Call.Factory。

注意:

  1. 设计模式的使用只是为了得到好的代码设计,而过度使用会造成冗余,三思再用。
  2. 设计模式的使用不要过于依赖所谓的类图或者结构图,往往稍微变化的设计模式更好用。

参考资料

  • 设计模式-可复用面向对象软件的基础 只服四人帮的这本书,虽然例子和内容过时了,但设计思想杠杠的。
  • LoveLion的博客

`

组件对外接口设计-易用性相关推荐

  1. 对系统组件化接口设计的一点看法

    今天海浪分享一篇对系统组件化接口设计的一点看法.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:of ...

  2. 其他系统 对外接口设计_外观模式:统一接口 VS.暴露细节

    什么是接口--java语言中的接口 Java类中定义的所有public型的方法都可以被简单地视为该类对外提供的接口. 抽象类中public型的抽象方法,可以被看成是整棵继承树的对外接口. 对于Java ...

  3. 其他系统 对外接口设计_设计模式分类及设计原则

    点击蓝字,关注我们 01 概述 设计模式的基础是:多态. 学习设计模式将有助于更加深入地理解面向对象思想,让你知道: 1.如何将代码分散在几个不同的类中? 2.为什么要有"接口"? ...

  4. 其他系统 对外接口设计_领导:项目有个接口要对外开放,小张你来设计一下?...

    前言 最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要:这里整理了一下常用的一些安全措施以及具体如何去实现. 安全措施 个人觉得安全措施大体来看主要在两 ...

  5. 16. 设计模式之契约原则:如何做好 API 接口设计?

    一.契约式设计原则:API 设计的指导书 无论是架构设计还是编码实现,现在都越来越离不开接口设计,接口可以说是新时代的"集装箱",是得到了几乎所有人一致共识的通用标准. GoF 在 ...

  6. 优秀的API接口设计原则及方法

    一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的 ...

  7. API接口设计之RESTful软件架构风格

    说到API接口设计有的喜欢用Web Service,有的喜欢用WCF,当然也有还在用最原始的ashx,aspx页面的.无论采用什么方式能很好的满足业务需求就ok,但是不同的方式在扩展性.易用性,可维护 ...

  8. 腾讯技术分享:微服务接口设计原则

    来源|腾讯技术工程(ID:Tencent_TEG) 本文结合自身后台开发经验,从高可用.高性能.易维护和低风险(安全)角度出发,尝试总结业界常见微服务接口设计原则,帮助大家设计出优秀的微服务. 1.前 ...

  9. 接口设计,这36个核心知识点一定要注意

    目录 前言 设计好接口的 36 个锦囊 总结 前言 作为后端开发,不管是什么语言,Java.Go 还是 C++,其背后的后端思想都是类似的.我们做后端开发工程师,主要工作就是:如何把一个接口设计好.所 ...

最新文章

  1. Linux入门(四)
  2. Android vector标签 PathData 画图超详解
  3. Exchange Server 2016管理系列课件53.DAG管理之设置滞后数据库副本
  4. 散列(hash)练习题
  5. [css] img标签是行内元素,为什么却能设置宽高
  6. 数据管理,数据治理,数据中心,数据中台,数据湖这下就分清楚了!
  7. JQuery 绑定事件
  8. anaconda 安装在c盘_Anaconda安装和使用原来这么简单...
  9. 冒泡、选择、快速、归并、堆排序算法 python实现
  10. 家到学校路线图怎么画_从家到学校的详细地图怎么画?
  11. 《NAT穿越(NAT-T)RFC3947文档》记录
  12. 华为员工吐槽加班太多,晒出7天上班打卡记录网友:不怕猝死吗?
  13. linux lsof详解
  14. Python(贪心算法)问题 D: 删数问题_输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右次序组成一个新的正整数。
  15. python 免费空间_用python做大数据
  16. PowerDesigner根据数据库生成数据字典
  17. python批量检索文献pubmed_如何使用PubMed高效检索文献
  18. python生成word 带目录_利用python程序生成word和PDF文档的方法
  19. 2021-06-11警告: 多个不同应用注册了相同服务,请检查
  20. 让Windows系统自动登陆,支持XP 2003 win7 win2008 win10

热门文章

  1. 多模态学习(一) 初识
  2. 怎么用xmind做读书笔记
  3. 调用WindowsMedia播放器与Flash播放器
  4. python 输入一个数,判断是不是水仙花数
  5. linux内存不足解决办法
  6. 德国电信疫情期间净赚9个亿
  7. 华为机试题目:工单调用策略
  8. Keil C51中头文件INTRINS.H的作用
  9. 影像传感器尺寸换算(英寸-毫米)
  10. 山特UPS不间断电源的主要技术参数