Android中的设计模式之构建者模式
参考
- 《设计模式:可复用面向对象软件的基础 》3.2 Builder 生成器--对象创建型模式
- 《Android源码设计模式解析与实战》第3章 Builder模式
意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性
- 相同的方法,不同的执行顺序,产生不同的事件结果时。
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。
- 当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。
结构
- Product
- 表示被构造的复杂对象
- 包含定义组成部件的类,包括将这些部件装配成最终产品的接口
- Builder 抽象Builder类,为创建一个Product对象的各个部件指定抽象接口,规范产品的组建,一般是由子类实现具体的组建过程。
- ConcreteBuilder 具体的Builder实现类
- Director 使用Builder接口进行构造
协作
- 客户创建Director对象,并用它所想要的Builder对象进行配置。
- 一旦产品部件被生成,Builder就会通知生成器
- 生成器处理Builder的请求,并将部件添加到该产品中。
- 客户从生成器中检索产品
例子1:RTF阅读器
一个RTF(Rich Text Format)阅读器应能将RTF转换为多种正文格式。该阅读器可以将RTF文档转换为普通ASCII文本或者一个能以交互方式编辑的正文窗口组件。但问题是在于可能转换的数目是无限的。因此要能够很容易地实现新的转换的增加,同时却不改变RTF阅读器。
一种解决办法就是运用Builder模式,用一个可以将RTF转换成另一种正文表示的TextConverter对象配置这个RTFReader类。当RTFReader对RTF文档进行语法分析时,它使用TextConverter去做转换。
每种转换器类将创建和装配一个复杂对象的机制隐含在抽象接口的后面。转换器独立于阅读器,阅读器负责对一个RTF文档进行语法分析。
每一个转换器类可以作为生成器builder,而阅读器作为director。Builder模式将分析文本格式的算法与描述怎样创建和表示一个转换后格式的算法分离开来。这使得我们可以重用RTFReader的语法分析算法,分局RTF文档创建不同的正文表示--仅需使用不同的TextConverter的子类配置该RTFReader即可。
例子2:组装电脑
我想随意组装一台电脑,比如一台Inter主板,Retina显示屏,MacOs的电脑
计算机的组装过程较为负复杂,并且组装顺序是不固定的,所以我们可以用Buider模式。
示例代码:
// 电脑基础抽象类 public abstract class Computer { protected String mBoard; protected String mDisplay; protected String mOS; protected Computer(){} //设置主板 public void setBoard(String board){ this.mBoard=board; } //设置显示器 public void setDisplay(String display) { mDisplay=display; } //设置操作系统 public abstract void setOS(); @Override public String toString() { StringBuilder stringBuilder=new StringBuilder(); if (mBoard!=null) { stringBuilder.append("myBoard is:"+mBoard); } if (mDisplay!=null) { stringBuilder.append("\nmDisplay is:"+mDisplay); } if (mOS!=null) { stringBuilder.append("\nmyOS is:"+mOS); } return stringBuilder.toString(); } } //Macbook电脑,实现了setOs public class MacBook extends Computer{ @Override public void setOS() { mOS="Mac _S X 10.10"; } } // 抽象Builder public abstract class Builder{ abstract Buider buildBoard(String board); abstract Buider buildDisplay(String display); abstract Buider buildOS(); abstract Computer create(); } //具体的一个Builder类 public class MacBookBuilder extends Buider { private Computer mComputer=new MacBook(); @Override public Buider buildBoard(String board) { mComputer.setBoard(board); return this; } @Override public Buider buildDisplay(String display) { mComputer.setDisplay(display); return this; } @Override public Buider buildOS() { mComputer.setOS(); return this; } @Override public Computer create() { return mComputer; } } // Director类,负责构造Computer public class Director{ Builder mBuilder = null; public Director(Builder builder){ mBuilder = builder; } public void construct(String board,String display){ mBuilder.buildBoard(board); mBuilder.buildDisplay(display); mBuilder.buildOs(); } } //使用 public static void main(String[] args) { Builder macBookBuilder=new MacBookBuilder(); Director director = new Director(macBookBuilder); // 使用Director构造 director.construct(英特尔主板,retina); System.out.println(macBookBuilder.create().toString()) // 通常我们都会通过Builder的链式调用省略Director类,比如如下所示 System.out.println(macBookBuilder.buildBoard("英特尔主板") .buildDisplay("retina") .buildOS() .create().toString()); }
结果:
myBoard is:英特尔主板
mDisplay is:retina
myOS is:Mac _S X 10.10
效果
- 它使你可以改变一个产品的内部表示
- 它将构造代码和表示代码分开
- 它使你可对构造过程进行更精细的控制
- 《Effective java》书中建议如果构造一个对象复杂,需要传入很多参数,不妨采用Builder模式,有效减少了传参失误。
- 当然缺点是增加了代码量。
例子3 Android中的AlertDialog.Builder
// todo 后更
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
阅读手札:《Android开发艺术探索》(一)
《Android开发艺术探索》这本书在Android开发界内可谓口碑极佳,他的作者任玉刚在百度担任Android资深开发工程师。我的一个初中朋友现在深圳百度做Android研发,上周去深圳找他玩的时候碰巧在他电脑桌上看到了这本书,他谈到这本书内容多、有深度且知识点非常系统值得反复阅读。的确,《Android开发艺术探索》这本书去年看过一遍就感觉非常不错,下面将一些书中的重要知识点归纳并分享出来,这是本系列的第一篇,主要介绍的是 Activity的生命周期和启动模式 评语:本节也从原理解释了为什么每次继承Activity后,需要重写onCreate(Bundle savedInstanceState),方法里面的savedInstanceState虽然用的少,但是很重要!谷歌Android团队的这种设计策略可以从侧面反映其思虑之远、逻辑健壮性以及降低特殊情况的损耗。正文有详细解释 下面是我们熟悉的Activity的生命周期流程图: Activity的生命周期 下面就生命周期逐个分析: (1)onCreate:create 表示Activity正在被创建,这是Activity生命周期的第一...
- 下一篇
界面无小事(七):使用代码动态增删布局
界面无小事(一):RecyclerView+CardView了解一下界面无小事(二):让RecyclerView展示更多不同视图界面无小事(三):用RecyclerView + Toolbar做个文件选择器界面无小事(四):来写个滚动选择器吧!界面无小事(五):自定义TextView界面无小事(六):来做个好看得侧拉菜单!github传送门 目录 效果图 前言 布局文件 实现 最后 效果图 不多废话, 先上图, 有兴趣再看下去: 效果图 前言 这篇是之前的一篇旧文改的, 也是想将这篇放入自己的界面无小事专题, 所以当成新篇章来写, 绝对不是为了什么日更之类的事情哦(手动滑稽)~. 布局文件 先来看看布局文件, 不是很复杂, 但是涉及到之后java部分的代码, 所以必须都贴出来. 不过你可以看下预览图就好: 布局预览图 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题