How is it more correct to organize the logic of working with SharedPreferences in Clean Architecture? After all, it will be difficult to access stored data from everywhere, it will entail the expenditure of time and nerves when you need to change something. If we write only one class for this, it will be “clean”. In this class, private keys and public getters / savers for the data will obviously be stored.


Method 1

Let's try to create it somewhere, and then forget where to access it from anywhere. The most stupid thing that comes to mind is to save it in a custom class inherited from Application :

 public class App extends Application { private static Prefs prefs; @Override public void onCreate() { super.onCreate(); prefs = new Prefs(this); } public static Prefs getPrefs() { return prefs; } } 

Well, the Prefs class Prefs written like this:

 public class Prefs { private static final String COINS = "coins"; private SharedPreferences sp; public Prefs (Context context) { sp = PreferenceManager.getDefaultSharedPreferences(); } public long getCoins() { return sp.getLong(COINS, 0); } public void saveCoins(long coins) { sp.edit().putLong(COINS, coins).apply(); } } 

The method is quite good, everything is logical: the application ( App ) contains the settings ( Prefs ), but it does not really like that every call to Prefs passes through the App .


Method 2

Initialize the Prefs and let it live by its nature

 public class App extends Application { @Override public void onCreate() { super.onCreate(); Prefs.init(this); } } 

Well, what it looks like:

 public class Prefs { private static final String COINS = "coins"; private static SharedPreferences sp; public static void init(Context context) { sp = PreferenceManager.getDefaultSharedPreferences(); } public static long getCoins() { return sp.getLong(COINS, 0); } public static void saveCoins(long coins) { sp.edit().putLong(COINS, coins).apply(); } } 

Now you can not touch the App and access Prefs from anywhere directly and, moreover, without transferring the context.

  • Which option is better for Clean Architecture?
  • Is it logical to place Prefs in com.example.app.data?
  • 1. In this case, it will be much cleaner if you inject this model with the help of Dagger2 . 2. Yes, data - the layer is great in your case. But I usually in such cases do a separate model for each entity and call it with the manager . (It makes requests to the database or pref), and this model is injected into Repository - no news
  • Why a separate entity, Clean must comply with all the paradigms of SOLID , and in this case, SRP (the principle of one-stop responsibility) is one of them. - no news
  • @nonews, for now I’ll leave it in the data package, later I'll try to learn how to use Dagger2 - Flippy

1 answer 1

  1. In this case, it will be much cleaner if you inject this model with the help of Dagger2 .

  2. Yes, data - the layer is great in your case. But I usually in such cases do a separate model for each entity and call it with the manager . (It makes requests to the database or pref), and this model is injected into the Repository

Why a separate entity

Clean must abide by all the paradigms of SOLID , and in this case SRP (the principle of shared responsibility) is one of them.