Android_对象的创建And建造者模式
2016-03-20 14:05
447 查看
作为一个普通的Android的上层开发,最早引以为荣的事情就是自己实现了某些效果,完成了某些自定义控件自豪,会使用当前较为流行的开源框架而自豪,比如RxJava retrofit fresco…..
这些天也是不是也反思为毛招聘Android工程师,技能点都是JAVA基本功,深入JVM 数据结构和算法,说好的招Android开发呢!
地基打不好,楼层盖不高
曾经浪费掉的光阴,只能今天来弥补,于是最近在阅读大神推荐的Effective Java.
提高代码严谨性,提高编程思想,copy 永远是copy ,使用一直是使用,思想是别人demo给不了你的!
–2016年03月20日
-静态工厂的使用
有些时候我们需要用静态工厂的方法代替构造器,
静态工厂,实例对象的时候代码更容易阅读,他们有名称
静态工厂,不必再每次调用他们的时候都创建一个新的对象
静态工厂,可以返回原返回类型的任何子类型的对象
如下代码片段
我们创建了一个Map的工厂类,于是我们在使用的时候就可以非常便捷
不管你创建何种类型的map都只需要,newInstance即可
遇到多个构造器参数的时候考虑用builder pattern
是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
我们Android程序员其实经常碰见这类代码,比如我们创建一个dialog的时候,
上面的代码我们再熟悉不过了,我们要弹出一个对话框,
对话框中有很多参数,并不是我们构造的时候都要传入的,他分为
必传参数和可选参数,比如context 是必传的,剩下的title和icon 和message都是可选的还有按钮的数量,
再比如我们用的网络请求库retrofit,可以选择设置header,gosonfactory ,等
为了更好的理解建造者模式中的各个角色,我们就仿造android的alertdialog的写法,自己做一个建造者,来调用下
首选我们写一个House类,我们来盖房子
因为我们要用建造者来实例化不同的房子,所以,
我们House的构造就必须私有化,不提供给外界调用,我们调用的时候直接是用类名,调用的建造者的build方法,所以我们需要在类的内部提供一个static的建造者
将静态的建造者提供实例化各种属性类别的方法,返回当前的建造者
最后提供一个公开的build方法返回设置好各种属性的当前的对象
我们在代码中看一下分工,
最后我们在我们的类中使用下我们的建造者,给我和你分别建立一个house,
这样就一路了然,我们的必选参数通过建造者的构造函数传入,可选参数分别调用了当前参数建造方法,在全部的参数配置完毕之后,我们调用下build()方法就返回了当前的class对象,
?为什么调用build方法没new当前对象就能返回当前的class呢
答案就是,我们build方法在内部调用了 new Instance()方法.并且把配置好全部属性的builder传入到构造中,并且把builder的属性给我们的class属性赋值,
好了我们看下结果,我的房子和我的车都是什么属性
总结 :如果类的构造器或者静态工厂中具有多个参数,设计这种类,Builder模式就是个不错的选择,特别有很多可选参数或者元素的时候,使用传统的构造器或者重载,并没有Builder模式简单让客户端代码更容易阅读和编写…
谢谢您的阅读!!
这些天也是不是也反思为毛招聘Android工程师,技能点都是JAVA基本功,深入JVM 数据结构和算法,说好的招Android开发呢!
地基打不好,楼层盖不高
曾经浪费掉的光阴,只能今天来弥补,于是最近在阅读大神推荐的Effective Java.
提高代码严谨性,提高编程思想,copy 永远是copy ,使用一直是使用,思想是别人demo给不了你的!
–2016年03月20日
-静态工厂的使用
有些时候我们需要用静态工厂的方法代替构造器,
静态工厂,实例对象的时候代码更容易阅读,他们有名称
静态工厂,不必再每次调用他们的时候都创建一个新的对象
静态工厂,可以返回原返回类型的任何子类型的对象
如下代码片段
public class HashMapFactory { private HashMapFactory() { } public static <K, V> HashMap<K, V> newInstance() { return new HashMap<K, V>(); } }
我们创建了一个Map的工厂类,于是我们在使用的时候就可以非常便捷
Map<String, String> mTestString; Map<String, Integer> mTestInteger; mTestInteger = HashMapFactory.newInstance(); mTestString = HashMapFactory.newInstance(); mTestInteger.put("INTEGER", 12); mTestInteger.put("INTEGER1", 13); mTestString.put("String", "sfsfs"); mTestString.put("String1", "哈哈哈哈");
不管你创建何种类型的map都只需要,newInstance即可
遇到多个构造器参数的时候考虑用builder pattern
是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
我们Android程序员其实经常碰见这类代码,比如我们创建一个dialog的时候,
//显示基本的AlertDialog private void showDialog(Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setIcon(R.drawable.icon); builder.setTitle( "Title" ); builder.setMessage( "Message" ); builder.setPositiveButton( "Button1" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setTitle( "点击了对话框上的Button1" ); } }); builder.setNeutralButton( "Button2" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setTitle( "点击了对话框上的Button2" ); } }); builder.setNegativeButton( "Button3" , new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { setTitle( "点击了对话框上的Button3" ); } }); builder.create().show(); // 构建AlertDialog, 并且显示 }
上面的代码我们再熟悉不过了,我们要弹出一个对话框,
对话框中有很多参数,并不是我们构造的时候都要传入的,他分为
必传参数和可选参数,比如context 是必传的,剩下的title和icon 和message都是可选的还有按钮的数量,
再比如我们用的网络请求库retrofit,可以选择设置header,gosonfactory ,等
为了更好的理解建造者模式中的各个角色,我们就仿造android的alertdialog的写法,自己做一个建造者,来调用下
首选我们写一个House类,我们来盖房子
因为我们要用建造者来实例化不同的房子,所以,
我们House的构造就必须私有化,不提供给外界调用,我们调用的时候直接是用类名,调用的建造者的build方法,所以我们需要在类的内部提供一个static的建造者
将静态的建造者提供实例化各种属性类别的方法,返回当前的建造者
最后提供一个公开的build方法返回设置好各种属性的当前的对象
我们在代码中看一下分工,
public class House { // 必选的参数 private String foundation; private String material; // 可选的参数 private String bigDoor; private String setp; private String ceilingLamp; // 内部提供一个静态的builder类,提供参数的设置,以及返回实例 public static class Builder { private String foundation; private String material; // 可选参数赋默认值 private String bigDoor = "普通大门"; private String setp = "普通台阶"; private String ceilingLamp = "普通吊灯"; /** * 构造参数中传递必选参数 * * @param foundation * @param material */ public Builder(String foundation, String material) { this.foundation = foundation; this.material = material; } // 可选参数的可选builder方法 public Builder bigDoor(String bigDoor) { this.bigDoor = bigDoor; return this; } public Builder setP(String setp) { this.setp = setp; return this; } public Builder ceilingLamp(String ceilingLamp) { this.ceilingLamp = ceilingLamp; return this; } // 上述必选和可选的参数全部配置完毕,最后开始建造房子,返回当前房子对象 public House build() { return new House(this); } } // 构造函数私有化返回当前的对象 private House(Builder builder) { this.foundation = builder.foundation; this.material = builder.material; this.bigDoor = builder.bigDoor; this.setp = builder.setp; this.ceilingLamp = builder.ceilingLamp; } }
最后我们在我们的类中使用下我们的建造者,给我和你分别建立一个house,
private static void testBuilderPattern() { // 使用的时候因为我们的类已经私有化构造函数,所以只能通过New 出来当前类的建造者来配置,和builder Car mCar = new Car.Builder("高级轮胎", "进口引擎", "24k金方向盘") .graffiti("全裸涂鸦") .sticker("豪放贴纸") .build(); // 不传递可选参数 Car otherCar = new Car.Builder("普通轮胎", "大众引擎", "拖拉机改造方向盘") .build(); House mHouse = new House.Builder("350平米地基", "全进口材料") .bigDoor("镀金双开大门") .ceilingLamp("南非镶钻吊灯") .setP("进口大理石台阶") .build(); House otherHouse = new House.Builder("10平米厕所旁地基", "国内高含量超标材料") .bigDoor("破大门") .ceilingLamp("普通灯泡") .setP("蓝翔挖掘的红砖台阶") .build(); }
这样就一路了然,我们的必选参数通过建造者的构造函数传入,可选参数分别调用了当前参数建造方法,在全部的参数配置完毕之后,我们调用下build()方法就返回了当前的class对象,
?为什么调用build方法没new当前对象就能返回当前的class呢
答案就是,我们build方法在内部调用了 new Instance()方法.并且把配置好全部属性的builder传入到构造中,并且把builder的属性给我们的class属性赋值,
// 配置完毕执行build方法返回当前具备属性的对象 public Car build() { // 这调用了下面的私有构造方法,接受当前配置好属性的builder return new Car(this); } // 这里传入了配置好属性的builder给我们的class属性赋值, private Car(Builder builder) { this.engine = builder.engine; this.graffiti = builder.graffiti; this.sticker = builder.sticker; this.tires = builder.tires; this.wheel = builder.wheel; }
好了我们看下结果,我的房子和我的车都是什么属性
总结 :如果类的构造器或者静态工厂中具有多个参数,设计这种类,Builder模式就是个不错的选择,特别有很多可选参数或者元素的时候,使用传统的构造器或者重载,并没有Builder模式简单让客户端代码更容易阅读和编写…
谢谢您的阅读!!
相关文章推荐
- Android 自定义View触摸相关工具类详解
- 闭关日记 Day07
- Android事件传递机制
- 【 Android】自定义的AlertDialog中的EditText无法调用输入法问题解决
- From Android ART (binary-only) to DEX? Yes, we can!™ (kinda)
- AndroidManifest.xml文件解析
- 如何实现android和服务器长连接呢?推送消息的原理
- Android实现推送方式解决方案
- android 进程和线程
- Android SDK下载方法
- android activity全屏的另一种写法
- 手机的音频口通信
- android 中 checkBox 的使用
- Dagger 笔记 一
- android SDK 更新问题解决
- 总结Android Studio导入项目的几种方法
- Android屏幕适配方案
- Android 定时器
- Android Volley框架的使用(5)
- [置顶] Android开发之ListView详解 以及简单的listView优化