SharedPreferences に保存するとして、保存・読み出しでキーを間違えたり、対象の SharedPreferences を間違えたりしないためには、SharedPreferences への保存と読み出しを行うためのクラスを用意するとよいです。
例えば次のような Utils クラスを用意したとしましょう。
- public class ProfileSettingUtils {
- private static final String PREF_KEY_BLOOD_TYPE = "blood_type";
- private static SharedPreferences getPref(@NonNull Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
- }
- @Nullable
- public static String getBloodType(@NonNull Context context) {
- return getPref(context).getString(PREF_KEY_BLOOD_TYPE, null);
- }
- public static void setBloodType(@NonNull Context context, @Nullable String bloodType) {
- getPref(context)
- .edit()
- .putString(PREF_KEY_BLOOD_TYPE, bloodType)
- .apply();
- }
- }
しかし、"a" がA型を意味するなど、利用側が返される文字列の意味を知っている必要がありますし、"-" など意図しない文字列も保存できてしまいます。
血液型のような取り得る値が決まっているものは enum で定義して、保存・読み出し部分も enum でやりとりするべきです。
- public enum BloodType {
- A("a"),
- B("b"),
- O("o"),
- AB("ab");
- @NonNull
- public final String value;
- BloodType(@NonNull String value) {
- this.value = value;
- }
- @Nullable
- public static BloodType from(@Nullable String value) {
- if (value != null) {
- for (BloodType bloodType : values()) {
- if (bloodType.value.equals(value)) {
- return bloodType;
- }
- }
- }
- return null;
- }
- }
- public class ProfileSettingUtils {
- private static final String PREF_KEY_BLOOD_TYPE = "blood_type";
- private static SharedPreferences getPref(@NonNull Context context) {
- return PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
- }
- @Nullable
- public static BloodType getBloodType(@NonNull Context context) {
- return BloodType.from(getPref(context).getString(PREF_KEY_BLOOD_TYPE, null));
- }
- public static void setBloodType(@NonNull Context context, @Nullable BloodType bloodType) {
- getPref(context)
- .edit()
- .putString(PREF_KEY_BLOOD_TYPE, bloodType != null ? bloodType.value : null)
- .apply();
- }
- }
では Utils クラスをやめてみましょう。
- public class ProfileSetting {
- private static final String PREF_KEY_BLOOD_TYPE = "blood_type";
- @NonNull
- private final SharedPreferences pref;
- public ProfileSetting(@NonNull Context context) {
- pref = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
- }
- @Nullable
- public BloodType getBloodType() {
- return BloodType.from(pref.getString(PREF_KEY_BLOOD_TYPE, null));
- }
- public void setBloodType(@Nullable BloodType bloodType) {
- pref
- .edit()
- .putString(PREF_KEY_BLOOD_TYPE, bloodType != null ? bloodType.value : null)
- .apply();
- }
- }
このままだとロジック部分がデータアクセス部分に依存しています。
そこで、依存関係逆転の原則(DIP)を適用してロジックが抽象に依存できるように interface を用意します。
- public interface Profile {
- @Nullable
- BloodType getBloodType();
- void setBloodType(@Nullable BloodType bloodType);
- }
- public class ProfileSetting implements Profile {
- private static final String PREF_KEY_BLOOD_TYPE = "blood_type";
- @NonNull
- private final SharedPreferences pref;
- public ProfileSetting(@NonNull Context context) {
- pref = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
- }
- @Override
- @Nullable
- public BloodType getBloodType() {
- return BloodType.from(pref.getString(PREF_KEY_BLOOD_TYPE, null));
- }
- @Override
- public void setBloodType(@Nullable BloodType bloodType) {
- pref
- .edit()
- .putString(PREF_KEY_BLOOD_TYPE, bloodType != null ? bloodType.value : null)
- .apply();
- }
- }
さて、これを Kotlin 化してみましょう。
- enum class BloodType(val value: String) {
- A("a"),
- B("b"),
- O("o"),
- AB("ab");
- companion object {
- fun from(value: String?): BloodType? =
- value?.let { values().firstOrNull { it.value == value } }
- }
- }
- interface Profile {
- var bloodType: BloodType?
- }
- class ProfileSetting(context: Context) : Profile {
- companion object {
- private const val PREF_KEY_BLOOD_TYPE = "blood_type"
- }
- private val pref: SharedPreferences =
- PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
- override var bloodType: BloodType?
- get() = BloodType.from(pref.getString(PREF_KEY_BLOOD_TYPE, null))
- set(bloodType) = pref.edit().putString(PREF_KEY_BLOOD_TYPE, bloodType?.value).apply()
- }
0 件のコメント:
コメントを投稿