How can I make an existing Java class/interface implementation a singleton? - java

Suppose I am using an ApplicationContext implementation in Spring.
ApplicationContext is an interface in the Java Spring Framework and I cannot change it.
How do I ensure that there can be only one instance of this implementation?
For eg. I have the following code -
public class ApplicationContextSingleton
{
private static ApplicationContext context;
private static int numberOfInstances = 0;
public static ApplicationContext getApplicationContext()
{
if(numberOfInstances == 0)
{
context = new ClassPathXmlApplicationContext("spring.xml");
numberOfInstances++;
}
return context;
}
}
This way, I can ensure that there is only one instance of ApplicationContext, provided it is obtained as follows -
ApplicationContext context = ApplicationContextSingleton.getApplicationContext();
But that doesn't stop another programmer from saying -
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
thereby creating a new ApplicationContext. How to prevent this from occuring?

You want to make ApplicationContext a singleton, so I'd override the class with my own custom class, make sure it appears first on the class path, and make it have a private constructor.
That is, if you're dead set on making it a singleton. There are better ways to solve your problem, as pointed out by other answers and comments.
Should note that it's usually a bad idea to override pieces of libraries, as it can be the cause of headaches later, especially when you try upgrading your framework version.

Unless somebody can come up with something reeeeeally creative, I don't think there's a way to do this. This would be similar to trying to make an int a singleton. Just not gonna happen, as you don't have any control over the usage of classes you didn't write. You're just going to have to trust your developers not to create a second context.
Alternatively, and I can almost promise this will be out of the question, but you could get the full source for spring, make some code changes to make the context a singleton, and then build it out yourself. Not a likely solution, but I felt the need to point it out anyway.

there is no way to do that because
ClassPathXmlApplicationContext is not implemented as Singleton pattern by Spring.
Inform every one that you have a utility method to access the context object and creating context using new is expensive.

Use an automated build system that builds your code whenever it is committed to your software repository.
Integrate tools into your build process like FindBugs or PMD. If these tools trigger certain conditions, fail the build and allow no artifacts to be generated.
Create a case in your integrated tool that looks for developers creating their own context.
So you can't stop them from doing it, but you can stop them from pushing such things into your dev, qa, and prod environments. This might seem like overkill, but this sort of process will help with hundreds of things your developers -can- do but shouldn't.

Josh Block suggests using an enum in Effective Java. This isnt a link to that book, but it shows his and the older way (alternative) way of doing it

Related

How should I work around the context object for DI and testing?

