So couple of days ago I was in an interview. Recruiter asked me this question but I had no idea nor I did not understand anything after his answer. Question was:
"I have a multi modular system. I have one data module and one app module. Let's say I haven't put any android library in my data module, it's forbidden for me to add it. How do I register or access to shared preferences in this data module?"
I could not answer this but he said with dependecy inversion. Can someone explain me how this works. His answer was not enough for me.
This is actually a good question, it verifies if the candidate knows how to design a modular application.
The idea is that we abstract the way how the data is loaded and saved. We create an interface which doesn't reference the Android in any way. Depending on the case it could be something like:
interface DataRepository {
fun load(): MyData
fun save(data: MyData)
}
This interface is stored either in the data module or in a common module and it doesn't reference Android in any way.
Data module consumes this interface. It uses it to load and save the data, but it doesn't implement it, so it doesn't know what is the type of the database behind. Data module also doesn't know how to create the repository - it receives it externally. Class handling this in the data module could look like this:
class DataHandler(private val repo: DataRepository) {
fun doSomething() {
val data = repo.load()
...
repo.save(data)
}
}
Application module knows how to access the data, it implements the repository:
class SharedPrefRepository : DataRepository {
override fun load(): MyData {
// load the data from shared prefs
}
override fun save(data: MyData) {
// save the data to shared prefs
}
}
Then the application uses the data module like this:
val dataHandler = DataHandler(SharedPrefRepository())
dataHandler.doSomething()
This way only the application module knows about the Android and shared preferences, but the data module can still access the data from shared prefs.
This approach is called the dependency inversion, because the data module knows it needs the repository as its dependency, but it doesn't acquire this dependency directly - it is provided to it.