I'm wondering what is the best/correct way to access methods from other classes in java.
I'll show how I'm doing it right now.
Sometimes like this:
public class DriverManager {
private final SeleniumDriverManager seleniumDriverManager;
public DriverManager() {
this.seleniumDriverManager = new SeleniumDriverManager();
}
public void startDriver() {
seleniumDriverManager.startWebDriver();
}
public void quitDriver() {
seleniumDriverManager.quitWebDriver();
}
}
and sometime like this
public class DriverManager {
private final SeleniumDriverManager seleniumDriverManager = new SeleniumDriverManager()
public void startDriver() {
seleniumDriverManager.startWebDriver();
}
public void quitDriver() {
seleniumDriverManager.quitWebDriver();
}
}
It's working in both cases, but is there any difference? Should I follow 1st or 2nd approach
There is no difference.
In the first one, seleniumDriverManager is initialized directly in the constructor via this.seleniumDriverManager = new SeleniumDriverManager();.
In the second one, seleniumDriverManager is initialized when the (generated) default no-arg constructor is called (similar to what happens in the first case).
Nevertheless, the best approach could be different:
public class DriverManager {
private final SeleniumDriverManager seleniumDriverManager;
public DriverManager(SeleniumDriverManager seleniumDriverManager) {
this.seleniumDriverManager = seleniumDriverManager;
}
public void startDriver() {
seleniumDriverManager.startWebDriver();
}
public void quitDriver() {
seleniumDriverManager.quitWebDriver();
}
}
In this case, you actually request the seleniumDriverManager to be passed in the constructor as an argument. This is one of the bases of Dependency Injection which relies on this approach of "asking" instead of (silently) providing. Dependency injection is actually the foundation of Frameworks such as Spring and has a huge amount of advantages. Still, this really depends on our use case, but keep this option in mind ;)
Related
I facing a real hard problem in my code snippet.
I want to learn how to use Interface in Java the correct way.
So for this I have my Application-Class...
package inversionUsage;
public class Application {
public static void main(String [] args) {
String standard = "Standard version!";
if (FeatureDecisions.checkEnabledFeatures("new-feature1")) {
System.out.println("Implement new feature...");
}else {
System.out.println(standard);
}
}
}
Then I made a Interface...
package inversionUsage;
public interface AppConfiguration {
boolean isEnabled(String searchFeature);
}
I want to use the Interface in another class:
package inversionUsage;
import java.util.Arrays;
public class FeatureDecisions implements AppConfiguration{
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public static boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
if (Arrays.asList(_implNewFeature).contains(searchFeature)) {
return true;
}else {
return false;
}
}
private String [] fetchFeatureTogglesFromSomehere() {
// TODO get the CONFIG from somewhere
enabledFeatures = new String [2];
enabledFeatures[0] = "new-feature1";
enabledFeatures[1] = "new-feature2";
return enabledFeatures;
}
}
So the workflow is:
1. I start the Application
2. Main method checks the enabled features via FeatureDecisions.java
3. In Feature Decisions i implemented the Interface
I getting the error:
Cannot make a static reference to the non-static method isEnabled(String) from the type FeatureDecisions
May Someone can help me out?
The only way to use an instance method is to have an instance on which to call it. Your checkEnabledFeatures is static, so it doesn't receive an instance you can use (as this). To use an instance method, it would need to create an instance. But obviously that's not what you want here.
Java's interface construct is for defining the interface that instances implement. Java doesn't have the concept of a "static interface" that a class must implement. On the rare occasions when that's needed, it's usually implemented using reflection (perhaps with a class-level annotation to indicate that the class has the necessary feature).
You would have to instantiate the FeatureDecisions class.
public static boolean checkEnabledFeatures(String searchFeature) {
return new FeatureDecisions().isEnabled(searchFeature);
}
or make all members static.
Additional info: There are frameworks like togglz that do this for you.
There's no way to do that. The closest can get is to use the singleton pattern (though lots of people - myself included - would discourage it).
public enum FeatureDecisions implements AppConfiguration
{
INSTANCE;
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
//...
}
}
Your call would then change from:
FeatureDecisions.checkEnabledFeatures(...)
to
FeatureDecisions.INSTANCE.checkEnabledFeatures(...)
It's also worth noting that checkEnabledFeatures doesn't actually do anything besides defer to isEnabled. You could scrap the former and just call the latter directly.
There are several (5+) classes, in code I cannot change, that I need to extend by a few fields. Is there any way to do this without writing (and editing every time I need to change something) the almost exactly same code 5 times? So is there any more elegant way than this:
class Subclass1 extends Superclass1 {
private String newField;
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
class Subclass2 extends Superclass2 {
private String newField;
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
//...
I do NOT want multiple inheritance, I want 5 seperate subclasses - just without the duplicate code, because the subclasses all add exactly the same.
The only alternative I can think of is copying the original classes and having the copy extend a Superclass which is probably even worse.
No, you can't do this in Java. You can in certain other JVM-based languages, such as Scala (traits). However, if you must use plain Java, you might consider the following:
Determine the (hopefully single) purpose of the fields you are adding, and the behavior that you want.
Create a new class encompassing all of the fields and the new methods. For example:
public class ExtraFields // Don't use this name!
{
private String myExtraField1;
private String myExtraField2;
// etc.
public void doSomethingWithExtraFields() {
// etc.
}
}
Then, you could take one of the following approaches:
Subclass each of the five classes, and add one field, which is an instance of the class you created above, and delegate behavior accordingly. You will have to use this approach if you must have the extra fields in places where you must pass in one of your five classes. For example:
public class Subclass1 extends Superclass1
{
private ExtraFields extraFields;
public MySubclass()
{
super();
extraFields = new ExtraFields();
}
public void doSomethingWithExtraFields()
{
extraFields.doSomethingWithExtraFields();
}
}
Create a new wrapper class that contains an instance of both your new class created above, and one of those five subclasses. You can make this typesafe using generics. For example:
public class Wrapper<T> // Don't use this name either...
{
private ExtraFields extraFields;
private T myClass;
public Wrapper(T myClass) {
this.myClass = myClass;
this.extraFields = new ExtraFields();
}
}
In this second approach, you don't strictly need the ExtraFields class. But it's still often a good idea to do this so as to encapsulate related functionality.
Hope that helps!
Since you can't change the base classes, it's impossible to eliminate the redundancy. Eric Galluzzo's idea to store the extra fields in a separate class is the best one so far, but I don't know if that's practical in your case. If it isn't, create an interface that defines the extra fields. You'll still have to do a lot of repetitive typing, but at least you'll know immediately when you've made a mistake.
You could use a generic wrapper class, as long as it wouldn't be too tedious to change the rest of the code that works with it.
class Wrapper<E> {
private E obj;
private String newField;
public Wrapper (E obj) {
this.obj = obj;
}
public E get() {
return obj;
}
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
I have a class with a method that takes a single parameter. This parameter is a nested class inside the mocked class, but it is private (And static but I don't think that makes much of a difference to this). How do I go about mocking this method?
Example:
public class myClass {
public anotherObject;
public myClass(AnotherObject anotherObject) {
this.anotherObject = anotherObject;
}
public void exec() {
//Some instructions ...
//This second method is inside another completely seperate class.
anotherObject.secondMethod(new NestedClass());
}
private static class NestedClass {
public NestedClass() {
//Constructor
}
//Variables and methods, you get the picture
}
}
In the above example secondMethod(...) is the method that I want to mock.
All attempts to find other examples of this problem just return results relating to mocking a single private nested class, or mocking static classes, which aren't completely relevant to this and don't seem to provide any work around that I can figure out.
EDIT:
I'm looking for some sort of solution that looks like this:
#Test
public void testExec() {
AnotherObject anotherObject = mock(AnotherObject.class);
when(anotherObject.secondMethod(any(NestedClass.class))).thenReturn(0);
MyClass testThisClass = new MyClass(anotherObject);
}
Notes: I'm not allowed to make modifications to the code I'm afraid, I am only allowed to create these tests to make sure the current implementation works later down the line when modification are made to it.
If I am understanding the requirement correctly, add one method say executeSecondMethod(). Call this method in your main method class.
public class myClass {
public void exec() {
//Some instructions ...
secondMethod(new NestedClass());
}
public void secondMethod(NestedClass example) {
//Some instructions that I want to just mock out...
}
private static class NestedClass {
//Variables and methods, you get the picture
}
public static executeSecondMethod(){
secondMethod(new NestedClass()); // pass the nested class object here
}
}
public class mainClass{
public static void main(){
executeSecondMethod();
}
}
The main reasons I like passing in runtime dependencys in constructors are:
It makes the dependency required
It provides a central place to set instance variables
Setting the dependency as an instance variable prevents you from
having to pass it around from method to method within the class or pass it in twice or more
to two or more public methods
This has led me to use a lot of Assisted Injects when using Guice. This creates extra code compared to not using DI so reading things like this:
How exactly is Assisted-inject suppose to be use to be useful?
It seems like most people don't pass the runtime(derived, not available at startup) dependencies in constructors using assisted inject, and instead pass them in individual methods. Thats fine for the simple class given in the above stackoverflow post where there is only one method that relies on the dependency:
public class SomeClass {
#Inject
SomeClass(...) {
...
}
public void doWork(int s) { /* use s */ ... }
}
But what if the class has many methods that use the dependency? Do you pass it from the public method to private methods and require it passed in on all public methods?
For example:
public class SomeClass {
#Inject
SomeClass(...) {
...
}
public void doWork(int s) {
/*some code */
someOtherMethod(s);
anotherMethod(s);
}
//any private method that needs it gets it passed in as a param
private void someOtherMethod(int s)...
private void anotherMethod(int s)...
//require it passed in all public methods that need it
public void anotherPublic(int s){
someOtherMethod(s);
}
}
As opposed to using constructors this adds a bit of extra code as seen here:
public class SomeClass {
private int s;
SomeClass(int s) {
this.s = s;
}
public void doWork() {
someOtherMethod();
anotherMethod();
}
private void someOtherMethod()...
private void anotherMethod()...
public void anotherPublic(){}
}
Or would you set the instance var from the service method like this?
public class SomeClass {
Integer s;
#Inject
SomeClass(...) {
...
}
public void doWork(Integer s) {
/***set instance var this time***/
this.s = s;
someOtherMethod();
anotherMethod();
}
private void someOtherMethod()...
private void anotherMethod()...
public void anotherPublicMethod(){
if(s==null){ //check if s was set already
throw new IllegalStateException();
}else{
/* do something else */
}
}
}
Or would you pass the dependency into the other public method as a param and set the instance var there as well? For Example:
public class SomeClass {
#Inject
SomeClass(...) {
...
}
public void doWork(Integer s) {
/***set instance var this time***/
this.s = s;
someOtherMethod();
anotherMethod();
}
private void someOtherMethod()...
private void anotherMethod()...
public void anotherPublicMethod(Integer s){
this.s = s;
/* do something else */
}
}
So I think passing the param from method to method or throwing illegal state exceptions to check for it isn't ideal compared to using normal constructors, but obviously there are advantages/disadvantages to any framework/pattern.
If I am just not separating my objects in the ideal way, please let me know some guidelines you use, ie "I only use one public method per service class, see this book or post about it:.." .
What do you guys do in the above situations?
You nailed down some great reasons to use assisted injection in your question: It ensures that the object instances only ever exist in a fully-initialized state, keeps your dependencies together, and frees the object's public interface from requiring a predictable parameter in every method.
I don't really have any alternatives to add, other than the ones you mentioned:
Adding a setter method for that dependency, probably requiring IllegalStateException checks or a good default value
Creating an initialize(int s) pseudoconstructor method with the same IllegalStateException checks
Taking in the parameter in individual methods
Replacing the FactoryModuleBuilder boilerplate with a custom factory, thereby creating more extra boilerplate you're trying to avoid
My favorites are the two you seem to be deciding between--assisted injection or taking the parameter in every method--mostly because they both keep the object in a predictable, usable state at all times. My decision between them rests on what kind of state the object should carry, whether that state is mutable, and how I want to control instances. For Car.licensePlateNumber, the license plate number may vary with the car instance; each car has one license plate number that (in this example) never varies, and the car isn't valid without it, so it should be a constructor argument. Conversely, Repository<T> may frequently take in the same T instance in all of its methods, but a Repository is still a Repository no matter which instance you pass in, and you may want the freedom to reuse that instance without creating a new one for each T (as you may have to do with assisted injection). Both designs are valid, and each one is optimal for a certain set of cases.
Remember that there shouldn't really be that much extra code required for assisted injection:
/** In module: install(new FactoryModuleBuilder().build(SomeClass.Factory.class)); */
public class SomeClass {
public interface Factory {
SomeClass create(int s);
}
private final int s;
#Inject
SomeClass(/* ..., */ #Assisted int s) {
this.s = s;
}
public void doWork() { /* ... */ }
}
There's a problem I can't solve. I have simple part of code here:
public class Item{
Block blockDrop;
public void setBlockDrop(Block block) {
this.blockDrop = block;
}
}
public class Block{
Item itemDrop;
public void setItemDrop(Item item) {
this.itemDrop = item;
}
}
public class ItemDirt extends Item {
public ItemDirt() {
setBlockDrop(Registry.blockDirt);
}
}
public class BlockDirt extends Block {
public BlockDirt() {
setItemDrop(Registry.itemDirt);
}
}
public class Registry {
public static ItemDirt itemDirt = new ItemDirt();
public static BlockDirt blockDirt = new BlockDirt();
}
When I run this, blockDirt WILL drop itemDirt, but itemDirt WON'T drop blockDirt. Is there any way I can solve this? I could instead add to Registry constructor:
itemDirt.setBlockDrop(blockDirt);
blockDirt.setItemDrop(itemDirt);
but that defeats whole simplicity of my objects.
The problem is that when ItemDirt is constructed and assigned to Registry.itemDirt, its constructor already uses Registry.blockDirt, although it has not been initialized and is still null at that point of time.
This is a typcial problem that happens when objects try to prematurely grab alien objects at construction time. Usually, a constructor should never 'reach' outside and grab other objects that may or may not exist at that point of time.
There seems to be no pretty way to break your vicious circle without some visible alterations to your code, but maybe something like this will be less ugly:
public class Registry() {
public static ItemDirt itemDirt;
public static BlockDirt blockDirt;
static {
itemDirt = new ItemDirt();
blockDirt = new BlockDirt();
itemDirt.setBlockDrop(blockDirt);
}
}
Or some lazy initializations in your set methods. Your call.
It looks like you're trying to implement something similar to the Mediator Pattern, but the real way to do this is not in the constructor, because you cannot be assured of the order of construction.
Instead, when you implement a business method, you call a Mediator, which then handles the inter-class communication. Please read up on the Mediator Pattern before you go further, as it will provide some insight on how to do this better.