Android中的创建型模式总结
创建型模式共5种,单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
单例模式
定义:确保某一个类的实例只有一个,而且向其他类提供这个实例。
单例模式的使用场景:某个类的创建需要消耗大量资源,new一个对象代价太大,如访问IO和数据库等资源,或者避免多次创建该对象消耗内存过多。
懒汉模式
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉模式是当需要改单例对象时,才初始化,与之相对的是饿汉模式,静态变量instance声明时就初始化。
由于每一次调用getInstance()都需要同步,资源消耗大。
double check Lock
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronize(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
在需要时才初始化,线程安全,且对象初始化后不再进行同步锁。
第一次判断null为了不必要的同步,第二层判空是在没有其他线程进入同步块时,是否需要创建实例。但上述示例代码还是有问题,在代码instance = new Singleton()处, 代码会编译成多条指令,大致做了3件事:
1.给Singleton的实例分配内存
2.调用Singleton()构造函数,初始化成员字段
3.强instance对象指向分配的内存空间(此时instance不为null)
由于java编译器的指令执行在不影响结果的情况下是可以乱序的,所以无法保证上述2、3步骤是顺序执行的,这样当一个线程A获取单例时,先执行步骤3,步骤2还没有执行,就切换到线程B,由于此时instance已经不为空,所以线程B之间获得instance,但instance的初始化还没有完成,这样就会造成问题。
解决DCL的失效问题就是在字段instance前面加入关键字volatile,该关键字禁止指令重排序优化,确保执行到instance = new Singleton()时的指令顺序按照上述步骤1-2-3执行。
public class Singleton{
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronize(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
静态内部类单例模式
public class Singleton(){
private Singleton(){}
public static Singleton(){
return InnerSingleton.instance;
}
//静态内部类
private static class InnerSingleton{
private static final Singleton instance = new Singleton();
}
}
第一次加载Singleton时不会初始化instance,只有调用getInstance()时才初始化,因为此时需要加载静态内部类InnerSingleton。
这种方式不仅确保线程安全,也能够保证单例对象的唯一性,同时也延迟了对象实例化。
Android中的单例模式
通过context获取的各种系统服务,和LayoutInflate都是采用单例模式
WindowManager wm = (WindowManager) getSystemServie(getApplication().WINDOW_SERVICE);
//ListView中getView中使用LayoutInflate
itemView = LayoutInflate.from(context).inflate(id,null);
Builder 创建者模式
定义:讲一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
就是说某一个对象有许多字段参数需要设置,不同的设置得到不同的结果。
public class Config{
private int size;
private int number;
private String name;
public Config(int size, int number, String name){
this.size = size;
this.number = number;
this.name = name;
}
public void setSize(int size){
this.size = size;
}
public void setNumber(int number){
this.number = number;
}
public void setName(String name){
this.name = name;
}
}
如果只是极少数的变量需要设置,通过构造器还是可以接受的,如果变量个数特别多,构造器参数对应哪个变量就变得很难读懂,当只需要部分参数时,由需要重新写一个构造方法,这是很不利于程序扩展的。
public class Config{
private int size;
private int number;
private String name;
public int getSize() {
return size;
}
public int getNumber() {
return number;
}
public String getName() {
return name;
}
public static class Builder{
private int size;
private int number;
private String name;
public Builder setSize(int size){
this.size = size;
return this;
}
public Builder setNumber(int number){
this.number = number;
return this;
}
public Builder setName(String name){
this.name = name;
return this;
}
public Config build(){
Config config = new Config();
config.size = size;
config.number = number;
config.name = name;
return config;
}
}
}
当我们需要初始化Config时,通过它的静态内部类Builder进行实例化
Config.Builder builder = new Config.Builder();
Config config = builder.setName("haha")
.setNumber(2)
.setSize(3)
.build();
通过返回this实现链式调用,代码可读性强,也更好维护。
Android中的Builder模式
我们常用的提示框就采用了Builder模式
AlertDialog.Builer builder=new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon)
.setTitle("title")
.setMessage("message")
.setPositiveButton("Button1",
new DialogInterface.OnclickListener(){
public void onClick(DialogInterface dialog,int whichButton){
setTitle("click");
}
})
.create()
.show();
Notification从API11开始也采用了Builder模式
Notification.Builder builder = new Notification.Builder(this);
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentText("内容")
.setContentTitle("标题")
.setTicker("状态栏上显示...")
.setNumber(2)
.setOngoing(true);
//API11
Notification notification = builder.getNotification();
//API16
Notification notification = builder.build();
原型模式
定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
原型模式就是将一个对象进行克隆,将一个对象的内部属性完全复制,生成一个新的拷贝对象,被复制的实例对象就称为原型。当一个对象的属性过多时,重新new一个对象比较复杂和消耗资源,此时就可以用原型模式。
public class CloneMode implements Cloneable {
public String txt;
public CloneMode(String txt) {
this.txt = txt;
System.out.println("----CloneMode构造函数----");
}
public CloneMode clone() {
CloneMode cm;
try {
cm = (CloneMode) super.clone();
cm.txt = this.txt;
return cm;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
注意通过clone拷贝对象时并不会执行构造函数。还要注意的就是深拷贝和浅拷贝,浅拷贝指的是拷贝原型对象时,并没有将原型对象的字段重新构造,而是将拷贝后的副本中的字段引用指向原型对象中的字段。举个例子:A引用B,这两个对象指向同一个地址,当修改A时,B也会改变,B修改时,A也会改变。深拷贝则对于原型对象中的引用类型字段也进行拷贝,生成一个新的引用对象。将上述代码添加一个引用类型对象,深拷贝如下:
public class CloneMode implements Cloneable {
public int num;
//引用类型对象
public ArrayList<String> lists = new ArrayList<>();
public CloneMode(int num) {
this.num = num;
System.out.println("----CloneMode构造函数----");
}
public CloneMode clone() {
CloneMode cm;
try {
cm = (CloneMode) super.clone();
cm.num = this.num;
//深拷贝:引用类型对象也进行拷贝;
cm.lists = (ArrayList<String>)this.lists.clone();
//浅拷贝
//cm.lists = this.lists;
return cm;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
Android中的原型模式
Uri uri=Uri.parse("smsto:10086");
Intent shareIntent=new Intent(Intent.ACTION_SENDTO,uri);
//克隆副本
Intent intent=(Intetn)shareIntent.clone();
startActivity(intent);
工厂模式
定义:工厂模式定义一个用于创建对象的接口,让子类决定实例化哪个类。
下述代码为工厂模式的通用代码
public abstract class Product{
public abstract void method();
}
public class ConcreteProductA extends Prodect{
public void method(){
System.out.println("我是产品A!");
}
}
public class ConcreteProductB extends Prodect{
public void method(){
System.out.println("我是产品B!");
}
}
public abstract class Factory{
public abstract Product createProduct();
}
public class MyFactory extends Factory{
public Product createProduct(){
return new ConcreteProductA();
}
}
Android中的工厂模式
其实,在getSystemService方法中就是用到了工厂模式,他就是根据传入的参数决定创建哪个对象,当然了,由于返回的都是以单例模式存在的对象,因此不用new,直接把单例返回就好。
public Object getSystemService(String name) {
if (getBaseContext() == null) {
throw new IllegalStateException("System services not available to Activities before onCreate()");
}
//........
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
//.......
return super.getSystemService(name);
}
抽象工厂模式
定义:为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体类。
模式通用代码:
public abstract class AbstractProductA{
public abstract void method();
}
public abstract class AbstractProdectB{
public abstract void method();
}
public class ConcreteProductA1 extends AbstractProductA{
public void method(){
System.out.println("具体产品A1的方法!");
}
}
public class ConcreteProductA2 extends AbstractProductA{
public void method(){
System.out.println("具体产品A2的方法!");
}
}
public class ConcreteProductB1 extends AbstractProductB{
public void method(){
System.out.println("具体产品B1的方法!");
}
}
public class ConcreteProductB2 extends AbstractProductB{
public void method(){
System.out.println("具体产品B2的方法!");
}
}
public abstract class AbstractFactory{
public abstract AbstractProductA createProductA();
public abstract AbstractProductB createProductB();
}
public class ConcreteFactory1 extends AbstractFactory{
public AbstractProductA createProductA(){
return new ConcreteProductA1();
}
public AbstractProductB createProductB(){
return new ConcreteProductB1();
}
}
public class ConcreteFactory2 extends AbstractFactory{
public AbstractProductA createProductA(){
return new ConcreteProductA2();
}
public AbstractProductB createProductB(){
return new ConcreteProductB2();
}
}
Android中的抽象工厂模式
从Framework角度来看,Activity和Service都可以看做是一个具体的工厂,oncreate()和onBind()就相当于一个工厂方法。
Android中的创建型模式总结的更多相关文章
- ANDROID 中设计模式的採用--创建型模式
所谓模式就是在某一情景下解决某个问题的固定解决方式. 全部的创建型模式都是用作对象的创建或实例化的解决方式. 1 简单工厂模式 创建对象的最简单方法是使用new来创建一个对象,假设仅仅创建一种固 ...
- ANDROID 中设计模式的采用--创建型模式
所谓模式就是在某一情景下解决某个问题的固定解决方案. 所有的创建型模式都是用作对象的创建或实例化的解决方案. 1 简单工厂模式 创建对象的最简单方法是使用new来创建一个对象,如果只创建一种固定 ...
- sjms-2 创建型模式
设计模式分类 创建型模式(5种):工厂方法模式.抽象工厂模式.创建者模式.原型模式.单例模式结构型模式(7种):适配器模式.桥模式.组合模式.装饰模式.外观模式.享元模式.代理模式行为型模式(11种) ...
- [转] Android中的设计模式-备忘录模式
转自Android中的设计模式-备忘录模式 定义 备忘录设计模式的定义就是把对象的状态记录和管理委托给外界处理,用以维持自己的封闭性. 比较官方的定义 备忘录模式(Memento Pattern)又叫 ...
- 工厂方法模式——创建型模式02
1. 简单工厂模式 在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...
- 单例模式——创建型模式01
1. 名称 单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类.单例模式是一种对象创建型模式. 2. 问题 ...
- C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)
一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...
- Java设计模式之创建型模式
创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类
- 第26章 创建型模式大PK
26.1 工厂方法模式 VS 建造者模式 26.1.1 按工厂方法建造超人 (1)产品:两类超人,成年超人和未成年超人. (2)工厂:这里选择简单工厂 [编程实验]工厂方法建造超人 //创建型模式大P ...
随机推荐
- MSSQL 查询统计某状态出现的次数及累计时间
1.问题来源 最近客户需要统计某个设备,某状态,在某一个时间段内出现的次数,并计算累计出现的时间. 数据源如下: 现在如果要统计UPSCTSTA状态为D出现的次数(同一状态,连续出现的认为是一次),并 ...
- Winamp传统外观皮肤MusicRio发放
这款皮肤是我在2002年自己弄的,如果能给还在使用Winamp的朋友使用那就最好了. 下载地址:http://files.cnblogs.com/lzhdim/MusicRio.rar
- C++ 约瑟夫环
约瑟夫环: 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周 ...
- phpcms v9为联动菜单字段添加验证提醒功能 解决标题不能为空
v9系统中,如果你在模型中添加了联动菜单字段就算你在字段设置中设置了最小值为1,提交内容之前你不选择联动菜单中的值,也不会出现类似类似“标题不能为空”这样的提示下面提供解决办法打开phpcms\lib ...
- OpenStack点滴02-WSGI
OpenStack对外提供REST API,那么REST API是如何建立起来的呢? OpenStack用了一种叫WSGI(Web Service Gateway Interface)的东西,WSGI ...
- Dapper试用简例
1.选择3.5以上框架在新建项目中引用Dapper.dll. 2.在后台写代码,代码写出来后感觉以前学的都白学了. 3. using Dapper; using System; using Syste ...
- Speed-BI报表按钮链接设置
使用Speed-BI开发报表的时候,常常会需要增加一个链接按钮,点击按钮可跳转到其他报表或外部链接:那么我们可以通过新增‘仪表盘’--‘文本框’图表(如图1), <ignore_js_op> ...
- JDK TOMCAT MAVEN在myeclipse如何配置
对于没有基础的人来说,本工具务必放在D盘根目录下. 1配置环境变量, "我的电脑-->右键-->属性" 貌似是这样吧,我电脑桌面没"我的电脑"或&q ...
- 摇滚吧HTML5!有声前端交互!(一)
生命的伊始,婴儿用明亮的哭声宣告一个新生命的诞生,睁开双眼之前,一双小耳朵已经开始聆听这个世界.在如今的用户体验领域,几乎所有公司都会有视觉设计师,却鲜有注重听觉交互的公司.随着各大厂商对HTML5支 ...
- swipejs
http://swipejs.com/ http://www.scoop.it/t/javascript-for-mobile http://www.open-open.com/news/view/c ...