I am working on an API which interface with a proprietary piece of hardware. In this API, I have constructed a utility class (for the sake of this post let's call it B), consisting of only static methods. Most of these methods depend on another class for communicating with the hardware, let's call this A. I am currently a little unsure how to design the dependency of B on A as I cannot instantiate B and inject the dependency using constructor injection. From a design perspective, what is the best way to model this behavior?
For a little more hands-on description, here is what I am trying to achieve. Let's say A has declarations of certain other classes like so
class A
{
private HardwareCommunicator communicator;
private ModelLoader modelLoader;
public HardwareCommunicator getCommunicator()
{
return communicator;
}
public ModelLoader getModelLoader()
{
return modelLoader;
}
}
And B then has static methods like so, which seek to use some of the members declared in A
class B
{
public static PerformOperation()
{
AnotherClass c = new AnotherClass();
c.someMethod(someValue, hardwareCommunicator.getCommunicator()); // Needs reference
}
}
Obviously, B needs a reference to A, so I am currently fiddling with passing the dependency as an argument to the method, like this:
class B
{
public static PerformOperation(HardwareCommunicator communicator) // Passed as argument
{
AnotherClass c = new AnotherClass();
c.someMethod(someValue, communicator.doSomething()); // OK, so far so good
}
}
Now I run into the problem that I sometimes need more dependecies than just the communicator in B, e.g. in another static method in B I might need both the HardwareCommunicator and the ModelLoader
class B
{
public static SomeOtherOperation(HardwareCommunicator communicator)
{
AnotherClass c = new AnotherClass();
c.SomeMethod(someValue, communicator.doSomething(),
ModelLoader.getModelLoader()); // Missing reference
}
}
OK, so I could just pass this as a parameter as well, but now I am thinking I have an architectural problem. I should (shouldn't I?) be able to just go
class B
{
public static SomeOtherOperation()
{
AnotherClass c = new AnotherClass();
c.someMethod(someValue, instanceOfA.getCommunicator(),
instanceOfA.getModelLoader());
}
}
Without being able to call a constructor on B and pass in an instance of A I obviously can't achieve this behavior.
What am I missing? Thank you.
Related
I'm starting with developing something, and I have few classes that are using the same methods, so I want to have it in one class (to easy fixing in one place etc). Problem is that I dont know how to use methods from different classes on object in main class. Code for explanation:
public class A extends C {
public UiDevice device;
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
public void test(){
methodFromC();
}
}
public class B extends C {
public UiDevice device;
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
public void test(){
methodFromC();
}
}
public class C {
protected void methodFromC(){
device.something();
}
}
I know that I can do it by adding argument to methodFromC:
public class C {
protected void methodFromC(UiDevice device){
device.something();
}
and running it by
methodFromC(device);
But maybe is there better solution?
First of all, as a beginning programmer unless you are doing it for school, avoid extending classes. It ends up a big spaghetti mess until you learn to moderate it (I fell for this one big-time), What you are trying to do isn't good code right now.
I THINK what you are trying to do, however is something like this:
(Assume unspecified code remains pretty much as it is)
class A extends C
{
public UiDevice getDevice()
{
return device;
}
}
abstract class C
{
public abstract UiDevice getDevice();
public methodFromC()
{
getDevice().doSomethingToDevice();
}
}
This pattern allows you to access something from A in a parent class.
B can also have it's own device. I believe this is what you are after (C being able to operate on A's device or B's device depending on which one extended C).
Get rid of the public variable.
You can use the super keyword to access anything from the class you are extending. In your case :
public class B extends C {
public UiDevice device;
device = super.methodFromB();
public void test(){
methodFromB();
}
}
If many of your classes declare methods that do the same thing, you can make them inherit from one class, let's call it class A. In class declare and implement the method. Then in child classes declare methods and in their body write:
super.nameOfYourMethodFromParentClass();
In general, to use a method from different class you just create an object of the class and call a method on it. Like:
class A {
public void myMethod() {
B b = new B();
b.methodFromB();
}
}
When it comes to inheritance be aware of this:
You can create an object of a class that declares this method or of a class that inherits from the class that declares this method and call the method on this object.
Like:
Class A inherits from C. In class C you have method methodFromC() declared. To invoke method from class C on object from class A you can do:
A a = new A();
a.methodFromC(device);
The invoked method here is the method from class C.
But if in class A you override method from class C (that means in class A you declare a method that has the same name and parameters as method in class C), then by executing the code I have written above you will invoke the method from class A, not class C.
(With static and dynamic I mean the distinction whether code is susceptible to change)
I have a bit of a weird problem I'm currently stuck on. I'm writing an application which involves some complex interactions between components in which it becomes hard to keep track of the code flow. To simplify this, I'm trying to structure the code by creating 'layers', where each layer has increased functionality compared to the layer above it. Each layer is contained in a package. I'm having the following problem:
Consider the following 2 classes and their subclasses with increased functionality:
Class A:
package layer;
class A {
B b;
A() {
b = new B();
}
void foo() {
b.foo();
}
/* More A-class methods here */
}
Class B:
package layer;
class B {
void foo() {
// Do something
}
/* More B-class methods here */
}
Subclass A:
package sublayer;
class ASub extends A {
ASub() {
super.b = new BSub(); // This needs a cast to compile
}
}
Subclass B:
package sublayer;
class BSub extends B {
#Override
void foo() {
// Do something with more functionality
}
}
In the end I just want to instantiate and modify classes ASub and BSub, being able to use all methods of superclasses A and B without actually needing to modify code in classes A and B itself.
If I call new ASub().foo(), I want the overridden foo() of BSub to execute instead of that of B. Ofcourse I can add a variable BSub bsub in ASub and override A's foo() method to call bsub.foo(), but this doesnt avoid the creation of the object b in the constructor of A, which seems sloppy coding. Any thoughts on this? Any comments are welcome.
Your question is a bit controversial. Object creation and dependency injection is the subject of a lot of discussion and a core focus of various frameworks and design patterns.
But here is, I hope, one simple answer to your question, which isn't a general "what's the best way to create objects in Java?"
In the code below, I move the responsibility of instantiating B to a method (instantiateB()) which is called from the A (superclass) constructor. So, when you want to subclass A, you override that method instead of overriding the constructor.
package com.matt.tester;
public class SE {
static class A {
B b;
A() {
instantiateB();
}
void instantiateB () {
this.b = new B();
}
void foo() {
b.foo();
}
/* More A-class methods here */
}
static class B {
void foo() {
System.out.println("Hellow from B.foo()!");
}
/* More B-class methods here */
}
static class ASub extends A {
#Override
void instantiateB() {
this.b = new BSub();
}
}
static class BSub extends B {
#Override
void foo() {
System.out.println("Hellow from BSub.foo()!");
}
}
public static void main(String[] args) {
A a = new ASub();
a.foo();
}
}
Using inheritance to promote reusability is a really really bad idea. The inheritance should be always driven by the nature of the objects that you are trying to describe. You need to learn yourself to work with terms and abstractions to ask yourself "What is the nature of what I am trying to describe". My suggestion is to learn a book on Domain Driven Design for example or Code Complete. Also think about polymorphism and design patterns.
Suppose that I have two classes A and B and I want to make it so that instances of B can only be created in A and in B itself. I don't want any other class (including subclasses of A) to be allowed to create instances of B. Is there any way of doing this in Java?
Here is a bit of code if it's not clear what I am trying to do:
public class A {
B instance;
public A(){
// Still allows for subclasses to access B
instance = B.getInstance((Object)this);
}
}
Here is the class whose construction I want to limit:
public class B {
// If I make this public all classes can create it, but
// if I make it private without any getter methods then
// no other classes but itself can create it
private B(){}
// Problem with this is that subclasses of A
// can also create instances of B
public static B getInstance(Object o){
if(o instanceof A)
return new B();
else
return null;
}
}
I have tried Googling and searching on StackOverflow for possible solutions, but the closest thing that I have found is using a Singleton design pattern with a modified getInstance() method to make sure only a class with a particular type can have access to instances of class B. While this works fairly well, it still enables any subclass which extends A to get instances of B. Is there any way to stop this from occurring or would it ruin the whole point of subclassing if a subclass couldn't do what its superclass could do?
Suppose that I have two classes A and B and I want to make it so that instances of B can only be created in A and in B itself. I don't want any other class (including subclasses of A) to be allowed to create instances of B.
You could make B a private inner class of the A class.
While this works fairly well, it still enables any subclass which
extends A to get instances of B. Is there any way to stop this from
occurring or would it ruin the whole point of subclassing if a
subclass couldn't do what its superclass could do?
If you don't want your class A to be subclassed, you can make class A final, or can have a private constructor for A. Although as suggested in previous answers,, its better to create private inner classes.
public final class A {
B instance;
public A(){
// Still allows for subclasses to access B
instance = B.getInstance((Object)this);
}
}
A can present something to B that only A can possess. For example
public class A
{
public static class Pass
{
private Pass(){}
Only A can create an A.Pass object. If such objects are only transmitted from A to B, nobody else can get a hold of them and pretend to be A.
public class B
{
public static B getInstance(A.Pass token)
{
if(pass==null)
throw ...
else
caller must be A
This class will throw an exception if creating class is not B
class A {
A() {
new SecurityManager() {
{
if (getClassContext()[1] != B.class) {
throw new IllegalStateException();
}
}
};
}
...
you cannot break it even with reflection
I have a superclass that I would like to forward a static method called getInstance() to all subclasses.
When creating an instance of a subclass, I then register the instance in the superclass (perhaps using a hashtable, where the key is based on getClass()). Then, I wish to use the aforementioned static method ( getInstance ) where the superclass method will return the instance of the correct type.
For example, I have a superclass A, and a subclass B extends A.
I want to write a static method A.getInstance(); when called from B (B.getInstance()), I would like it to return the instance of B that I stored earlier.
Its kinda hard to explain, but I am going to be using this superclass a lot, and I would rather not code a getInstance method into every single subclass.
How would I go about doing something like this?
edit: I just realized that my question may be misconstrued as creating a NEW instance of the object. I have already created the instance, and i wish to get the existing instance of the class
As many others have noted in the comments, what you are trying to do is not possible with static methods. Also, you should try to avoid static methods whenever possible because they can result in a testing and maintanance nightmare (*).
You named your method "getInstance", so I guess what you want to do is a mix of Factory- and Singleton patterns. Here is some information to get you started about these patterns:
Singleton: http://en.wikipedia.org/wiki/Singleton_pattern
Factory Method: http://en.wikipedia.org/wiki/Factory_method_pattern
Abstract Factory: http://en.wikipedia.org/wiki/Abstract_factory
Both should not be coded by hand in these days (*) - Have a look at a good "Dependency Injection" (DI) container like Google Guice or Spring. I am not 100% sure what exactly you want to achieve, but it looks like a DI container will do it for you.
Edit: This is a response to an edit of the question. You want to receive a cached instance of the sub classes. In this case, I would still advise against static methods. You could create a singleton instance of a "BCache" class (using a DI container or programming it by hand), and then use this cache object to look up your registered objects. Using Guice as a DI container, it could look like this (warning, untested):
#Singleton
public class BCache {
private Map<Class<? extends B>, B> cache = ...;
public <T> T getInstance(Class<? extends T> type) {
return (T) cache.get(type);
}
}
I still think it would be possible to get rid of the cache class completely using a DI container, though. Again, this is untested code, using Guice, but it could look like this:
#Singleton
public class A extends B {
public A() {
//I am not sure if you need to register in this case, because your
//DI container keeps track of the singleton instances.
super.register(this);
}
}
public class SomeClassUsingA {
#Inject private A a;
}
(*) Note that "all generalizations are wrong", that is, in some projects it might make sense, but in most it will not.
You can't do exactly what you want with the static methods, in good OOP way. You can can do something with the reflection or bunch of if .. else if.
You however, should use some well defined design patterns like Abstract fectory or Factory method. This is the way you should go, like someone said "Don't invent warm water".
You can always assign a subClass instance to a superClass reference. Therefore your superClass's static methods can set or get a subClass instance. But make sure to cast the returned instance before using.
public class A {
private static A a;
/**
* #param a the a to set
*/
public static void setA(A a) {
A.a = a;
}
/**
* #return the a
*/
public static A getA() {
return a;
}
public class B extends A {
private int index = 0;
/**
* #param index the index to set
*/
public void setIndex(int index) {
this.index = index;
}
/**
* #return the index
*/
public int getIndex() {
return index;
}
Usage:
public static void main(String[] args) throws Exception {
B b = new B();
A.setA(b);
B c = (B) A.getA();
System.out.println(c.getIndex());
}
Change form getInstance() to getInstance(String class)
in the superclass:
public static A getInstance(String class){
if(class.equals("A")){
RegisterObject(...);//User defined method
return new A(...);
}
else if(class.equals("B")){
RegisterObject(...);//User defined method
return new B(...);
}
else if(class.equals("C")){
RegisterObject(...);//User defined method
return new C(...);
}
//... and so on
}
Static methods are cannot know which class is used to invoke them. If for example you have class A and B that extends A and static getInstance() implemented in A there is no difference whether you invoke getInstance() using A or B. Moreover attempt to call B.getIntance() will produce compilation warning (at least in Eclipse).
However you can pass the class as a parameter of getInstance():
public class A {
public static <T extends A> T getInstance(Class<T> clazz) {
return clazz.newInstance(); // I do not catch exceptions here: do it yourself
}
}
public class B extends A {
}
...............
B b = A.getInstance(B.class);
You can do like this way,
class A{
public static A getInstance(){
return new A();
}
#Override
public String toString() {
return "inside A";
}
}
class B extends A{
public static A getInstance(){
return new B();
}
#Override
public String toString() {
return "inside B";
}
}
inside main :
public static void main(String[] args) {
A a1 = A.getInstance();
A a2 = B.getInstance();
System.out.println(a1.toString());
System.out.println(a2.toString());
}
Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO