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

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.

Related

Accessing multiple nested static objects

I want to create a set of classes that allows me to write records
What I want to achieve is this
Record.write.field1();
Record.write.field2();
My understanding is that I can create multiple static nested objects but I'm struggling with it
I created the following
public abstract class Record{
public Write write;
}
public abstract class Write{
public static void field1();
}
The approach above hasn't helped me achieve that.
The questions I have is
Can I write a set of classes in a way so I can achieve the following pattern
Record.write.field1();
Record.write.field2();
This is so that I can scale it up when needing to add additional field
If I can, is this a good approach?
If I can't, what's the best approach?
Thank you
UPDATE: I can do Record.write but can't do Record.write.field15();
public class Record {
public static Write write;
}
public class Write {
public static void field15(){
System.out.println("Hello");
}
}
This allows you to write the code the way you want:
class Record {
public static Write write = new Write();
}
class Write {
public void field15(){
System.out.println("Hello");
}
}
public class Main {
public static void main(String[] args) {
Record.write.field15(); // prints "Hello"
}
}
Note that static methods are invoked on the class name, and instance methods are invoked on a specific instance value.

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.

Reflection VS static stuff

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.

Shadowing variable used in a default method of an interface in Java 8

Today I was thinking about a nice way to write less code for a common functionality that is required for different objects.
Inheritance can do the job but then the classes won't be able to inherit from anyone else, so I chose Interfaces.
So I have my interface with the functionality I will need for some objects:
public interface Test {
String message = "Hello from Interface!";
default void printMessage() {
System.out.println(message);
}
}
And then I can use it in any object without having to override/write any code more than just simply calling the method when needed:
public class TestingTest implements Test {
public String message = "Hello from Class!";
public TestingTest() {
printMessage();
}
public static void main(String[] args) {
new TestingTest();
}
}
It works like a charm! But... Then I thought, what if I want some of those objects to specify a different message without being required (optional), well first thing I thought was to shadow the interface variable, but it doesn't work, the default method keeps using the variable from the interface instead of the class variable (which shadowed it).
A solution of course would be to overload the printMessage method in the interface so it recieves the message as a parameter for when the user requires to specify the message, but is there any more elegant way? Something like simply just declaring a new message in the class?
The String message in the interface is static (AFAIK). So that scheme does not work.
You might do something (ugly) as:
default void printMessage(String... messages) {
if (messages.length == 0) {
messages = new String[] { "arrgg" };
}
System.out.println(messages[0]);
}
Fields have no inheritance, so the value can only stem from an overridable method like
public String message() { return "..."; }
What you want is a functionality in n classes that should also be modifiable, if needed.
To be honest, your example is a little bit abstract and thus my answer will be abstract, too.
public interface Test {
void printMessage();
default void printMessage(String message) {
System.out.println(message);
}
}
public class TestingTest {
private final test;
public TestingTest(Test test) {
this.test = test;
}
public void someMethod() {
test.printMessage("Hello from class");
}
}
Additionally, you would have a class that implements the interface and offers the message. This way you could group your objects, change the message, make more complex logging and you would actually see the dependency from outside.
In my opinion, you are misusing the interface. An interface offers public methods to call it from outside, but you want to use them inside like they were private functionalities for the class.
Just use objects instead.

Java Passing in Type as Function Parameter

I come from a Python background and in Python you can pass in the type of an object as a parameter. But in Java you cannot do this, any tips on how to get something like this working?
private void function(Type TypeGoesHere)
Stock s = new TypeGoesHere();
s.analyze();
}
Java does not support Python’s way of referencing functions and classes. To achieve this behaviour, you have to use two advanced techniques: generics and reflection. Explaining these concepts is beyond the scope of a SO answer. You should read a Java guide to learn about them.
Yet here is an example how this would look like, assuming that the given class has a no-argument constructor:
public <T extends Stock> void analyzeNewStock(Class<T> clazz) throws Exception {
Stock s = clazz.newInstance();
s.analyze();
}
Then call this function with analyzeNewStock(MyStock.class).
As this is a rather complicated and error-prone approach, you’d rather define an interface that creates Stock instances:
public interface StockProvider {
Stock createStock(String value);
}
public class MyStockProvider implements StockProvider {
private final String valueTwo;
public MyStockProvider(String valueTwo) {
this.valueTwo = valueTwo;
}
#Override
public Stock createStock(String valueOne) {
return new MyStock(valueOne, valueTwo);
}
}
public class MyOtherClass {
public void analyzeNewStock(StockProvider provider) {
provider.createStock("Hi!").analyze();
}
public static void main(String[] args) {
analyzeNewStock(new MyStockProvider("Hey!"));
}
}
In Java you can pass a Class. You can do it like this:
private void function(Class c)
This is not very common procatice though. You can probably get wha you need by looking into Strategy pattern, or proper use of Object Oriented Programming (polymorphism).
If you are looking for a way to build some objects, look into Factory pattern.
If you want to create a generic class- look into this detailed answer: https://stackoverflow.com/a/1090488/1611957
You could use generics. For example:
private <T> void function(Class<T> clazz) {
try{
T t = clazz.newInstance();
//more code here
}catch(InstantiationException | IllegalAccessException ex){
ex.printStackTrace();
}
}
The Class<T> clazz shows what type to instantiate. The try/catch is just to prevent errors from stopping your code. The same idea is expanded in this SO post. More info here.
However, I'm not really sure why you would want to do this. There should easily be a workaround using a simple interface. Since you already know that you want an object with type Stock, you could pass an implementation of the interface. For example:
//interface to implement
public interface Stock {
public void analyze();
}
//rewrite of function
private void function(Stock s){
s.analyze();
}
And using two ways to call function:
//first way
public class XYZ implements Stock{
public void analyze(){
//some code here
}
}
//calling the function
function(new XYZ());
//second way
function(new Stock(){
public void analyze(){
//your code here
}
});

Categories

Resources