I am getting into Inversion of Control, specifically using Guice and RoboGuice for Android and I have a question.
I have a method call that returns a Resource (which is essentially an XML or JSON String).
public Resource getResource(){
// Some implementation details that call a web service and throw the result in a string...
String resource = ........
}
The Resource class is really just a wrapped String, so I figured it made sense to pass it in in the constructor, since it is an essential part of a Resource object.
public class Resource{
Resource(String theXMLorJSON){
...
}
}
A couple of questions:
How do I construct a new Resource in the getResource call? I would think that I want to use IoC and not call new in the method.
If another class takes a Resource in the constructor, how can I use the Guice container to construct it when I need a dynamic String at construction time? I just asked a similar question and believe there may be a specific way to handle this using Guice.
Thanks so much!
I think you may be misunderstanding something about dependency injection. You don't need to try to avoid using new in all cases... you primarily want to avoid using new to create anything that you might want to be able to mock out for testing, and it's generally best to allow the container to wire up any class that depends on such an object.
Your Resource class, though, sounds like a simple value object that you can easily create manually in any testing you do. It also doesn't depend on any kind of services... it just contains a String. So there's no reason to try to have the container create it.
The class containing the getResource() method, on the other hand, you definitely want the container to create, because you'd like to be able to use something that depends on that class in testing without having to actually call a web service.
Note that if you have a class with a constructor that takes both dependencies you want injected by the container and parameters that are only known at runtime, you need to create an intermediate factory of some kind with a method that only takes the runtime parameters. With Guice you can automatically create such a factory from an interface using the Assisted Inject (not sure if that works with RoboGuice, but it's easy to create such a factory implementation manually too).
Related
Currently, I have a database manager class that handles all operations to the database like this:
class DatabaseManager(val context: Context) {
private val db = Firebase.firestore
//Other functions, etc.
}
It makes use of the context passed in by different activities to perform functions to the database. The thing is, every single activity that requires database functions have to instantiate this manager class first, then call the functions. I would like to make use of the Singelton design pattern to make it such that all the activities will only use a single instance of the class. I believe kotlin's objects can do this, however I also need to be able to pass in the context of the activities into this manager class. Any assistance is appreciated, thank you!
I would recommend not doing that. The problem with Singletons is that they make code hard to test, you can't fake out the database. And for a database this is a particularly bad problem, as setting up all the right fake data can be painful. Instead, take a look at injection. It can do the same thing (make a single instance shared between everyone who needs it), but it manages that global state rather than having the classes themselves manage it via a static reference, passing it in (generally via the constructor) to whoever needs it. This makes it easy to provide an alternative or mock database when needed for testing. Injection used to be a bit painful to set up, but Hilt makes it a lot easier these days.
Recently at my company a debate started after reviewing a different approach for writing heavy duty classes.
A big Java class holding component specific logic (no standard OOP principles made sense) had to be rewritten in Kotlin. The solution provided was splitting the logic in categories and the categories into separate files with internal extension functions to the main class.
Example:
Main.kt
class BigClass {
// internal fields exposed to the extension functions in different files
// Some main logic here
}
BusinessLogic.kt
internal fun BigClass.handleBussinessCase() {
// Complex business logic handled here accessing the exposed internal fields from BigClass
}
What are your thoughts on this? I haven't seen it used anywhere maybe for a good reason, but the alternative of thousand lines classes seems worse.
You have to consider that an extension function is nothing more than a function with an implicit first parameter which is referenced with this.
So in your case you'd have something like:
internal fun handleBussinessCase(ref: BigClass)
which would translate to Java as:
static void handleBussinessCase(BigClass ref)
But this could be assumed to be a delegate pattern, which could be encapsulated much cleaner in Kotlin as well.
Since the properties have to be internal anyhow, you could just inject these as a data class into smaller use-cases. If you define an interface around these (which would make the properties public though), you could create a delegate pattern with it and still reference each property with this in your implementation.
Here are some thoughts on making extension functions for the class:
It will be a utility function that will operate with the object you're extending, it will not be an object function, meaning that it will have access to only public methods and properties;
If you're planning to use class that being extended in unit tests, these methods (extensions) will be harder to mock;
Most likely they wont behave as you expect when used with inherited objects.
Maybe I missed something, so please read more about extensions here.
I am great fan of Kotlin and how it allows us to write better code. One of the best features is interface implementation delegation which looks like this:
class A(val someObject:SomeInterface) : SomeInterface by someObject
someObject has to be singleton (object), has to be created using constructor after keyword by (but then you cannot reference to it, or maybe someone has idea how to do it?) or has to be provided in constructor.
In Android messy and bad world we are discouraged to use constructors in fragments and activites due to configuration changes. But how about this:
class MyFragment(val someObject:SomeInterface = SomeObjectImpl()):Fragment,SomeInterface by someObject
I tried to change configuration and event I allowed system to kill my appliction and still, everything is looking ok, my object is creating again and again with my fragment. Is this valid, or am I missing something?
Happy Kotlin everyone!
This is valid. The reason you're discouraged from overloading fragment constructors is that Android can recreate them, and it will use the default one: MyFragment()
But the way Kotlin implements default parameter values behind the scenes is by creating additional constructors. You can decompile your class and see it contains two constructors now, one receiving someObject, and another empty.
From the JVM perspective the empty constructor would look like this:
public A() {
this(new SomeObjectImpl());
}
Calling it will populate your fragment with new instances of implemented classes.
There are many questions and answers on how to implement a global variable in Android/Java.
So it seems one can either implement a singleton or use a data class itself with static variables.
I am about to start a larger project and would like to start on the right foot.
I am just not sure which one to use.
Pro singleton/con Data Class
supposedly "cleaner" way (but I really don't know why)
ensures that there is really always just one representation
creates a new instance should the old one be "cleaned away" (whenever this may happen?)
Con singleton/pro Data Class
not recommendet by some (but did not find convincng reasons)
ensures that there is only one representation by design
very easy to access just by writing MyDataClass.x (vs accessing singleton requires getting access to it first somehow)
no need to pass it as a parameter
So in summary I tend to use DataClass but I am unsure because I read that this is supposedly not good programming style.
I like to add
the data this global object has to hold is quite big, more than 30k strings/keys. And this should not be cleaned at any stage so that when the app return it may crash because of that - as I read in other places eg Singletons vs. Application Context in Android? (the 3rd answer)
it's not a web application, I use only one classloader
it is multithread but only one thread is actually accessing this data
one may certainly also use this approach How to declare global variables in Android?, but isn't an ObjectClass just easier to use and access in this case?
And checking this http://developer.android.com/resources/faq/framework.html, esp under "Persistent Objects", implies that there is no real advantage for on or the other in those cases anyway.
Many thanks
Best way to implement singleton is to use enum.
public enum Singleton
{
INSTANCE;
public void someMethod()
{
// your code here
}
}
For more details you can read Effective Java (2nd Edition)
First of all: There's not much difference between a class with public static member variables and a singleton class. A lot of developers prefer the singleton pattern because the code looks more natural and more Java. E.g. Singleton.Data looks like a constant access and Singleton.getData() looks like you're accessing some kind of static data.
Personally I use the static Application pattern: See Accessing resources without an Activity or Context reference
You can use onCreate to setup any kind of static data or even other singletons. E.g. I prefer to setup a singleton SQLite database like that and access it then via App.getDb(). You can use this pattern to access the application context or resources.
While using static data you should think about memory leeks. I would recommend to take a look at this article then.
I need to use getString() from most of the modules in my application.
But for some strange reason, it is tied to Application or Context, so that means I need to pass to each and every class in my application, the Application reference as a parameter.
This clearly violates one of the most basic principles of object oriented design.
Is there a way around this?
The 'strange reason' is that since the string resources are tied to your application, there is no way to access them without some sort of handle to it (the Context). If most of your classes that are not activities need to access string resources, you might want to rethink your design a bit. A simple way to not depend on a Context is to load the strings and pass them to your classes in the constructor.
Yes, there is a workaround - if you happen to (or can) pass a View (any View-derived class) to the constructor, and you assign it to a data member, then you can access the string resources from anywhere in your class:
String str_via_res = yourView.getContext().getString(R.string.str_via_res);
Otherwise, you will have to pass a Context to every class that needs access to these string resources.
you can extend android.app.Application class to create a static method to pass on the context across all classes in your application.
Refer : PhoneApp.java