Reflection VS static stuff - java

Recently I've been restructuring a Java code of mines trying to eliminate, wherever possible, static stuff (variables and methods) and replace it with better coding practices.
I also started studying reflection and noticed that it allows me to do some things1 that, at first, I could only achieve (or, at least, that's how I see it) with static calls or references.
However, while I've been reading that the use of static is not much recommended, it doesn't seem to be the same with reflection.
So, I'm asking: instead of making a method static and calling it like ClassName.methodName(), is it a legitimate use of reflection making it an instance method and invoking it by java.lang.reflect.Method.invoke()?
1 like dynamically accessing a class' content
Here's a code sample:
Hypothetic situation that works (but I don't want to make the method static):
import static java.lang.System.out;
public class Foo
{
private static boolean light;
public Foo()
{
turnOn();
}
public static void turnOn()
{
light = true;
}
public static void turnOff()
{
light = false;
}
public static boolean isGreenLight()
{
return light;
}
}
public class Boo
{
public Boo()
{
if (Foo.isGreenLight()) // I need to access Foo.isGreenLight() from here, but cur-
{ // rently that method is not static (it should be to do so)
out.println("Ok!");
}
}
}
public final class Main
{
public static void main(String[] args)
{
final Boo boo = new Boo();
}
}
Hypothetic situation that also should work (how it'd be using reflection):
import static java.lang.System.out;
import java.lang.reflect.Method;
public class Foo
{
private boolean light;
public Foo()
{
turnOn();
}
public void turnOn()
{
this.light = true;
}
public void turnOff()
{
this.light = false;
}
public boolean isGreenLight()
{
return this.light;
}
}
public class Boo
{
public Boo()
{
if ((boolean) Class.forName("Foo").getMethod("isGreenLight", null).invoke(new Foo(), null))
{
out.println("Ok!");
}
}
}
public final class Main
{
public static void main(String[] args)
{
final Boo boo = new Boo();
}
}
Expected output (untested):
Ok!

Using reflection is a code smell, especially if the intent behind what you're writing does not warrant it.
It is difficult to say much more without seeing code as it's all just guesswork.
I would:
enumerate the reasons behind why you had those static members in the first place
determine if the static modifier was in fact the right decision in the first place: i.e. should these be instance or class members? How might they be used by "clients" of the classes in question? What paradigm am I using? Functional or Object Oriented code. Does it satisfy DRY, SOLID and KISS programming practices?
consider if I'm over-engineering in the first place
More importantly:
I would design my code through tests first, which drives the design of your API through the eye of the user, with the added benefit that you have test coverage before you've even implemented. Often times when writing code this way I eliminate such questions because the solution is more obvious when thought from the perspective of a user rather than a designer. It becomes a question of pragmatism rather than satisfying architectural design goals and philosophies.

Related

How can I avoid having to rely on an object of another class to make the methods in a different class work?

Maybe the title was confusing, so here's a snippet of what I'm trying to avoid:
public class Generator{
private static GUI userInterface;
public static boolean specialValidator(String specialEntryText)
{
if(entryValidator(specialEntryText))
{
int specialChars = Integer.parseInt(specialEntryText);
int maxPossible = Integer.parseInt(userInterface.getLength())-3;
if(specialChars < 1 || specialChars > maxPossible)
{
return false;
}
return true;
}
return false;
}
public static void main(String[] args) {
userInterface = new GUI();
}
}
My program runs and functions as intended (keep in mind there is more to it than this), but I don't know if what I've done here is considered bad practice or what the downsides of doing it this way are. If my main method was not in the Generator class, this would not work, which seems like a problem to me.
Also, is there a specific name for what I did here, too?
The main method is the entry point of the program, and it needs to be in a class. It does not need to be in the Generator class.
As long as there is access to the class that you want to use, you can call it from another class. In you case it is public so it should be OK.
If it is in another class it could be something like
package yourPackage;
public class Main {
public static void main (String[] args) {
Generator gen = new Generator ();
//
gen.specialValidator(..);
}
}
Many things jump out at me.
There seems to be a dependency on GUI in specialValidator which is producing a "tight coupling" - you can't use the method without GUI.
This doesn't seem to make sense to me. You want to focus on reducing this coupling/dependency by passing all the required information into the method directly, for example...
public class Generator {
public static boolean specialValidator(String specialEntryText, int length) {
if (entryValidator(specialEntryText)) {
int specialChars = Integer.parseInt(specialEntryText);
// Any resason we're not using the specialEntryText length?
int maxPossible = length - 3;
if (specialChars < 1 || specialChars > maxPossible) {
return false;
}
return true;
}
return false;
}
}
Now specialValidator doesn't care "how" the information is generated, only that the information is made available to it. This "decouples" the method and makes it more independent, meaning you can call it any way you like (it also supports "dependence injection" making it more testable ๐Ÿ˜)
And now you can call it anyway you like, for example...
public class Main {
public static void main(String[] args) {
Generator.specialValidator("some text", 8);
}
}

can powermock be used to test static methods

I have the following two classes:
public class Prod
{
public void logon(){
System.out.println("'\u000CProd logon");
addUser();
}
public void addUser(){
System.out.println("Prod addUser");
}
}
public class Dev extends Prod
{
public void addUser(){
System.out.println("Dev addUser");
}
public static void main(String[] args){
Dev test = new Dev();
test.logon();
}
}
Is there a way to make all the methods static and then test whether the Dev.addUser() is working correctly?
Here's what I would like to be able to do:
public class Prod
{
public static void logon(){
System.out.println("'\u000CProd logon");
addUser();
}
public static void addUser(){
System.out.println("Prod addUser");
}
}
public class Dev extends Prod
{
public static void addUser(){
System.out.println("Dev addUser");
}
public static void main(String[] args){
logon();
}
}
When I run the main() in Dev we should get:
Prod logon
Dev addUser
Is there a way to make all the methods static and then test whether the Dev.addUser() is working correctly?
No, there isn't.
This is really fundamental Java: you want to use static methods in a polymorphic context. But static methods are not polymorphic. There is no true inheritance, there is no overwriting of static methods. See here for lengthy explanations why that is. Repeat: the desired output can't be achieved in a purely static way, built around class A extending class B. End of story.
And as already said: this is also wrong from a conceptual point. Because of such restrictions, static should only be used carefully in Java. Simply go with the non-static code you have right now.
Unfortunately your question isn't really clear what exactly you intend to test, therefore I can't help with that part.

Importing two utility classes with same name. Feature or useless?

For two utility classes with the same names, which contain only static methods, I proceeded as follows:
Simply imported the first
Created an instance of the second class.
Example:
package util1;
public class Utility {
public static void method() {
System.out.println("First Utility. static method");
}
}
package util2;
public class Utility {
public static void method() {
System.out.println("Second Utility. static method");
}
}
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = new util2.Utility();
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I don't need to write a full second util-class name for invoke its methods, but maybe I did not foresee something...?
P.S:
The methods of the class Component are called through a reflection by a certain BlackBox. All the multithread-safe features are in BlackBox.
UPD: I have found better trick:
import util1.Utility;
public class Component {
private static final util2.Utility anotherUtility = null; // There are some changes
public static void usedByReflection() {
Utility.method();
anotherUtility.method();
}
}
Now I dont create new object, but is it possible to use it without any bugs?
IMO, this is confusing and could much more clearly be handled by something like:
public class CombinedUtilityComponent {
public static void usedByReflection() {
util1.Utility.method();
util2.Utility.method();
}
}
Or, better yet, in your code you can just fully qualify the class names and they become unique names without any confusing tricks.
Yes, this works. I wouldn't do it, though.
You're calling a static method as if it were an instance method. anotherUtility.method() has a useless reference to anotherUtility.
You also have an unnecessary instantiation of util2.Utility. This technique wouldn't work if the default constructor were disabled.

Java: Using a class as an parameter to describe a setups

I couldn't think of a good way to name this. Basically I'm have a program where I want to have a default "pattern" almost I guess of how something should function. But I wanted to allow the use to create their own implementation (This is like an API) of the class and use that as a parameter instead, with the functionality inside. Is this the most efficient way to do it? If you don't understand that bad description here is an example.
public class SimpleStyle extends AbstractStyle {
public void personalizedImplementation() {
// manipulate the program this way
}
}
Then in the method
public static void do(Class<? extends AbstractSyle> style) {
// Use reflection in herre to get the implementation and do it
}
Is there a better and more efficient way to do something like this
You should not use reflection for this task if you can avoid it. It is less readable and more error-prone than well designed interfaces.
The basic solution (Iโ€™m not sure whether you already considered it) is to simply pass instances of AbstractStyle to your method:
public static void doSomething(AbstractStyle style) {
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyle());
}
If you cannot use this approach โ€“ this depends on the specific use case โ€“ you could define an additional interface that handles the creation of the AbstractStyle instance:
public interface StyleFactory {
AbstractStyle createStyle();
}
public class SimpleStyleFactory implements StyleFactory {
#Override
public SimpleStyle createStyle() {
return new SimpleStyle(/* ... */);
}
}
public static void doSomething(StyleFactory styleFactory) {
AbstractStyle style = styleFactory.createStyle();
style.personalizedImplementation();
}
public static void main(String[] args) {
do(new SimpleStyleFactory());
}
Note: do is a Java keyword, so it canโ€™t be used as an identifier. I used doSomething instead.

Encapsulating what doesn't vary?

It's a common practice to encapsulate code that often changes. In fact, it is often in the form of using an object to delegate the varying logic to. A sample would be the following:
public class SampleClass {
Object obj = new ObjectWithVaryingMethod();
public SampleClass(Object obj){
this.obj=obj;
}
public String getString(){
return obj.toString();
}
public static void main(String args[]){
SampleClass sampleClass=new SampleClass(new ObjectWithVaryingMethod());
System.out.println(sampleClass.getString());
}
}
class ObjectWithVaryingMethod{
#Override
public String toString(){
return "Hi";
}
}
Can you suggest what problems I may encounter when "encapsulation" is done on what doesn't vary? I find it to be a good coding conduct when the main class itself is the one that is often subject to change or improvement. A sample would be the following. In this second case, retrieving "Hi", which is the part that doesn't vary, was "encapsulated" in another class.
public class SampleVaryingClass {
public static void main(String args[]) {
//here I may opt to print getHi's value on sysout or on a dialog
System.out.println(ObjectWithNonVaryingMethod.getHi());
}
}
In a completely different class...
public class ObjectWithNonVaryingMethod {
private static final String hi = "Hi";
//"Hi" should always be returned
public static String getHi() {
return hi;
}
}
Can you give some pro's and con's on doing this?
Both code cannot be compared each other. One is static, another one isn't. I hope you understand the concept of encapsulating the object in the first code. Here is the pros and cons for the second one. Remember that static is "generally" bad, and do not support concurrency by default.
pros:
With getHi, you are keeping the string field private, meaning that it cannot be set from other source
Say that you need to do setHi from other source, you can add several guard clauses for it. This is called defensive programming.
public static setHi(String input){
if(input == null) { input = ""; } // can throw exception instead
hi = input;
}
cons:
It is static, needless to say
You don't get any advantage other than guard clauses. If your class is not static, you can swap it with other class implementing same interface, or other class inherited from that class.

Categories

Resources