Instance controlling using enum - java

I have a factory class, which I have made singleton using enum. I want to make sure that the object being created is also singleton (Please note that I do not own the class being created, but I want to ensure that it's object is singleton).
I am trying something like this
public enum MyFactoryImpl implements MyFactory {
INSTANCE;
private final MyObject myObject = buildMyObject(); //I want to instance control this
private MyObject buildMyObject() {
return new MyObject();
}
public MyObject myFactoryMethod() {
return this.myObject;
}
}
I tried calling the factoryMethod in a test case in parallel fashion using testNG, and multiple invocation seem to return the same hashCode.
#Test(threadPoolSize = 10, invocationCount = 600, timeOut = 100000)
public void test_instanceControlledBehavior() {
final MyFactory f1 = MyFactoryImpl.INSTANCE;
final MyFactory f2 = MyFactoryImpl.INSTANCE;
Assert.assertEquals(f1.myFactoryMethod().hashCode(), f2.myFactoryMethod().hashCode());
}
Is this the correct way of implementing the behavior? Is there a better way I can instance control 'MyObject'?

Related

Global mapping in the Java application

I wonder what is the best practice of having some global mapping in a Java application?
Say I have a text file with the mapping:
key1:value1
key2:value2
...
keyN:valueN
The file is huge, and both keys and values are arbitrary, so I can't really use Enum.
In the Java application I'm going to instantiate a bunch of classes with keys as the input (note that the code is more adequate in reality, just trying to put it abstract and simple):
for(int i = 0; i < 10000; i++) {
String key = magicallyGetArbitaryKey();
SomeClass someClass = new SomeClass(key);
//do stuff
}
and assign a property in the constructor based on the map lookup.
public class SomeClass {
private String value;
public void SomeClass(String key) {
this.value = getValue(key);
}
private String getValue() {
// what is the best way to implement this?
}
}
I want my code to be simple and, what is important, testable. And avoid using frameworks such as Spring.
This is what I came up with so far: create a Holder class, which is simply a wrapper around the HashMap with the additional methods for initialization:
class MappingHolder {
private Map<String, String> keyValueMap = new HashMap();
public MappingHolder(String filePath){
keyValueMap = ...; //init from the file
}
public MappingHolder(Map initMap) { //constructor useful for testing
keyValueMap = initMap;
}
public String get(String key) {
return keyValueMap.get(key);
}
It seems to be obvious that I want to have only one instance of the mapping.
As far as I can see the options are:
Have the MappingHolder#getValue as a static method
public class SomeClass {
...
private String getValue() {
return MappingHolder.getValue()
}
Have the MappingHolder#getValue as an instance method, but make
field of the type MappingHolder static in the SomeClass
public class SomeClass {
...
private static MappingHolder mappingHolder = new MappingHolder();
private String getValue() {
return mappingHolder.getValue();
}
Make the MapppingHolder a singleton.
public class SomeClass {
...
private MappingHolder mappingHolder = MappingHolder.getInstance();
private String getValue() {
return mappingHolder.getValue();
}
Neither of this seems to me testable, having just JUnit and Mockito and not leveraging some more powerful mocking frameworks. Though I sucks in testing and maybe I am wrong.
So it would be great if one could recommend the approach, either how to develop further my own, or better one which I may be missing. Thanks!

Java child class that can be refreshed with new instances of the parent class

I'm working with the Java AWS API to monitor some EC2 instances and on every refresh I need to query the service which returns a bunch of Instance objects (freshly constructed). I want to extend the functionality of these objects, I figure I can maintain a map of MyInstance objects which can be refreshed with the new Instances on each poll.
Now I could easily do this with a simple wrapper class that holds the original Instance as a property the issue is I would like to keep access to the base Instance API as I already use these functions in my code. Would it be possible to replace only the super-class parts of an instantiated object? Contrived example of what I'm going for:
class Instance {
protected int prop;
public Instance(int prop) {
this.prop = prop;
}
}
class MyInstance extends Instance {
protected int prop2;
public MyInstance(int prop, int prop2) {
super(prop);
this.prop2 = prop2;
}
}
MyInstance foo = new MyInstance(1, 2);
Instance foster = new Instance(3);
//what i want to do
foo.adoptedBy(foster);
//with the result that foo.prop == 3
Obviously this example would be trivial to transform but in my actual case there are far more properties that need to be transferred. Can Reflection do this? What kind of performance impact am I looking at if I use Reflection for 10 of these every second? Thanks for reading!
The best solution is to combine both your ideas:
Wrap the original Instance in a class that extends the Instance class. (In the constructor of the child class, you can create a new Instance object and set it)
Delegate all methods to the wrapped instance (and add new properties)
In your foster method, you simply change the wrapped Instance.
class Instance {
private int prop;
public Instance(int prop) {
this.prop = prop;
}
public int getProp() {
return prop;
}
}
class MyInstance extends Instance {
private Instance delegate;
private int prop2;
public MyInstance(Instance delegate, int prop2) {
super(prop);
this.delegate = delegate;
this.prop2 = prop2;
}
#Override
public int getProp() {
return delegate.getProp();
}
public int getProp2() {
return prop2;
}
public void foster(Instance i) {
delegate = i;
}
}
MyInstance foo = new MyInstance(1, 2);
Instance foster = new Instance(3);
//what i want to do
foo.adoptedBy(foster);
//with the result that foo.getProp() == 3

Passing object by reference to a thread

Let's say I have a class called Object and a thread called ObjectCreator that manages the creation of an Object. For the sake of simplicity, Object has attributes: objectNumber and objectName.
If I were to create an instance of Object called instance, it would be held by ObjectCreator. Now let's say I needed another thread (let's call it ObjectChanger) to be able to see and manipulate instance; does it make sense to turn instance into a static Object?
I've managed to see results by making instance static so now I can do something like:
ObjectCreator.instance.getName();
Where getName() is a method of Object. From what I've read from answers to similar questions, static things are evil and there's always workarounds. One suggestion I've read is to pass instance to ObjectChanger as an argument for its constructor but what if instance wasn't created yet at the time I need to create an ObjectChanger?
Perhaps this question is more about OOP concepts than multi-threading or it may be a duplicate so forgive me but I'm quite lost here.
EDIT: To address frankie's and Jim's suggestions, here are some code snippets:
Object:
class Object
{
private String objectName = "Something";
private int objectNumber = 1;
public synchronized void changeNumber(int newNumber)
{
objectNumber = newNumber;
}
}
ObjectCreator:
class ObjectCreator extends Thread
{
static Object instance;
public ObjectCreator (Object something)
{
instance = something;
}
static void createObject()
{
...
}
static Object getObject()
{
return instance;
}
}
ObjectChanger:
public class ObjectChanger extends Thread
{
private Object currentInstance = null;
private int instanceNumber = null;
public void run()
{
currentInstance = ObjectCreator.getObject(); //If I were to make getObject() non-static, this line churns up an error
instanceNumber = currentInstance.getObjectNumber();
currentInstance.changeNumber(2); //valid?
}
}
If you want a thread to obtain access to an object not created within it, you must ensure that said thread has a path of references which it can follow, leading to the new object.
Consider the following code, with no threads involved.
class MyObject { /* ... */ }
interface MyObjectProvider {
MyObject getMyObject();
}
class Creator implements MyObjectProvider {
private MyObject obj;
/* ... */
#Override
public MyObject getMyObject() {
return obj;
}
/** Invoked at some point in time. */
void createMyObject() {
obj = new MyObject();
}
}
class Consumer {
private MyObjectProvider provider;
Consumer(MyObjectProvider mop) {
provider = mop;
}
void consume() {
// At some point in time...
MyObject o = provider.getMyObject();
}
}
Example of a program:
public static void main(String[] args) {
Creator creator = new Creator();
Consumer consumer = new Consumer(creator);
creator.createMyObject();
consumer.consume();
}
When you add threads to the mix, some code has to change, but the struture is the same.
The idea is to run the Creator in a thread, and the Consumer in another, as you've pointed out.
So, in short, these are the things you should be looking into:
Concurrency control: look into data races, synchronized, mutual exclusion, and their friends. Start here.
wait and notify, if the Consumer should wait for MyObject to be created. Look here.
When you have a nice grasp on these concepts, you may look into the volatile keyword (watch out for its pitfalls), and the java.util.concurrent package which provides better concurrency primitives, concurrent collections, and atomic variables.
You can put your objects in a list structure like Vector and store them in the ObjectCreator. Add a getter method to ObjectCreator which will accept an index of the object to be received.
This is just a skeleton showing the basic structure. Error handling is left as an exercise :-)
public class MyObject { ... }
...
public class MyObjectCreator {
private Map<String,MyObject> createdObjects = new HashMap<>();
public MyObject makeNewObject(int objNum, String objName)
{
MyObject o = new MyObject(objNum, objName);
this.createdObjects.put(objName,o);
}
public MyObject getObject(String objName)
{
return this.createdObjects.get(objName);
}
}
...
public class MyProgram {
public static void main(String[] args)
{
MyObjectCreator oc = new MyObjectCreator();
MyObject mo = oc.makeNewObject(10,"aNewObject");
...
MyObject o = oc.get("aNewObject");
...
If you only want to change the values of the fields of your class, you should just pass the object into your newly created thread. Then there is really no need to keep a static reference around in a holder class.
But as commented already, we need a bit more information to get to what you want to do with your object and thread.
Why cant you just make an getter in the ObjectCreator class that retrieves said Object?
ex: ObjectCreater.getMyObject()
EDIT:
I think you're looking for something like this if Im not mistaken:
public class ObjectCreator{
ArrayList<Object> children;
public ObjectCreator(){
children = new ArrayList<Object>();
}
//returns back index in children array (for accessing from other threads)
public int createObject( whatever params here ){
Object o = new Object( params );
children.add(o);
return children.size()-1;
}
}
since I dont know much about the problem you're trying to solve, Im not sure if it has to be thread safe, if you want these objects mapped, or accessed differently, but Im confused where all the confusion about static is coming...

Test a factory of a 3rd party class

My application uses a third party jar (no access to source, etc.) I have a factory that creates an object (call it Foo) correctly from settings, i.e.
public FooFactoryImpl implements FooFactory {
private final Settings settings;
private final OtherDependency other;
#Inject
public FooFactoryImpl(Settings settings, OtherDependency other) {
this.settings = settings;
this.other = other;
}
public Foo create(String theirArg) {
Foo newFoo = new Foo(theirArg); // there is no no-arg constructor
// This isn't exactly the way I do it but this is shorter and close enough
newFoo.setParamOne(settings.get("ParamOne"));
newFoo.setParamTwo(settings.get("ParamTwo"));
// etc.
}
}
I would like to unit test this factory using Mockito - make sure the created object is configured correctly. But of course, I run into this problem; that is, because my factory calls new, I can't inject a spy.
One possible solution is to introduce something like:
public FooFactoryDumb implements FooFactory {
public Foo create(String theirArg) {
return new Foo(theirArg);
}
}
And then something like:
public FooFactoryImpl implements FooFactory {
#Inject #Dumb private FooFactory inner;
// snip, see above
public create(String theirArg) {
Foo newFoo = inner.create(theirArg);
// etc.
}
}
This seems like a lot of boilerplate code just to enable unit testing. It smells bad to me, but I might be wrong. Is there a better way?
There is a similar but simpler way to do it: add a protected method to your factory to create a Foo:
protected Foo create(String theirArg){
return new Foo(theirArg);
}
then in your tests of your Factory, create a Test Double of your FactoryImpl and override the create method:
private class FooFactoryImplTestDouble extends FooFactoryImpl{
...
#Override
protected Foo create(String theirArg){
//create and return your spy here
}
}
Create a new class:
public class FooFactory3rd {
public Foo create3rdParty(String theirArg) {
return new Foo(theirArg);
}
}
Then change your class to:
public FooFactoryImpl implements FooFactory {
private final Settings settings;
private final OtherDependency other;
private final FooFactory3rd fooFactory3rd;
#Inject
public FooFactoryImpl(Settings settings, OtherDependency other, FooFactory3rd fooFactory3rd) {
this.settings = settings;
this.other = other;
this.fooFactory3rd = fooFactory3rd;
}
public Foo create(String theirArg) {
Foo newFoo = fooFactory3rd.create3rdParty(theirArg);
// This isn't exactly the way I do it but this is shorter and close enough
newFoo.setParamOne(settings.get("ParamOne"));
newFoo.setParamTwo(settings.get("ParamTwo"));
// etc.
}
}
And in your test code:
Foo fooMock = mock(Foo.class);
FooFactory3rd fooFactory3rdMock = mock(FooFactory3rd.class);
when(fooFactory3rdMock.create3rdParty(any(String.class)).thenReturn(fooMock);
FooFactoryImpl fooFactoryImpl = new FooFactoryImpl(settings, other, fooFactory3rdMock);
fooFactoryImpl.create("any string");
This way, you can inject your fooMock. When you call fooFactoryImpl.create("any string"), your mocked Foo is called under the cover.
Or if you want to go further clean, don't even need the constructor arg of FooFactory3rd. Just declare
private final FooFactory3rd fooFactory3rd = new FooFactory3rd();
And in your test, use reflection to change it to the mocked FooFactory3rd.
Well, it turns out that I had to use PowerMock anyway because the third party's methods were final. Since I'm already using PowerMock, I realized I can just do this:
#Before
public void setUp() throws Exception {
Foo toReturn = PowerMockito.mock(Foo.class);
PowerMockito.whenNew(Foo.class).withAnyArguments().thenReturn(toReturn);
}
And then I don't have to touch my original class at all.
Note: If you do this, you have to prepare both classes for PowerMock, i.e. do
#PrepareForTest( { Foo.class, FooFactoryImpl.class } )
Take a step back and think about what the contract of FooFactoryImpl is. It is that it must create a fully functional Foo, whatever that means. So if the contract of a Foo is that it does X, Y and Z, then the contract of a FooFactoryImpl is that it creates objects that do X, Y and Z.
This is a case for the kind of test in which the SUT consists of more than one class. I don't care whether you call this a unit test, an integration test, a subsystem test, a collaboration test, or some other name. The point is that the only meaningful test of FooFactoryImpl is a test that tests Foo as well. Instead of writing a test class for Foo alone, write a test class that tests the two classes jointly.
So, if the contract of Foo is to do X, Y and Z, then your test cases will do the following things with a FooFactoryImpl.
Call create and test that the created object does X.
Call create and test that the created object does Y.
Call create and test that the created object does Z.
I believe this is the only sensible way to attack this problem. The hard part is coming up with a convincing name for the test class.

How to extend a singleton class to handle a specific number of objects

In Java, I have created a singleton class as follows:
public class Singleton
{
private Singleton() { print("Singleton Constructor"); }
private static Singleton pointer = new Singleton();//static here so only one object
public static Singleton makeSingleton()
{
return pointer;
}
public static void main (String args[])
{
Singleton nuReference = Singleton.makeSingleton();
if(nuReference == pointer)
{
print("Both are references for same object.");
}
}
}
Here, only the reference to an already-created object of Singleton class is being returned. How can I create a class so that only, say, four objects of that class are allowed to be created? Can I use this Singleton class for that or do I have to make it from scratch?
Oh, and print() is my custom method here. Works the same as System.out.println(), just with fewer keystrokes :)
That should work:
public class Singleton
{
private Singleton()
{
print("Constructor");
}
private static Singleton instances[] = new Singleton[4];
private static Boolean initiated = false;
public static Singleton getInstance(int index)
{
tryInitiate();
if(instances[index] == null)
{
instances[index] = new Singleton();
}
return instances[index];
}
private static Boolean tryInitiate()
{
if(initiated) return false;
for (int i = 0; i < instances.length; i++)
{
instances[i] == null;
}
initiated = true;
return true;
}
}
Instead of initiating the objects with "null" you could also instantiate the objects during the initiation. But this way only the needed objects are instantiated.
Add a static int count = numyouwant; to your code, every time the static creation method is called, reduce the count by 1. and more importantly, check whether count is 0 before call the private constructor in the creation method~
Singletons, by definition, only have a single instance of itself. What you're suggesting sounds like you would make better use of a Factory-type paradigm, along with a counter/limiter (built into the class).
Make a Factory class that contains a counter (or a list to store created objects, if you prefer) and a createObject method. In the method, do your logic for determining whether there are too many objects, and therefore you may limit creation of the objects.
Here's an example of a Factory with a max limit on created objects. The object in question is an inner class for simplicity.
public class Factory {
private final int maxObj = 4;
public class MyObject {
MyObject() { print("Constructor"); }
}
private List<MyObject> objects = new List<Object>();
// Returns new MyObject if total MyObject
// count is under maxObj, null otherwise
public MyObject makeObject() {
if (objects.length() >= maxObj)
return null;
MyObject obj = new MyObject();
objects.add(obj);
return obj;
}
}
create a variable x
increase its value every time when makeSingleton is called
if x<4 then return pointer
else return null
Create a field of List<Singleton> mySingletons; and a field int singletonCounter=0;
in makeSingleton() method add 1 to counter if it is equal to 4 return null or return a singleton of 4.If counter is less than 4 then create a singleton.
my question is that how can i create a class so that say only 4 objects of that class are allowed to be created. any help ?
can i use this Singleton class for that or do i have to make it from scratch ?
I believe you want to keep a pool of objects of a class . You can't do it through a Singleton class , which by definition should return the only instance it has.
Suggested reads:
Object Pool in Java
.
Build your own ObjectPool
You could add a Queue of 4 instances of the same object, and manage the queue/dequeue operations.
Beware: Sounds you should apply thread-safety for those operations.
I created one with Thread Safty
import java.util.ArrayList;
import java.util.List;
public class SingletonLimit{
private List<SingletonLimit> inst_Obj= new ArrayList<>();
private static final int maxLimit=4;
private SingletonLimit(){
}
public SingletonLimit getInstance(){
if(inst_Obj.size()>=maxLimit)
return null;
SingletonLimit singleLimit=null;
synchronized(SingletonLimit.class){
singleLimit= new SingletonLimit();
inst_Obj.add(singleLimit);
}
return singleLimit;
}
}

Categories

Resources