I have an ObjectFactory and a specialized case of implementation of that factory. I can't change the interface, that has 0 argument.
In one of the implementation I have to read a file and load some data. To pass the filename I can use the system properties because all I need to share is a string.
But in the other implementation I must start not from a file but from a memory structure. How can I do to pass the object (then I think the object reference) to the factory? Other methods? No way I serialize the object on a file and after I read it again because what I want to avoid is right the I/O footprint.
Thanks
OK, more informations:
This is the interface and the abstract factory I have to implement
public abstract interface A
{
public abstract Set<Foo> getFoo();
public abstract Set<Bar> getBar();
}
//this is otherpackage.AFactory
public abstract class AFactory
{
public static AccessFactory newInstance()
{
return a new built instance of the factory
}
public abstract A newA();
}
This is my implementation with my problem:
public class AFactory extends otherpackage.AFactory
{
#Override
public Access newA()
{
return new AA();
}
}
public class AA implements A
{
protected AA()
{
this.objectReferenceIWantToSaveHere = I retrieve from the shared memory zone;
use the object
}
}
Now I'd like to do something like this:
B b = something I built before
save b in a shared memory zone or something like that
otherpackage.AFactory f = mypackage.AccessFactory.newInstance();
A a = f.newA();
And inside the f.newA() call I'd like to access to the b object
Can't you simply use a constructor?
interface ObjectFactory { Object create(); }
class SpecialFactory implements ObjectFactory {
private final Object data;
public SpecialFactory(Object data) { this.data = data; }
#Override public Object create() { return somethingThatUsesData; }
}
Ass assylias proposes, you can pass the reference to the constructor. Or if you know where to find the reference, you could just ask for it before you use it? E.g. data = dataBank.giveMeTheData()
Agree it would help to get some more context around what you are doing... but could you use a shared static class in which your calling code places info into the static class, and your interface implementation references this same static class to obtain either the object and/or instructions?
So here's a client class. It has the entry point..and wants to pass an object to the interface implementer but it can't pass it directly...So it set's object it wants to pass in the MyStaticHelper.SetSharedObject method.
public class Client {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String mySharedObject = "Couldbeanyobject, not just string";
// Set your shared object in static class
MyStaticHelper.SetSharedObject(mySharedObject);
InterferfaceImplementer myInterfaceImplementer = new InterferfaceImplementer();
//
myInterfaceImplementer.RunMyMethod();
}
Here is the code for the static helper...
public class MyStaticHelper {
private static Object _insructionsObject;
public static void SetSharedObject(Object anObject)
{
_insructionsObject = anObject;
}
public static Object GetSharedObject()
{
return _insructionsObject;
}
}
and finally the the class that you call that uses the static helper to get the same object.
public class InterferfaceImplementer {
// no objects
public void RunMyMethod()
{
System.out.println(MyStaticHelper.GetSharedObject());
}
}
Again this works in a very simple scenario and wouldn't stand up if more than one implementer needs to be called simultaneously as this solution would only allow one obj to be in the static helper class.
Related
In previous C++ code I've used friend classes when creating a factory that can output "read only" objects which means that as the objects are consumed throughout the code there is no risk that they can be inadvertently changed/corrupted.
Is there is there a similar way to implement this in Java or am I being overly defensive?
Make use of the final keyword. This keyword can mark a class/methods as non-extendable, and mark fields/variables as non-mutable.
You will hide the default constructor of the object using the private constructor, and force parameterised constructors which will initialise all necessary final fields.
Your only problem is that the factory is kind of redundant. Since all fields of the object are final, you will have to use all factory methods at object build-time.
Example:
public final class DataObject
{
protected final String name;
protected final String payload;
private DataObject()
{
}
public DataObject(final String name, final String payload)
{
this.name = name;
this.payload = payload;
}
}
// Using the factory
DataObject factory = new Factory().setName("Name").setPayload("Payload").build();
// As opposed to
DataObject dao = new DataObject("Name", "Payload");
// ==> Factory becomes redundant, only adding extra code
Solution without final:
I'm afraid you will have to forget about the immutability mechanism of C++. The factory pattern is never a bad choice if you have huge data objects (i.e. with a lot of setters), but you can't really avoid mutability of the constructed object. What you could do, is make the data object an inner class of the factory, and make the setters private. That way, ONLY the factory can access the setters. This would be the best approach for you (i.e. simulate immutability).
Example:
public class Factory
{
private String name;
private String payload;
public Factory setName(final String name)
{
this.name = name;
}
public Factory setPayload(final String payload)
{
this.payload = payload;
}
public DataObject build()
{
DataObject newObj = new DataObject();
newObj.setName( this.name );
newObj.setPayload( this.payload );
return newObj;
}
public class DataObject
{
// fields and setters, ALL PRIVATE
}
}
You can either put the object class and factory in the same package, and make the mutable methods package-scoped (this is the default visibility in Java, simply don't declare the methods to be public, private or protected), or make the class truly immutable and do all the work in the constructor. If you find that there are too many arguments in the constructor and it is difficult to understand, consider the Builder Pattern.
There is no direct equal to friend classes in Java. However have a look at http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html.
If your object implements an interface and the factory returns interface type rather than the concrete type (which is better) then you can use java.lang.reflect.Proxy to create dynamic proxy at runtime that intercepts all method calls to the target object. As in the following code example FooFactory class creates a Foo instance (every time its createFoo method is called) but does not directly return instance but instead returns a dynamic proxy that implements the same interface as Foo and dynamic proxy intercepts and delegates all method calls to the Foo instance. This mechanism can be helpful to control access to a class when you dont have class code.
public class FooFactory {
public static IF createFoo() {
//Create Foo instance
Foo target = new Foo(); // Implements interface IF
//Create a dynamic proxy that intercepts method calls to the Foo instance
IF fooProxy = (IF) Proxy.newProxyInstance(IF.class.getClassLoader(),
new Class[] { IF.class }, new IFInvocationHandler(target));
return fooProxy;
}
}
class IFInvocationHandler implements InvocationHandler {
private Foo foo;
IFInvocationHandler(Foo foo) {
this.foo = foo;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().equals("setMethod")) {
// Block call
throw new IllegalAccessException();
} else {
// Allow call
method.invoke(proxy, args);
}
return null;
}
}
class Foo implements IF {
public void setMethod() {
} // method that is not allowed to call
public void getMethod() {
}
}
interface IF {
void setMethod(); // method that is not allowed to call
void getMethod(); // method that is allowed to call
}
The closest thing to a C++ friend class in Java is package-private access.
SomeObject.java:
package somewhere.someobjandfriends;
public class SomeObject {
Object aField; // field and constructor
SomeObject() {} // are package-only access
public void aMethod() {
System.out.println(this);
}
}
SomeObjFactory.java:
package somewhere.someobjandfriends;
public class SomeObjFactory {
public SomeObject newHelloWorld() {
return new SomeObject() {
{
aField = "hello world!";
}
#Override
public String toString() {
return aField.toString();
}
};
}
}
Anywhere outside of the package can see SomeObject and aMethod but can only create new instances through the factory.
I am trying to wrap my head around interfaces, and I was hoping they were the answer to my question.
I have made plugins and mods for different games, and sometimes classes have onUpdate or onTick or other methods that are overridable.
If I make an interface with a method, and I make other classes which implement the method, and I make instances of the classes, then how can I call that method from all the objects at once?
You'll be looking at the Observer pattern or something similar. The gist of it is this: somewhere you have to keep a list (ArrayList suffices) of type "your interface". Each time a new object is created, add it to this list. Afterwards you can perform a loop on the list and call the method on every object in it.
I'll edit in a moment with a code example.
public interface IMyInterface {
void DoSomething();
}
public class MyClass : IMyInterface {
public void DoSomething() {
Console.WriteLine("I'm inside MyClass");
}
}
public class AnotherClass : IMyInterface {
public void DoSomething() {
Console.WriteLine("I'm inside AnotherClass");
}
}
public class StartUp {
private ICollection<IMyInterface> _interfaces = new Collection<IMyInterface>();
private static void Main(string[] args) {
new StartUp();
}
public StartUp() {
AddToWatchlist(new AnotherClass());
AddToWatchlist(new MyClass());
AddToWatchlist(new MyClass());
AddToWatchlist(new AnotherClass());
Notify();
Console.ReadKey();
}
private void AddToWatchlist(IMyInterface obj) {
_interfaces.Add(obj);
}
private void Notify() {
foreach (var myInterface in _interfaces) {
myInterface.DoSomething();
}
}
}
Output:
I'm inside AnotherClass
I'm inside MyClass
I'm inside MyClass
I'm inside AnotherClass
Edit: I just realized you tagged it as Java. This is written in C#, but there is no real difference other than the use of ArrayList instead of Collection.
An interface defines a service contract. In simple terms, it defines what can you do with a class.
For example, let's use a simple interface called ICount. It defines a count method, so every class implementing it will have to provide an implementation.
public interface ICount {
public int count();
}
Any class implementing ICount, should override the method and give it a behaviour:
public class Counter1 implements ICount {
//Fields, Getters, Setters
#Overide
public int count() {
//I don't wanna count, so I return 4.
return 4;
}
}
On the other hand, Counter2 has a different oppinion of what should count do:
public class Counter2 implements ICount {
int counter; //Default initialization to 0
//Fields, Getters, Setters
#Overide
public int count() {
return ++count;
}
}
Now, you have two classes implementing the same interface, so, how do you treat them equally? Simple, by using the first common class/interface they share: ICount.
ICount count1 = new Counter1();
ICount count2 = new Counter2();
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(count1);
counterList.add(count2);
Or, if you want to save some lines of code:
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(new Counter1());
counterList.add(new Counter2());
Now, counterList contains two objects of different type but with the same interface in common(ICounter) in a list containing objects that implement that interface. You can iterave over them and invoke the method count. Counter1 will return 0 while Counter2 will return a result based on how many times did you invoke count:
for(ICount current : counterList)
System.out.println(current.count());
You can't call a method from all the objects that happen to implement a certain interface at once. You wouldn't want that anyways. You can, however, use polymorphism to refer to all these objects by the interface name. For example, with
interface A { }
class B implements A { }
class C implements A { }
You can write
A b = new B();
A c = new C();
Interfaces don't work that way. They act like some kind of mask that several classes can use. For instance:
public interface Data {
public void doSomething();
}
public class SomeDataStructure implements Data {
public void doSomething()
{
// do something
}
}
public static void main(String[] args) {
Data mydataobject = new SomeDataStructure();
}
This uses the Data 'mask' that several classes can use and have certain functionality, but you can use different classes to actually implement that very functionality.
The crux would be to have a list that stores every time a class that implements the interface is instantiated. This list would have to be available at a level different that the interface and the class that implements it. In other words, the class that orchestrates or controls would have the list.
An interface is a contract that leaves the implementation to the classes that implements the interface. Classes implement the interface abide by that contract and implement the methods and not override them.
Taking the interface to be
public interface Model {
public void onUpdate();
public void onClick();
}
public class plugin implements Model {
#Override
public void onUpdate() {
System.out.println("Pluging updating");
}
#Override
public void onClick() {
System.out.println("Pluging doing click action");
}
}
Your controller class would be the one to instantiate and control the action
public class Controller {
public static void orchestrate(){
List<Model> modelList = new ArrayList<Model>();
Model pluginOne = new plugin();
Model plugTwo = new plugin();
modelList.add(pluginOne);
modelList.add(plugTwo);
for(Model model:modelList){
model.onUpdate();
model.onClick();
}
}
}
You can have another implementation called pluginTwo, instantiate it, add it to the list and call the methods specified by the interface on it.
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}
If we have class A & B, and class A's constructor is private, and we want to use an instance of A in B, how to do that ? I see an answer that says "provide a static method or variable that allows access to an instance created from within the class " but I didn't understand that.
The code pattern you seek is called the Factory Method.
The class provides a static method that returns an instance of its own class. Private constructors are visible to all methods (including static ones) of the class, so the static method can invoke the private constructor on the caller's behalf.
Here's an example of this pattern in action:
public class A {
private A() {
}
public static A create() {
return new A();
}
}
This is often employed in conjunction with the Singleton Pattern, which would change the above example to this:
public class A {
private static A INSTANCE = new A();
private A() {
}
public static A getInstance() {
return INSTANCE;
}
}
A needs to have a public method that provides an instance of the class A, eg:
class A {
/*Constructors and other methods omitted*/
public static A getInstance() {
return new A();
}
}
Alternatively, if B is an inner class of A (or vice-versa), then B can directly reference the constructor eg:
public class A {
private A() {}
public static class B {
private A instanceOfA = new A();
public B() {}
}
}
A class that only has private constructors is designed so that other classes cannot instantiate it directly. Presumably there is a sound reason for this. The class may provide a factory method for instantiating the class ... or getting an existing instance of the class.
If you need to change the design, the best way is to modify the class; e.g. by making a constructor visible, or by adding a factory method. If you can't do that, I think it is possible to use reflection to break the visibility rules and create an instance using a private constructor. However, I'd only do this as a last resort ... and not before carefully analysing the consequences for the overall application.
Private constructors are intended to make a class not to have any instance. But the content can be accessed from child class using super(). Implementation is like this:
public class ClassA {
private int val;
private ClassA(int val)
{
this.val = val;
}
public int getVal() {
return val;
}
}
public class ClassB extends ClassA {
public ClassB(int val) {
super(val); } }
...
ClassB b = new ClassB(4);
System.out.println("value of b: " + b.getVal());
As an example see class Calendar. To get an instance you must not call its constructor but use a static method:
Calendar rightNow = Calendar.getInstance();
source
public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??
You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members
Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass
Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.
I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}
Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}