I have a class that creates a bitmap object.
It needs access to a bitmap resource so it needs access to the context which I pass into its constructor so I call it like myClass(context)
Ideally i'd like to inject the dependency somehow. I wanted to do this with a factory so I could just ask the factory for the object and it creates it for me, but I can only get context from activity classes which create new windows. So it seems I'll have to keep passing in context from my main activity.
I asked a similar question recently and was told I shouldnt call context statically at all and should always be passing it around.
This means if I want to test this class my test class needs access to the android framework (which means I can't test locally and will have to use AndroidTests).
Is this how it is supposed to work? My class just needs a bitmap but I can't test locally now because of context.
If you need the functionality of Context, then you'll need to pass it into MyClass one way or another. However, this doesn't mean that you need to statically store Context. In fact, that would be a really bad design choice (looks like you already know that).
If you use Dagger, then I have this video tutorial that explains how to structure dependency injection code. Part of this structuring is indeed handling the complexity of Context objects.
Now, even if MyClass needs an access to Context in order to obtain bitmap, it doesn't necessarily mean that you need resolve to integration tests.
First of all, you can use Robolectric - this library "mocks" Android framework, and I think that it supports getting bitmap from resources.
However, depending on your use case, there is also a simpler option. Do you really need a specific bitmap, or you just want to ensure that MyClass performs specific actions on this bitmap?
If you need the specific one that you add as a resource then go for Robolectric, but if not and all you need is to make sure that the obtained bitmap is being used correctly then you can just mock the bitmap.
In order to increase readability, simplify the testing and prevent violation of Law of Demeter, I suggest that you wrap Context into this class:
public class BitmapRetriever {
private final Context mContext;
public BitmapRetriever(Context context) {
mContext = context;
}
public Bitmap getBitmapById(int id) {
// code that obtains bitmap
}
}
Then make MyClass depend on BitmapRetriever instead of Context.
Once you do this, it will be straightforward to pass mocked BitmapRetriever in test that will return mocked Bitmap when MyClass asks for it. Then you can assert various conditions on that mock.
If your class only needs a bitmap, why can't you mock a bitmap? You should test the logic in your class. You do not need to test the Context bitmap loading functionality as I'm sure that is already tested in the Android framework. You already have a great idea with the factory pattern as you could just inject a mock factory for testing by using myClass(bitmapFactory) in your app and myClass(mockFactory) in your tests.
If you're absolutely sure you need to write a test to cover the bitmap loading, then look into testing frameworks like robolectric as it can provide mock context for scenarios like this.

Behavior of static class variables in Android application [duplicate]

In android, are using static variables a recommended practice?
E.g, implementing a Singleton pattern in Java, I usually do:
private static A the_instance;
public static A getInstance() {
if (the_instance == null) {
the_instance = new A();
}
return the_instance;
}
Also, when does this get cleaned up by the Android JVM?
static fields are attached to the Class instance as a whole, which is in turn attached to the ClassLoader which loaded the class. the_instance would be unloaded when the entire ClassLoader is reclaimed. I am 90% sure this happens when Android destroys the app (not when it goes into the background, or pauses, but is completely shut down.)
So, think of it as living as long as your app runs. Is Singleton a good idea? People have different views. I think it's fine when used appropriately, myself. I don't think the answer changes much on Android. Memory usage isn't the issue per se; if you need to load a bunch of stuff in memory, that's either a problem or it isn't, regardless of whether you encapsulate the data in a Singleton.
I think static variables are OK.
This is what Android doc says:
http://developer.android.com/guide/appendix/faq/framework.html
How do I pass data between Activities/Services within a single application?
A public static field/method
An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.
Contrary to what other people say - it is more than ok. Granted, it has some structure to it. In the official googlesamples/android-architecture repo it is used under todo-mvp-clean (Todo app implementing MVP pattern and following Clean Architecture principles).
Check out this file.
What you can see is a lot of static methods referencing singleton getters.
Modern, less error prone and convenient alternative is the Dagger DI framework.
I'm not sure if such approach is good for mobile platform where you have limited memory available to you. Not to mention that the application will be run on a multi-tasking enabled device.
I think, this approach may hog memory from the device but I have no document to support this. Perhaps someone who's more educated than me can share their thoughts.
No. Don't do it! Singleton is an anti-patern!. Instead, use dependency injection, whether via a framework (such as via Dagger or Roboguice) or by explicitly passing the instantiated object.

Affecting Java classes without changing the code

I am using a Java library, with two classes Foo and FooConfig; I am unable to change the library code, but can read it. Here are the relevant functions of a Foo:
public class Foo
{
/** Install a configuration on this Foo */
void configure(FooConfig config);
/** Uninstall the current configuration */
void unconfigure();
}
The library creates Foos at times I can't control, and installs configurations shortly after creation. A Foo can only have on configuration at a time. I would like to use MyFooConfig, inherited from FooConfig, instead. Is there any way to intercept the configure call, or the FooConfig constructor, or anything like that to use my class instead?
My current solution is to get a reference to the Foo object shortly after its creation and configuration, uninstall the current configuration,and then install a MyFooConfig instead. This could work, but it causes several different problems (both with being a difficult solution to implement and with some inelegancies which can't be hidden from the user). Is there a better way, preferably using features of Java to intercept the constructor call to FooConfig, or the configure method, or something similar? The closest thing to an alternate solution I've found is to try to use a different ClassLoader to replace FooConfig with my own class behind the scenes, but I don't actually have access to the object that creates the FooConfigs so I don't think that's possible. Other things that looked promising but ultimately didn't pan out are proxy objects (I can't make the Foos be proxy objects), seeing if I could somehow get notified when a FooConfig was created without actually intercepting the constructor (so I could find its Foo and reconfigure it in a better way than I`m currently doing), and changing the library code itself (which, for various reasons, turns out to not be possible).
I don't know much about aspect-oriented programming, but it seems like it could help. Unfortunately, all the AOP Java tools seem to require special compilers, and I don't want to change the build process.

Domain Driven Design - testability and the "new" keyword

I have been trying to follow a domain driven design approach in my new project. I have always generally used Spring for dependency injection, which nicely separates my application code from the construction code, however, with DDD I always seem to have one domain object wanting to create another domain object, both of which have state and behaviour.
For example, given a media file, we want to encode it to a different format - the media asset calls on a transcode service and receives a callback:
class MediaAsset implements TranscodingResultListener {
private NetworkLocation permanentStorage;
private Transcoder transcoder;
public void transcodeTo(Format format){
transcoder.transcode(this,format);
}
public void onSuccessfulTranscode(TranscodeResult result){
Rendition rendition = new Rendition(this, result.getPath(), result.getFormat());
rendition.moveTo(permanentStorage);
}
}
Which throws two problems:
If the rendition needs some dependencies (like the MediaAsset requires a "Transcoder") and I want to use something like Spring to inject them, then I have to use AOP in order for my program to run, which I don't like.
If I want a unit test for MediaAsset that tests that a new format is moved to temporary storage, then how do I do that? I cannot mock the rendition class to verify that it had its method called... the real Rendition class will be created.
Having a factory to create this class is something that I've considered, but it is a lot of code overhead just to contain the "new" keyword which causes the problems.
Is there an approach here that I am missing, or am I just doing it all wrong?
I think that the injection of a RenditionFactory is the right approach in this case. I know it requires extra work, but you also remove a SRP violation from your class. It is often tempting to construct objects inside business logic, but my experience is that injection of the object or a objectfactory pays off 99 out of 100 times. Especially if the mentioned object is complex, and/or if it interacts with system resources.
I assume your approach for unit testing is to test the MediaAsset in isolation. Doing this, I think a factory is the common solution.
Another approach is to test the whole system (or almost the whole system). Let your test access the outer interface[1] (user interface, web service interface, etc) and create test doubles for all external systems that the system accesses (database, file system, external services, etc). Then let the test inject these external dependencies.
Doing this, you can let the tests be all about behaviour. The tests become decoupled from implementation details. For instance, you can use dependency injection for Rendition, or not: the tests don't care. Also, you might discover that MediaAsset and Rendition are not the correct concepts[2], and you might need to split MediaAsset in two and merge half of it with Rendition. Again, you can do it without worrying about the tests.
(Disclaimer: Testing on the outer level does not always work. Sometimes you need to test common concepts, which requires you to write micro tests. And then you might run into this problem again.)
[1] The best level might actually be a "domain interface", a level below the user interface where you can use the domain language instead of strings and integers, and where you can talk domain actions instead of button clicks and focus events.
[2] Perhaps this is actually your problem: Are MediaAsset and Rendition the correct concepts? If you ask your domain expert, does he know what these are? If not, are you really doing DDD?

Using static variables in Android

In android, are using static variables a recommended practice?
E.g, implementing a Singleton pattern in Java, I usually do:
private static A the_instance;
public static A getInstance() {
if (the_instance == null) {
the_instance = new A();
}
return the_instance;
}
Also, when does this get cleaned up by the Android JVM?
static fields are attached to the Class instance as a whole, which is in turn attached to the ClassLoader which loaded the class. the_instance would be unloaded when the entire ClassLoader is reclaimed. I am 90% sure this happens when Android destroys the app (not when it goes into the background, or pauses, but is completely shut down.)
So, think of it as living as long as your app runs. Is Singleton a good idea? People have different views. I think it's fine when used appropriately, myself. I don't think the answer changes much on Android. Memory usage isn't the issue per se; if you need to load a bunch of stuff in memory, that's either a problem or it isn't, regardless of whether you encapsulate the data in a Singleton.
I think static variables are OK.
This is what Android doc says:
http://developer.android.com/guide/appendix/faq/framework.html
How do I pass data between Activities/Services within a single application?
A public static field/method
An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.
Contrary to what other people say - it is more than ok. Granted, it has some structure to it. In the official googlesamples/android-architecture repo it is used under todo-mvp-clean (Todo app implementing MVP pattern and following Clean Architecture principles).
Check out this file.
What you can see is a lot of static methods referencing singleton getters.
Modern, less error prone and convenient alternative is the Dagger DI framework.
I'm not sure if such approach is good for mobile platform where you have limited memory available to you. Not to mention that the application will be run on a multi-tasking enabled device.
I think, this approach may hog memory from the device but I have no document to support this. Perhaps someone who's more educated than me can share their thoughts.
No. Don't do it! Singleton is an anti-patern!. Instead, use dependency injection, whether via a framework (such as via Dagger or Roboguice) or by explicitly passing the instantiated object.

Categories