Android中建造者(builder)模式
来源:互联网 发布:2014matlab中对角矩阵 编辑:程序博客网 时间:2024/05/22 15:02
设计模式系列:
0.Android开发常用设计模式;
1. Android中单例模式;
2. Android中建造者(builder)模式;
3. Android中观察者模式;
4. Android中原型模式;
5. Android中策略模式;
6.Android中工厂模式;
7.Android中代理模式;
8.Android中装饰者模式;
9. Android中适配器模式;
一、常见需求场景
三毛:“小白,你平常项目里使用建造者模式多不多”
小白:建造者模式?毛毛哥,能说人话嘛
三毛:“就是builder模式,链式调用那种”
小白:思~索~片~刻~~,奥,你说的是下面这种吗,这面这样的链式形式我还没写过呢,只使用过,感觉挺清晰好看的
new AlertDialog.Builder(this) .setTitle("对话框") .setMessage("测试") .setIcon(R.mipmap.ic_launcher) .create() .show(); Glide.with() .load() .into(); Picasso.with() .load() .into();
二、基本解决方法
三毛:“不是吧,我的白,那你开发中例如遇到一个商品或用户注册有很多属性需要设置,你是怎么写的捏”
小白:喔,这个简单,根据情况分2种写法,第一种是属性不多的时候使用构造方法,如果属性很多,那就用set和get,像下面酱紫:
//第一种(属性不是很多的时候) class 商品{ private String 属性1;//必传的参数 private String 属性2;//必传的参数 private String 属性3;//选传的参数 public 商品(属性1) { this.(属性1) } public 商品(属性1,属性2,属性3) { this.(属性1,属性2) } public 商品(属性1,属性2,属性3) { this.属性1 = 属性1; this.属性2 = 属性2; this.属性3 = 属性3; } }//第二种(属性很多的时候)class 商品{ private String x1; private String x2; ......... public void setX1(String x1){ this.x1=x1; } public void setX2(String x2){ this.x2=x2; } public String getX1(){ return x1; public String getX2(){ return x2; } ......}
三、基本解决方法存在的问题
三毛:“小白,你上面使用构造函数那一种写法,当使用者,用或看你的构造方法时,第一个,第二个,第三个参数很难知道要传什么或传的是什么,你要去查看才知道,同时,拓展和维护也会很迷糊的啵”
小白:我吸口奶压压惊,老哥你继续
三毛:“属性多的时候,使用set,get第二种方式,是解决了上面的问题,但是会让调用set方法的对象重复了20次或更多,同时也属于不连续的情况,该类的其他属性在被创建之后被修改,给程序带来了一些不安全性,像下面”
//属性越多,调用者(商品)重复越多商品.setX1("");商品.setX2("");商品.setX3("");.....//修改已经设置好了的某个属性商品.setX1("修改后的属性");
小白:呐,毛毛哥,那应该怎么搞会好一点捏
四、变种Builder设计模式写法
建造者模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
三毛:”你可以使用变种建造者(builder)模式试试,根据自己情况来”
小白:等下,三毛哥,刚刚你说”变种”是啥子情况
三毛:“建造者(builder)模式起初是有自己的标准的,后面随着时间推移,在这基础上Android演变出了变种建造者(builder)模式,不过Android中一般使用变种buildr模式就够用了,至于经典builder模式,类有点多,怕等下把你搞乱了,先说完变种Builder模式,后面在说经典builder模式”
小白:那毛毛哥,你先告诉我变种builder模式怎么写
三毛:“那就用前面那个例子吧,变种builder模式很简单的,主要是在类里建立一个静态内部类,像下面这样”
public class A { private final String mX1; private int mX2; private A(Builder builder) { mX1 = builder.mX1; mX2 = builder.mX2; } public static final class Builder { private final String mX1; private int mX2; public Builder() { } public Builder setX1(String val) { mX1 = val; return this; } public Builder setX2(int val) { mX2 = val; return this; } public A build() { return new A(this); } }}//使用new A.Builder() .setX1() .setX2() .build();
五、变种Builder模式和普通写法的区别
1、链式调用,结构清晰;
2、属性设置后,不会被修改,安全性较高;(也是变种builder基本不使用单例理由之一)
3、因为变种builder模式主要是以静态内部类实现,需求改变后,只需要替换新的静态内部类,原来的静态内部类可以原封不动,拓展性和维护较好
========================经典Builder模式分割线=====================
小白:毛毛哥,快说,快说,啥是经典Builder模式
三毛:“哇,小白你辣么可爱,咳咳咳!,下面说正事”
三毛:“有这样一个例子,‘有2个商品,它们都要经历生产-包装-标价过程‘,我的白,你用正常写法模拟下”
小白:毛毛哥,这还不简单,下面是我对上面的案例的模拟过程
//来个公用的接口public interface IGoods { void produc();//生产商品 void packageGoods();//包装商品 void price();//给商品标价}//商品A类public class GoodsA implements IGoods{ @Override public void produc() { //生产商品A... System.out.println("生产商品A……"); } @Override public void packageGoods() { //包装商品A... System.out.println("包装商品A……"); } @Override public void price() { //给商品A标价... System.out.println("给商品A标价……"); } public void excuteOrder(){ produc(); packageGoods(); price(); }}//商品B和上面一模一样,就不贴重复代码了...//使用new GoodsA().excuteOrder();new GoodsB().excuteOrder();
小白:这里可以优化一下下,优化后代码
//把接口换成抽象类,把组装商品的过程放到这public abstract class IGoods { abstract void produc();//生产商品 abstract void packageGoods();//包装商品 abstract void price();//给商品标价 //执行一条龙服务 public void excuteOrder(){ this.produc();//生产 this.packageGoods();//打包 this.price();//标价 }}//商品A类public class GoodsA extends IGoods{ @Override public void produc() { //生产商品A... System.out.println("生产商品A……"); } @Override public void packageGoods() { //包装商品A... System.out.println("包装商品A……"); } @Override public void price() { //给商品A标价... System.out.println("给商品A标价……"); }}//商品B和上面一模一样,就不贴重复代码了...//使用new GoodsA().excuteOrder();new GoodsB().excuteOrder();
三毛:“可以哇,我的白,你上面其实就是经典Builder设计模式了,只不过不是完整的”
小白:啊,我不知不觉就用了经典Builder设计模式了?毛毛哥,那完整版是啥样子的,说来看看呗。
三毛:”不管怎样,首先你都要知道经典Builder模式有4个模块,如下。 “
//经典Builder 4个模块Product:被构造的复杂对象。Builder:抽象接口。BuilderImpl:抽象接口的具体实现。Director:接口的构造者和使用者。
三毛:”其实经典Builder模式只是比变种Builder模式复杂一点,下面我用经典Builder模式的形式完成你上面的案例,你可以和你的代码对比对比,有啥不同“
//实体类,也可以是其他业务类,看情况嘛public class GoodsBean { private String producProcess; private String packageProcess; private String priceProcess; private String goodsName; public String getGoodsName() { return goodsName; } public void setGoodsName(String goodsName) { this.goodsName = goodsName; } public String getProducProcess() { return producProcess; } public void setProducProcess(String producProcess) { this.producProcess = producProcess; } public String getPackageProcess() { return packageProcess; } public void setPackageProcess(String packageProcess) { this.packageProcess = packageProcess; } public String getPriceProcess() { return priceProcess; } public void setPriceProcess(String priceProcess) { this.priceProcess = priceProcess; }
//和你上面(没优化时)一样,只不过加了个获取商品类型的方法public interface IGoods { void produc();//生产商品 void packageGoods();//包装商品 void price();//给商品标价 GoodsBean getGoodsType();//得到商品类型}
//还是和你上面一样,没啥子区别public class GoodsABuilder implements IGoods{ private GoodsBean goodsBean; public GoodsABuilder() { this.goodsBean = new GoodsBean(); } @Override public void produc() { //生产商品A... goodsBean.setProducProcess("生产商品A……"); } @Override public void packageGoods() { //包装商品A... goodsBean.setPackageProcess("包装商品A……"); } @Override public void price() { //给商品A标价... goodsBean.setPriceProcess("给商品A标价……"); } @Override public GoodsBean getGoodsType() { goodsBean.setGoodsName("得到商品A……"); return goodsBean; }//商品B一摸一样,就不贴重复代码了...}
//这是商品的组装类了public class Goods { private IGoods mIGoods; public Goods(IGoods mIGoods) { this.mIGoods = mIGoods; } //执行一条龙服务 public void excuteOrder(){ mIGoods.produc();//生产 mIGoods.packageGoods();//打包 mIGoods.price();//标价 }}
//使用 GoodsABuilder goodsABuilder = new GoodsABuilder();//得到商品构建对象 new Goods(goodsABuilder).excuteOrder();//组装商品 GoodsBean goodsType = goodsABuilder.getGoodsType();//最终得到某某商品 System.out.println(goodsType.getGoodsName()); //商品B和上面一摸一样,也不贴重复代码了 ...
小白:毛毛哥,你上面的代码对应经典Builder模式4个模块是下面这样的吗
Product:被构造的复杂对象。 ---->GoodsBeanBuilder:抽象接口。 ---->IGoodsBuilderImpl:抽象接口的具体实现。 ---->GoodsABuilder、GoodsBBuilderDirector:接口的构造者和使用者。 ---->Goods
三毛:”嗯,不错哇,我的白,理解那么快”
小白:嘿嘿,因为和我的想法一样嘛,虽然类有点多,不过每个模块职责挺清晰的,要是新加很多新商品,只需要添加对应的商品类(GoodsABuilder、GoodsBBuilder、GoodsCBuilder…)就好了,厉害了,我的哥。
总结:
“经典Builder模式使得同样的构建过程可以创建不同的表示。像这里的商品都经历生产-包装-标价过程,但是每个商品都不同。”
特点:
1)封装性:使用建造者模式可以是客户端不必知道产品内部组成的细节。
2)建造者独立,容易扩展:goodsABuilder和goodsBBuilder是相互独立的,对系统扩展非常有利。
3)便于控制细节风险:由于具体的建造者是独立的,因此可以对建造者过程逐步细化,而不对其他的模块产生任何影响。
- Android中建造者(builder)模式
- Android 建造者(Builder)模式
- 建造者(Builder)模式
- 建造者(Builder)模式
- 建造者模式(Builder)
- 建造者模式(Builder)
- 建造者(Builder)模式
- 建造者模式(Builder)
- 建造者模式(Builder)
- 建造者(Builder)模式
- 建造者模式(Builder)
- 建造者模式(Builder)
- 建造者模式(Builder)
- Builder(建造者)模式
- 建造者(Builder)模式
- 建造者模式(builder)
- 建造者模式(Builder)
- 建造者模式(Builder)
- Genymotion配置和安装
- IP协议的主要特点与格式
- 20170929在stm32f103zet6 RTT上扩展外部SRAM
- iOS开发 ☞ 关于带系统导航栏坐标的问题
- 20行代码能干嘛?
- Android中建造者(builder)模式
- Redis中RDB持久化
- Android SurfaceFligner Vsync信号 Jni/C++调用实现
- OplogThread: Last entry no longer in oplog cannot recover!
- 堆排序算法的实现(HeapSort)
- 转-C++快速入门
- scrapy爬虫的暂停与重启
- 面向对象状态机框架
- 如何做到phpmyadmin中最大限制:2,048KB 解决办法