android 创建者模式,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 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)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()就相当于一个工厂方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值