世上本没有解耦,需求改的多了也便有了解耦。 —— 产品经理

本例将通过一个计时控件,聊聊如何解耦~

本TimerView仅作为demo,不保证其健壮性,请勿在实际项目中使用。

特点

UI 容器与计时逻辑分离

UI 容器与具体 UI 布局分离

Let's Go

话说,小明在做一个电商项目,有个倒计时需求。

需求 1.0

要求"时、分、秒"数字显示。

这个简单,小明很快自定义了一个TimerView:

public class TimerView {

TextView tvHour, tvMinute, tvSecond;

TextView divider1, divider2;

...

}

需求 2.0

界面太丑啦,加点颜色和背景吧~

这个也简单,小明很快加了一些自定义属性:

public class TimerView {

TextView tvHour, tvMinute, tvSecond;

TextView divider1, divider2;

// 添加 自定义属性

int tvHourBgRes, tvMinuteBgRes, tvSecondBgRes;

int tvHourColor, tvMinuteColor, tvSecondColor;

...

}

需求 3.0

这时,产品经理又跑了过来,你看我发现了啥~

发现一套火焰数字.jpg,好炫酷的说,帮忙改上去吧~

小明内心:你 TM 有病啊!!!

你发现了么,这下小明把自己带到沟里了。新需求要求显示火焰数字图片(ImageView)。

然而,由于TimerView由TextView构成,再怎么自定义属性也实现不了新需求(ImageView)了。

说的就是你呀:https://github.com/iwgang/CountdownView

分析

为啥会这样呢?因为一开始就设计紧耦合了。

TimerView依赖了具体子类TextView,功能也就被局限在TextView了。

那我们只需这么调整一下,把TextView改成更抽象的View。

这样一来tvHour既可以是TextView,也可以是ImageView,或者某个ViewGroup,功能得以拓展:

public class TimerView {

//TextView tvHour, tvMinute, tvSecond;

View tvHour, tvMinute, tvSecond;

//TextView divider1, divider2;

View divider1, divider2;

// 自定义属性也不用了,因为无法确定 tvHour 这些究竟是啥子类。

//int tvHourBgRes, tvMinuteBgRes, tvSecondBgRes;

//int tvHourColor, tvMinuteColor, tvSecondColor;

...

}

这也体现了软件设计的一大原则:要依赖抽象(View)而不要依赖具体(TextView)。

依赖注入

还有一个问题:tvHour究竟是啥呢,这个得由用户决定。

通常我们会提供一系列setXXX()方法给用户进行设置。这个套路叫做依赖注入。

依赖注入是解耦的一种常见的方式。通常,当你有无法确定的一些东西,都应该抛给用户决定。

举个例子,View被点击时,设计者不知道你想干嘛,于是设计了View.setOnClickListener()。这是典型的依赖注入。

好了,ImageView可以支持了,然而对于界面更新ImageView和TextView肯定是不一样的。

该怎么更新又无法确定了,我们可以再次用依赖注入的方式解耦,把难题抛给用户。

因此,我设计了类似Adapter的东西,都在代码里,就不详细展开了。

需求 4.0

嗨呀~还不够啊,产品经理的脑洞总是很大的。

产品经理:我看到一个 svg 诶~

小明:算我倒霉。不过,我早就重构解耦过了。改需求, 小 case~

需求 5.0

产品经理:小明,你还活着那?我发现机械表更好看诶~

小明: **, 我改就是了

感谢

