gpt4 book ai didi

java - 实现单例模式以在任何地方访问对象

转载 作者:行者123 更新时间:2023-11-30 10:44:24 25 4
gpt4 key购买 nike

目前,我有一个类,其构造函数采用用户名、密码和上下文。我希望能够从任何地方访问这个对象,所以我在考虑实现单例模式。

当前的构造函数使用传入的凭据来验证 future 通过该类的 api 调用。如果我要实现单例模式,我的第一个想法是让 getInstace() 方法获取用户名、密码等,但每次我抓取实例时都必须传递该信息似乎是错误的。因此,我正在考虑添加某种 .authenticate(usr, pswrd) 方法,以便在获取第一个实例时调用。

我的问题是,这是正确的方法吗?如果没有,处理这个问题的好方法是什么?这是当前代码:

构造函数:

public Play(String username, String password, Context context) {
api = getApi(username, password);
Intent intent = new Intent(context, MyService.class);
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

//check if first run
//if so, call api for info and store locally
//if not, update as needed

SharedPreferences pref = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();

if (pref.getBoolean("first_run", true)) {
loadInitialData(context);
}

editor.putBoolean("first_run", false);
editor.commit();
}

最佳答案

单例模式限制类的实例化,保证类的实例在java虚拟机中只存在一个。单例类必须提供一个全局访问点来获取类的实例。单例模式用于日志记录、驱动程序对象、缓存和线程池

此代码未经测试,但应该让您了解如何在使用 SharedPrefrences 的同时使用 singleton pattern

构造函数是私有(private)的,因此只有 getInstance() 方法可以访问该实例,因此如果该类不存在或者如果之前实例化过该实例,您将创建该类的实例

需要同步以确保多个线程首次尝试创建实例

import android.content.Context;
import android.content.SharedPreferences;

/**
* Created by Pankaj Nimgade on 23-05-2016.
*/
public class Play {

/**
* volatile keyword ensures that multiple threads handle the uniqueInstance
* variable correctly when it is being initialized to Singleton instance
*/
private volatile static Play play;

private static final String XML_FILE = "play_xml_file.xml";
private static final String KEY_DATA = "SOME_DATA_KEY";
private static final String KEY_USERNAME = "SOME_USERNAME_KEY";
private static final String KEY_PASSWORD = "SOME_PASSWORD_KEY";

private static SharedPreferences sharedPreferences;

private static SharedPreferences.Editor editor;

private Play() {
}

public static Play getInstance(Context context) {
if (play == null) {
synchronized (Play.class) {
if (play == null) {
sharedPreferences = context.getSharedPreferences(XML_FILE, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
play = new Play();
}
}
}
return play;
}

public boolean saveSomeData(String someData) {
editor.putString(KEY_DATA, someData);
return editor.commit();
}

public String readSomeData() {
return sharedPreferences.getString(KEY_DATA, "default Value");
}

public boolean saveUserNameData(String username) {
editor.putString(KEY_USERNAME, username);
return editor.commit();
}

public String readUserNameData() {
return sharedPreferences.getString(KEY_USERNAME, "default username Value");
}

public boolean savePasswordData(String password) {
editor.putString(KEY_PASSWORD, password);
return editor.commit();
}

public String readPasswordData() {
return sharedPreferences.getString(KEY_PASSWORD, "default password value");
}
}

在上面的方法中,我使类的实例创建变得惰性,因为实例只会在需要时创建,尽管代码是线程安全的并且可以在所有 Java 版本上工作,您可能需要考虑不同的方法来实现它如果您使用的是 Java 5 及更高版本。

https://sourcemaking.com/design_patterns/singleton/java/1

public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}

/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}

内部类的引用时间不早于调用 getInstance() 的时间(因此类加载器加载时间也不早)。因此,该解决方案是线程安全的,不需要特殊的语言结构(即 volatile 或同步)。

关于java - 实现单例模式以在任何地方访问对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37397014/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com