安卓中的单例模式和工厂模式

本文介绍了单例模式和工厂模式的基本概念、应用场景及优缺点。详细解释了单例模式的三种实现方式:懒汉式、加同步锁及内部类实现;工厂模式则通过标准工厂模式和简单工厂模式进行了阐述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式

简单的来说,单例模式就是提供一个实例,并且提供一个全局的访问点。

适用场景:1.应用中某个实例对象需要频繁的被访问。

2.应用中每次启动只会存在一个实例。

优点:内存中只有一个实例,减少了内存的开销,避免对资源的多重占用。

常用的三种方式:

(1)懒汉式

public class  A{

/* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */ 

private static A instance = null;

 /* 私有构造方法,防止被实例化 */  

private A(){

         }

 /* 1:懒汉式,静态工程方法,创建实例 */  

public static A getInstance(){

if(instance == null){

instance = new A()

        }

return instance;

    }

}

调用:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Singleton.getInstance().method();  

优点:延迟加载(需要时在加载)

缺点:线程不安全,在多线程中很容易出现不同步的情况

(2)加同步锁

既然线程不安全,那就加上同步锁,一种加法如下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /*2.懒汉式变种,解决线程安全问题**/  
  2.  public static synchronized Singleton getInstance() {  
  3.      if (instance == null) {  
  4.          instance = new Singleton();  
  5.      }  
  6.      return instance;  
  7.  }  

(3)内部类的实现

内部类是一种好的实现方式,可以推荐使用一下:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class SingletonInner {  
  2.   
  3.     /** 
  4.      * 内部类实现单例模式 
  5.      * 延迟加载,减少内存开销 
  6.      *  
  7.      * @author xuzhaohu 
  8.      *  
  9.      */  
  10.     private static class SingletonHolder {  
  11.         private static SingletonInner instance = new SingletonInner();  
  12.     }  
  13.   
  14.     /** 
  15.      * 私有的构造函数 
  16.      */  
  17.     private SingletonInner() {  
  18.   
  19.     }  
  20.   
  21.     public static SingletonInner getInstance() {  
  22.         return SingletonHolder.instance;  
  23.     }  
  24.   
  25.     protected void method() {  
  26.         System.out.println("SingletonInner");  
  27.     }  
  28. }  

调用:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. SingletonInner.getInstance().method();  
优点:延迟加载,线程安全(java中class加载时互斥的),也减少了内存消耗

工厂模式

简单来说就是给外部批量提供相同或者不同的产品,而外部不需要关心工厂是如何创建一个复杂产品的过程。所以工厂模式降低模块间的耦合,同时提高扩展性。

(1)标准工厂模式

   首先先介绍一下标准的工厂方法模式,不带任何的变种.以工厂生产不同操作系统的手机为例.

       建立一个产品接口,提供一个获取系统信息的方法.

[java]  view plain  copy
  1. /** 
  2.  * Created by jesse on 15-8-17. 
  3.  */  
  4. public interface IPhone {  
  5.     public void getOS();  
  6. }  
       再根据IPhone接口实现Android,IOS,Blackberry三种手机.

[java]  view plain  copy
  1. public class AndroidPhone implements IPhone {  
  2.     private final String TAG = AndroidPhone.class.getSimpleName();  
  3.     @Override  
  4.     public void getOS() {  
  5.         Log.i(TAG, "im Android");  
  6.     }  
  7. }  
  8. public class IosPhone implements IPhone {  
  9.     private final String TAG = IosPhone.class.getSimpleName();  
  10.     @Override  
  11.     public void getOS() {  
  12.         Log.i(TAG, "im IOS");  
  13.     }  
  14. }  
  15. public class BlackBerryPhone implements IPhone {  
  16.     private final String TAG = BlackBerryPhone.class.getSimpleName();  
  17.     @Override  
  18.     public void getOS() {  
  19.         Log.i(TAG, "im BlackBerry");  
  20.     }  
  21. }  

       标准的工厂方法模式都需要有抽象的工厂接口或者基类.

[java]  view plain  copy
  1. public abstract class IGenerator {  
  2.     public abstract IPhone generatePhone(String flag) throws Exception;  
  3. }  

       通过基类或者接口来实现真实的工厂类,这里需要注意跟简单工厂模式的不同,标准的工厂方法模式里面一个工厂只生产一个产品,所以这里要根据产品的种类划分出来三个工厂,分别生产三种不同的产品.这种设计思想非常契合单一职责原则.

[java]  view plain  copy
  1. public class AndroidGenerator extends IGenerator {  
  2.     @Override  
  3.     public IPhone generatePhone() {  
  4.         return new AndroidPhone();  
  5.     }  
  6. }  
  7. public class IOSGenerator extends IGenerator {  
  8.     @Override  
  9.     public IPhone generatePhone() {  
  10.         return new IosPhone();  
  11.     }  
  12. }  
  13. public class BlackberryGenerator extends IGenerator {  
  14.     @Override  
  15.     public IPhone generatePhone() {  
  16.         return new BlackBerryPhone();  
  17.     }  
  18. }  
       在客户端从工厂中获得产品并使用的过程中都是通过接口进行访问的,在创建产品的阶段有效得降低了使用者和产品之间的耦合度.

[java]  view plain  copy
  1. IPhone android, ios, bb;  
  2. IGenerator androidGenerator, iosGenerator, bbGenerator;  
  3. androidGenerator = new AndroidGenerator();  
  4. iosGenerator = new IOSGenerator();  
  5. bbGenerator = new BlackberryGenerator();  
  6. android = androidGenerator.generatePhone();  
  7. ios = iosGenerator.generatePhone();  
  8. bb = bbGenerator.generatePhone();  
  9. android.getOS();  
  10. ios.getOS();  
  11. bb.getOS();  
(2)简单工厂模式,也称为静态工厂方法模式。它不能通过继承进行扩展,如果有新增的产品,就只能在静态方法里面做修改。

       因为这是静态工厂方法模式,所以工厂类就没有接口或者虚基类来提供抽象.通过不同的Flag来初始化不同的产品.

[java]  view plain  copy
  1. public class PhoneGenerator{  
  2.     public final static String GENERATE_IOS = "generate_ios";  
  3.     public final static String GENERATE_ANDROID = "generate_android";  
  4.     public final static String GENERATE_BLACKBERRY = "generate_blackberry";  
  5.   
  6.     public static IPhone generatePhone(String flag) throws Exception {  
  7.         IPhone iPhone = null;  
  8.         switch (flag){  
  9.             case GENERATE_ANDROID:  
  10.                 iPhone =  new AndroidPhone();  
  11.                 break;  
  12.             case GENERATE_IOS:  
  13.                 iPhone =  new IosPhone();  
  14.                 break;  
  15.             case GENERATE_BLACKBERRY:  
  16.                 iPhone =  new BlackBerryPhone();  
  17.                 break;  
  18.             default:  
  19.                 throw new Exception("UNDEFINED FLAG");  
  20.         }  
  21.         return iPhone;  
  22.     }  
  23. }  
       对外部来说要使用工厂只需要把目标产品类传过去就行了.运行结果跟1)中的是一样的.

[java]  view plain  copy
  1. IPhone android, ios, bb;  
  2. android = PhoneGenerator.generatePhone(PhoneGenerator.GENERATE_ANDROID);  
  3. ios = PhoneGenerator.generatePhone(PhoneGenerator.GENERATE_IOS);  
  4. bb = PhoneGenerator.generatePhone(PhoneGenerator.GENERATE_BLACKBERRY);  
  5. android.getOS();  
  6. ios.getOS();  
  7. bb.getOS(); 









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值