android timer 控件,TimerView 一个解耦良好的计时控件,可自由扩展。 @codeKK Android开源站...相关推荐

  1. android堆内存解析,heapsnap HeapSnap 是一款针对 Android 进程堆内存进行追踪、定位,以便查出泄露位置的工具 @codeKK c开源站...

    1.HeapSnap 是什么 HeapSnap 是一个定位内存泄露的工具,适用于 Android 平台. 主要特性如下: 对系统负载低 不需要修改目标进程的源代码 支持 Andoroid 上的大多数 ...

  2. android 商品筛选view,FilterTabView 基于 Popupwindow 实现的筛选房源信息等相关的控件,可以自由排序 @codeKK Android开源站...

    基于 Popupwindow 的下拉筛选控件 功能 区分 支持区域二级联动选择 FilterTabConfig.FILTER_TYPE_AREA 支持单行 List 样式选择 FilterTabCon ...

  3. android差分升级原理,BigNews Android 增量更新框架差分包升级 @codeKK c开源站

    支持增量包/差分包/升级包 原理:在服务器端使用 bsdiff 工具将新老安装包的差异打包为一个体积较小的差分包/升级包,然后在 App 端通过 bspatch 工具(和 bsdiff 配套的)用差分 ...

  4. 张鸿洋 视频 android,PageStateManager 在张鸿洋的 LoadingAndRetryManager 的基础上改写,优化 api,封装 @codeKK Android开源站...

    页面状态管理 在张鸿洋的LoadingAndRetryManager的基础上改写,修正一些 bug,优化 api,并提供使用时封装的例子 特性 api 超级简单 可以在 xml 中使用 Statefu ...

  5. android 混音 源码,FFmpegAndroid android 端基于 FFmpeg 实现音频剪切、拼接、转码、混音、编解码;视频剪切、水印、截图、转码、编 @codeKK c开源站...

    android 端基于 FFmpeg 库的使用 添加编译 ffmpeg.shine.mp3lame.x264 源码的参考脚本 目前音视频相关处理: 音频剪切.拼接 音频混音 音频转码 音视频合成 音频 ...

  6. android view clip,ClipView 自定义 RadiusView,包含常用的 Layout 和 View,方便扩展 @codeKK Android开源站...

    这是使用 Canvas 的 clipPath 方法实现的圆角 View,在本库中提供了个人认为常用的几个 View 如下几种: RadiusFrameLayout RadiusLinearLayout ...

  7. 使用timer控件创建一个简单的报警程序

    简介: 当我使用计算机工作时,我总是如此的专心致志,以至于每当我过了"一会儿"去看时间时,发现已经过了三个小时,而我却完全没有意识到!所以我决定使用我从Code Project学来 ...

  8. Android之通过VideoView控件播放一个视频出现的问题以及我的解决办法

    1.在Android模拟器中是可以播放视频的,可播放视频的格式为3gp.mp4.mkv等,其中我们使用VideoView控件播放一个视频时,部署到模拟器上,往往会弹出一个对话框,如下图所示: 我认为出 ...

  9. android仿小米日历,实现一个仿小米日历控件

    先看效果图: 效果图 根据效果,我们可以看到,要实现该控件,需要具备: 容器以及触摸事件处理 周日历布局以及选择,切换上下周处理 月日历布局以及选择,切换上下月处理 首先说说容器 对于其他使用者来说, ...

最新文章

  1. BZOJ 4009 接水果
  2. (互联网)Yahoo邮箱的改版
  3. 洛谷P2501数字序列 动态规划
  4. Linux下IO多路复用之select函数的使用
  5. Python爬虫入门教程 22-100 CSDN学院课程数据抓取
  6. 对 BatchNormalization 中 Internal Convariate Shift 的理解
  7. 转:什么是Node.js?
  8. 怎么重置计算机网络设置密码,怎么重新设置wifi密码_如何重新设置无线密码?-192路由网...
  9. 谷歌高级搜索技巧之高级语法查询指令
  10. c语言中矩形法求定积分
  11. 生物信息学习--nr/nt 数据库(总+子)构建
  12. zlib简单使用说明(转)
  13. 华为存储FusionStorage(备份②)
  14. CI获取用户真实IP地址
  15. 用于链接预测的邻域重叠感知图神经网络
  16. 此生不戒多巴胺-冲刺日志(第八天)
  17. C/C++内存泄漏及检测
  18. 对发了offer,而没有来入职的应聘者,现在再次来应聘,如果你是面试官,你会录用吗?...
  19. [计蒜客][递归]阿克曼函数
  20. 藏文驾驶考试模拟软件

热门文章

  1. 怎么在mac下运行映像dmg_Mac制作dmg镜像重新安装系统方法
  2. 初识Shell Scripts编程--最最简单的shell例子
  3. .java.smap_Java Get.getAttributesMap方法代码示例
  4. 《春风十里不如你》身体骚动的魔性,精神成长的传记
  5. Proxifier 代理方式上网
  6. griffin-lim算法及 vocoder声码器
  7. asp.net正则表达式的使用
  8. BDD - Specflow Bindings
  9. C程序设计语言读书笔记:入门C语言
  10. 自己动手编写一个在线保存百度谷歌搜索关键词历史记录的油猴脚本