结合代码!Android常见的设计模式(持续更新)

这里借鉴了一个篇写非常不错的博客:https://www.cnblogs.com/android-blogs/p/5530239.html

 

什么是设计模式?

设计模式(Design pattern)是一套被反复使用的代码设计经验的总结。使用设计模式的目的是为了可重用代码、让代码更容易被他人理解。设计模式是是软件工程的基石脉络,如大厦的结构一样。

 

单例模式

在这之前先要了解单例模式,什么是单例模式?

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式的优点:

  • 对于那些比较耗内存的类,只实例化一次可以大大提高性能,尤其是在移动开发中。
  • 保持程序运行的时候该中始终只有一个实例存在内存中

单例有很多种实现方式,这里列出其中1种。

public class Single {
    private static volatile Single instance = null;    //单例使用volatile修饰

    private Single(){    //构造函数必须私有化,防止外部可以调用构造函数进行实例化
    }
 
    public static Single getInstance() {    //必须定义一个静态函数获得该单例
        if (instance == null) {
            synchronized (Single.class) {    //使用synchronized 进行同步处理,并且双重判断是否为null
                if (instance == null) {
                    instance = new Single();
                }
            }
        }
        return instance;
    }
}

要保证单例,需要做一下几步

  • 必须防止外部可以调用构造函数进行实例化,因此构造函数必须私有化。
  • 必须定义一个静态函数获得该单例
  • 单例使用volatile修饰
  • 使用synchronized 进行同步处理,并且双重判断是否为null,我们看到synchronized (Single.class)里面又进行了是否为null的判断,这是因为一个线程进入了该代码,如果另一个线程在等待,这时候前一个线程创建了一个实例出来完毕后,另一个线程获得锁进入该同步代码,实例已经存在,没必要再次创建,因此这个判断是否是null还是必须的。

 

单例的并发测试,可以使用CountDownLatch,使用await()等待锁释放,使用countDown()释放锁从而达到并发的效果。如下:

public static void main(String[] args) {
	final CountDownLatch latch = new CountDownLatch(1);    //CountDownLatch传入1,待完成线程减1
	int threadCount = 1000;
	for (int i = 0; i < threadCount; i++) {
		new Thread() {
			@Override
			public void run() {
				try {
					latch.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Single.getInstance().hashCode());
			}
		}.start();
	}
	latch.countDown();
}

看看打印出来的hashCode会不会出现不一样即可,理论上是全部都一样的。

不了解CountDownLatch可以先看:https://blog.csdn.net/Nobody_else_/article/details/97623701

 

而在Android中,很多地方用到了单例。

比如Android-Universal-Image-Loader中的单例

private volatile static ImageLoader instance;    //单例使用volatile修饰
/** Returns singleton class instance */
public static ImageLoader getInstance() {    //必须定义一个静态函数获得该单例
	if (instance == null) {
		synchronized (ImageLoader.class) {    //使用synchronized 进行同步处理,并且双重判断是否为null
			if (instance == null) {
				instance = new ImageLoader();
			}
		}
	}
	return instance;
}

EventBus中的单例

private static volatile EventBus defaultInstance;    //单例使用volatile修饰
public static EventBus getDefault() {    //必须定义一个静态函数获得该单例
	if (defaultInstance == null) {
		synchronized (EventBus.class) {    //使用synchronized 进行同步处理,并且双重判断是否为null
			if (defaultInstance == null) {
				defaultInstance = new EventBus();
			}
		}
	}
	return defaultInstance;
}

上面的单例都是比较规规矩矩的,当然实际上有很多单例都是变了一个样子,单本质还是单例。

如InputMethodManager 中的单例

static InputMethodManager sInstance;
public static InputMethodManager getInstance() {
	synchronized (InputMethodManager.class) {
		if (sInstance == null) {
			IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
			IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
			sInstance = new InputMethodManager(service, Looper.getMainLooper());
		}
		return sInstance;
	}
}

AccessibilityManager 中的单例,看代码这么长,其实就是进行了一些判断,还是一个单例

private static AccessibilityManager sInstance;
public static AccessibilityManager getInstance(Context context) {
	synchronized (sInstanceSync) {
		if (sInstance == null) {
			final int userId;
			if (Binder.getCallingUid() == Process.SYSTEM_UID
					|| context.checkCallingOrSelfPermission(
							Manifest.permission.INTERACT_ACROSS_USERS)
									== PackageManager.PERMISSION_GRANTED
					|| context.checkCallingOrSelfPermission(
							Manifest.permission.INTERACT_ACROSS_USERS_FULL)
									== PackageManager.PERMISSION_GRANTED) {
				userId = UserHandle.USER_CURRENT;
			} else {
				userId = UserHandle.myUserId();
			}
			IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
			IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
			sInstance = new AccessibilityManager(context, service, userId);
		}
	}
	return sInstance;
}

当然单例还有很多种写法,比如饿汉式,最后,我们应用一下单例模式。典型的一个应用就是管理我们的Activity,下面这个可以作为一个工具类。

public class ActivityManager {

	private static volatile ActivityManager instance;
	private Stack<Activity> mActivityStack = new Stack<Activity>();
	
	private ActivityManager(){
		
	}
	
	public static ActivityManager getInstance(){
		if (instance == null) {
		synchronized (ActivityManager.class) {
			if (instance == null) {
				instance = new ActivityManager();
			}
		}
		return instance;
	}
	
	public void addActicity(Activity act){
		mActivityStack.push(act);
	}
	
	public void removeActivity(Activity act){
		mActivityStack.remove(act);
	}
	
	public void killMyProcess(){
		int nCount = mActivityStack.size();
		for (int i = nCount - 1; i >= 0; i--) {
        	Activity activity = mActivityStack.get(i);
        	activity.finish();
            }
		
		mActivityStack.clear();
		android.os.Process.killProcess(android.os.Process.myPid());
	}
}

 

饿汉模式和懒汉模式

懒汉模式

在类加载的时候不被初始化。

public class Single {
    //在对象加载的时候只进行一次
    private static Single single = new Single();

    private Single() {}

    public static Single getSingle(){
        return single;
    }

}

饿汉模式

在类加载时就完成了初始化,但是加载比较慢,获取对象比较快。

public class LazySingle {

    private static LazySingle lazySingle = null;

    private LazySingle(){

    }
    //需要的时候才初始化
    public synchronized static LazySingle  getInstance(){   //线程不安全,加锁
        if (lazySingle == null) {
            lazySingle = new LazySingle();
        }
        return lazySingle;
    }

饿汉模式是线程安全的,在类创建好一个静态对象提供给系统使用,懒汉模式在创建对象时不加上synchronized,会导致对象的访问不是线程安全的。

 

未完待续...

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 云养老app是一款综合性的老年人服务应用,主要通过手机应用程序来为前来下载使用app的用户提供有关老年人生活、医疗、养老等一系列方便、实用的信息,包括营养保健、医疗养生、便民服务、亲情关怀等等。今天我们主要讨论的是和这个云养老app紧密相连的android代码。 首先,使用云养老app的用户可以通过android代码中的用户登录实现自己的账户管理,包括账户的开卡、密码的更改等等,这个“我的”功能是基于用户登录实现的。同时,在这个页面中,界面设计也非常人性化,非常适合老年人这一用户群的使用习惯。 其次,云养老app中的全部业务逻辑都是使用java语言编写的,通过android studio IDE来实现。在逻辑层的开发中,我们采取了单例模式、观察者模式设计模式,通过封装各个模块,以此来保证代码的高内聚性、低耦合性。这不仅有助于代码的维护和升级,更重要的是可以提高代码的可靠性和稳定性。 最后,在代码的整体架构上,由于云养老app面向老年人这一特定用户群体,我们遵循的是“MVC”设计模式,将前端的UI逻辑和后端的业务逻辑进行了分离,使得不同的开发人员可以进行独立开发和测试。这样的框架设计不仅保证了代码的稳定性和灵活性,而且在后续的维护和升级中也有很大的便利性,为整个应用的可持续性发展提供了保障。 综上所述,android云养老app代码是一份高效、健壮、易维护的代码,它的开发和实现充分体现了云养老app的优秀特性和服务意识,使得我们的老年人用户可以更加方便地享受、使用智能手机为生活服务的便利。 ### 回答2: Android云养老APP代码主要涵盖了用户登录、信息展示、社交互动、健康监测等功能。 首先,登录功能部分,代码通常包括用户注册、登录验证和密码找回等操作,通过用户输入手机号、验证码等信息完成验证。模块需连接云服务器,将用户数据存储在数据库中,保障安全性。 信息展示功能包括健康资讯、养老政策、活动推荐等模块,通过与云服务器交互,请求数据展示在APP中。代码中可使用网络请求库,如Volley或OkHttp,在请求URL的基础上获取JSON或XML格式数据,解析后展示在应用界面。同时,可以通过RecyclerView控件实现数据的轻松展示。 社交互动功能包括用户互动、社区动态、话题讨论等。通过代码实现用户之间的关注、评论、点赞等互动功能,同时展示社区中的新鲜事。可以将互动信息存储在云服务器的数据库中,通过相应接口进行读写操作。 健康监测功能模块则包括计步器、心率监测、睡眠监测等。代码可通过传感器监听用户行为并记录数据,如使用传感器Service获取心率数据,并将其展示在健康监测界面中。同时,云服务器可实时同步存储用户的健康数据,实现数据的可视化和跨设备的数据同步。 以上仅为云养老APP的部分代码功能介绍,实际开发需结合具体需求进行设计与实现。同时,还需考虑安全性、性能优化、界面友好度等因素,以提供给用户更好的养老服务体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值