Java Application return super class when initialized - java

Nowadays we are on writing some core application that is all other application will be relying on. Without further due let me explain the logic with some codes,
We used to have a single java file that was 1000+ lines long and each application was having it as class inside, so when there was a change, each application had to edit the java file inside of it or simply fix one and copy to all. This is hard to implement as much as it is hard to maintain. Then we end-up with creating this as a separate application that is divided to smaller part, which is easy to maintain and also a core maybe a dependency to other application so we fix in one place and all other code applications are fixed too.
I've been thinking for a some great structure for this for a while want to use a builder patter for this as below
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
The problem arises now. Like so, I initialized the object but now I'm having access to that objects public class only. This application actually will have many small classes that has public functions that I don't want them to be static methods that can be called everytime. Instead I want those methods to be called only if TheCore class is initilized like;
// doSomething() will be from another class
theCore.doSomething()
There are some ideas I produced like
someOtherClass.doSomething(theCore)
which is injecting the main object as a parameter but still someOtherClass needs to be initialized or even a static method which doesn't make me feel comfortable and right way to that.
Actually I do not care if initializing TheCore would bring me a super object that includes all other classes inside initialized and ready to be accessed after I initialized TheCore. All I want in this structure to have a maintainable separate app and methods avaiable if only the main object which is TheCore is this circumstances is initialized.
What is to right way to achive it? I see that Java does not allow extending multiple classes even it if does, I'm not sure it that is right way...
Thanks.

After spending significant amount of time of thought I ended up that
// doSomething() will be from another class
theCore.doSomething()
is not suitable since many java classes could possibly have identical method names. So...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
would be a better approach.
To make it easier to understand I'll have to follow a complex path to explain it which is starting from the package classes first.
Think that I have a package named Tools and a class inside SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
Now this SomeFancyTool.java must have a default access level which is actually package level access, because I don't want this classes to be accessed directly;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
So now we have the SomeFancyTool.java class but TheCore.java cannot access it since it is accesible through its Tools package only. At this point I think of an Initializer class that is gonna be in the same package, initialize these private classes and return them with a function when called. So initiliazer class would look like this;
ToolsInitializer.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
Since ToolsInitializer.java can initialize all functional private classes inside in Tools package and also can return them as objects to outside of the package scope, still we are not able to use these methods as we cannot import com.<domainName>.SomeFancyTool from TheCore.java because it is package wide accessible. I think here we can benefit from implementation of the java interface. A class that is not functional alone, so no problem even if it is accessed since it's methods will be nothing but declarations.
At this point I'll rename SomeFancyTool.java to SomeFancyToolImplementation.java which it will be implementing the interface and call SomeFancyTool.java to the interface itself.
SomeFancyTool.java (now as an interface)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
and lets rename prior SomeFancyTool.java and implement the interface
SomeFancyToolImplementation.java (renamed)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
#override
public String someStringMethod(){
return "Some string!";
}
#override
public int someIntMethod(){
return 123;
}
#override
public boolean someBooleanMethod(){
return true;
}
}
Now our structure has become like this with the final edits;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
Finally we can use our TheCore.java class to call all initializer classes with their methods to receive all these private classes inside as an object. This will allow external apps to call and initialize TheCore first to be able to access other methods.
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
All Done and it is ready to use. Now the functional package classes and its methods that it relying on if TheCore is initialized or not, cannot be accessed with out TheCore. And simple usage of this Library from a 3rd Party app would simply be;
3rd Party App
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
Note: Note that a the ToolsInitializer.java is still accessible and could be used the get private method without first calling TheCore but we can always set a checker inside getSomeFancyTool() method to throw error if some prerequisites are not satisfied.
I do not still know if this is a functional structural pattern to use or its just some hard thoughts of mine. And don't know if some pattern is already exist that I just could not see yet but this is the solution I end up with.

Related

Java: make static methods of one class mirror instance methods of another class

I have a POJO like this:
public class Foo {
private String bar1;
private String bar2;
//...
public String getBar1() { return bar1; }
public void setBar1(String bar1) { this.bar1 = bar1; }
public String getBar2() { return bar2; }
public void setBar2(String bar2) { this.bar2 = bar2; }
//...
}
As an alternative to Java reflection (which is quite slow in general), I would like to define a class with static methods like this:
public class FooStatic {
public static String getBar1(Foo foo) { return foo.getBar1(); }
public static void setBar1(Foo foo, String bar1) { foo.setBar1(bar1); }
public static String getBar2(Foo foo) { return foo.getBar2(); }
public static void setBar2(Foo foo, String bar2) { foo.setBar2(bar2); }
//...
}
which enforces the creation/deprecation of a static method every time the Foo class is updated. For example, if the field bar2 is deleted in FooStatic, then the static methods getBar2() and setBar2() in FooStatic should be identified by the compiler to be removed. If a new variable bar3 is added to Foo with getters and setters, the compiler should enforce the creation of new static methods getBar3() and setBar3() in FooStatic. Moreover, I have multiple POJOs, and would like a solution which scales. Is this possible?
Yes... sort of. It's very complicated.
Annotation Processors are compiler plugins that run at certain times during the compilation process. It gets complex fast - IDEs and build tools are 'incremental' (they don't want to recompile your entire code base everytime you change a single character, of course), for example.
Annotation processors can do a few things:
They can run as part of the compilation processes. This can be done automatically - they just need to be on the classpath, is all
They can be triggered due to the presence of an annotation.
They can read the signatures of existing files (the names of fields and methods, the parameter names, parameter types, return type, and throws clause, and the type of fields, and the extends and implements clauses, and the param names and types of the constructors). They can't read the body content (initializing expressions, method and constructor bodies). But I think you just need the signatures here.
They can make new files. They can even make new java files which will then automatically get compiled along with the rest.
Thus, you have a route here: Make an annotation, then make an annotation processor. For example, you could set it up so that you manually write:
#com.foo.Hossmeister.Singletonify
class Example {
void foo1() {}
String foo2(String arg) throws IOException {}
}
and have an Annotation Processor (which also has that com.foo.Hossmeister.Singletonify annotation), which, if it is on the classpath, automatically generates and ensures that all other code can automatically see this file:
// Generated
class ExampleSingleton {
private ExampleSingleton() {}
private static final Example INSTANCE = new Example();
public void foo1() {
INSTANCE.foo1();
}
public static String foo2(String arg) throws IOException {
return INSTANCE.foo2(arg);
}
}
But, annotation processors are tricky beasts to write, and they can be quite a drag on the compilation process. Still, that's the only way to get what you want. Now you have something to search the web for / read up on :)
You start by making a separate project that defines the annotation, has the annotation processor (a class that extends AbstractProcessor), pack that into a jar, and make sure the manifest includes an SPI file that tells java that your class that extends AbstractProcessor is an annotation processor, and then it'll be picked up automatically. I'll give you the annotation definition:
In a file named Singletonify.java:
#Retention(RetentionPolicy.CLASS)
#Target(ElementType.TYPE)
public #interface Singletonify {}
But... wait!
The concept of singletons is often problematic. Singletons should be 'stateless' - and if they are stateless, why isn't your Foo class just filled with entirely static methods, obviating the need for your "static mirror class"? If it is stateful, you now have global state which is a virtually universally decried anti-pattern. You don't want global state, it makes reasoning about control flow impossible.
A second problem is testability - because static stuff doesn't 'do' inheritance, you can't (easily) make test implementations of static methods. With non-static stuff this is much easier.
This problem is more generally solved by so-called Dependency Injection frameworks such as Dagger, Guice, or Spring. They let you write code that just 'gets' an instance of your Foo class, without callers having to actually figure out where to get this instance from: The Dependency Injection framework takes care of it. It lets you do things like "Have a singleton of this object... per web session". Which is pretty powerful stuff.
I think what you probably want is a DI system. You may want to investigate a bit before spending the 2 weeks writing that annotation processor.

How these codes work (Constructor And ListView)

I was following the udemy android app development course, In the course, we were writing code to Create A listview and get some data when the user clicks on the list, to do that the teacher uses a thing called Constructor I know how constructors work theoretically but can't understand the way it works in code. It will be great if someone can explain what these lines of codes do.
edit: Full Code is here https://github.com/atilsamancioglu/A14-LandmarkBook
import android.graphics.Bitmap;
public class Globals {
private static Globals instance;
private Bitmap chosenImage;
private Globals(){
}
public void setData(Bitmap chosenImage){
this.chosenImage=chosenImage;
}
public Bitmap getData(){
return this.chosenImage;
}
public static Globals getInstance() {
if(instance==null){
instance = new Globals();
}
return instance;
}
}
Constructors are special methods invoked when an object is created and are used to initialize them.
A constructor can be used to provide initial values for object attributes.
You can think of constructors as methods that will set up your class by default, so you don’t need to repeat the same code every time.
In your codes, you can define the constructor as below(it may be unrelated, it's just an example):
private Globals(int id){
return chosenImage.setId(id);
}
The constructor is called when you create an object using the new keyword:
Globals objectGlobe = new Globals(000008);
Also a single class can have multiple constructors with different numbers of parameters.
The setter methods inside the constructors can be used to set the attribute values.
It's not bad to be mentioned that; Java automatically provides a default constructor, so all classes have a constructor, whether one is specifically defined or not.

How is this interface being instantiated?

This is from the Minecraft server source code, also called the Minecraft Bukkit API, now you know as much as I do.
There is an interface called Server:
public interface Server extends PluginMessegeRecipient {
public String getVersion();
}
PluginMessageRecipient is an interface also.
There is a class called Bukkit that instantiates Server:
public final class Bukkit {
private static Server server;
}
Inside methods in the Bucket class they invoke methods from the server object. For example:
server.getVersion();
The thing is, there is no code for getVersion in the Server interface, just a method signature. There is also no code in the PluginMessageRecipient interface nor does it extend anything.
I have read all the questions and answers on SO that say I need an anonymous class or an inner class and this does not seem to fit those solutions.
There is a class called Bucket that instantiates Server:
Actually Bucket doesn't instantiate Server. The class Bucket contains a reference to a Server. You haven't shown how that got set so we don't know the actual class.
However, it is guaranteed that what is assigned to that reference (Bucket.server), assuming it's not null, is a an object of some concrete class that implements Server. That class will provide an implementation of getVersion() and that is what is being called.
Bukkit is just a Modding API. If you want to implement Bukkit, you need to create such an instance yourself and pass it there.
Take for example the unit tests that Bukkit includes:
https://github.com/Bukkit/Bukkit/blob/f210234e59275330f83b994e199c76f6abd41ee7/src/test/java/org/bukkit/TestServer.java#L77
A real implementation that allows you to run a Bukkit server is Spigot.
If I recall correctly, the particular concrete class that's being selected is determined at runtime via reflection. Because Minecraft is not open source, all the developers have are the obfuscated compiled class files to work with.
The code searches through each class file within the minecraft jar, searching for a class that matches certain conditions, and then, using a bytecode library, force that class to implement that interface.
For example, let's say that the following (obfuscated) class was the real Server class within the Minecraft code
class a {
String x_x317() {
return q_q98;
}
static a a_a1;
static String q_q98 = "1.9.4";
}
In this case, the method x_x317 returns the version string. The tool that allows them too hook into this class might do it based on the following conditions:
The class has default access
The class has only one default access static reference to itself
The class has only one default access static String field.
The class has a single method, that has default access, that returns String, and the returned value is the FieldRef found in 3.
This generally returns only one class. In the case that multiple are returned (usually in the dev phase of the new Bukkit version), they get more specific with their conditions to ensure that they only get the right class returned. They do this for every field, class, and method they need to identify.
Since they now know which exact class is the Server class, they can go ahead and make changes to it. First they would need to implement the interface
class a implements org.bukkit.Server
And then implement the method
class a implements org.bukkit.Server {
String x_x317() {
return q_q98;
}
public String getVersionNumber() {
return x_x317();
}
static a a_a1;
static String q_q98 = "1.9.4";
}
Now, we have a class that conforms to the Bukkit API.
When they need to instantiate that class, they just do something along the lines of
Server server = findAndTransformServerClassFromMinecraftJar();
// ...
Server findAndTransformServerClassFromMinecraftJar() {
// load classes from jar
// map them to the appropriate interfaces
// transform and hook the required classes and methods
Class<?> serverClass = doTheFirstThreeSteps();
return (Server) serverClass.newInstance();
}

Why can't I assign an Scala Object to a Java variable?

I have this monolithic Java-Application that I want to port to newer techniques and I want to apply Scala wherever it makes sense.
Now I translated a rather huge java-singleton class implementation to a Scala object.
In another class I used to do this (JAVA):
public class MyOtherClass
{
protected MyClass myClass;
public MyOtherClass()
{
myClass = MyClass.getInstance();
}
}
Now I'd like to do the following:
public class MyOtherClass
{
protected MySCALAClass myClass;
public MyOtherClass()
{
myClass = MySCALAClass$.MODULE$;
}
}
But this doesn't work. It says:
Required MyScalaClass, Found MyScalaClass$
I also tried to create a small function
def getInstance() = this
but of course this yields the same problem.
Any ideas? I have searched this topic and I see how it is not a problem if you just want to call the methods of the object, but I would need to rewrite many, many calls to the "myClass"-object to even test this.
edit: I'm fully aware that I could rename every call to "myClass" to "MySCALAClass", but that is no real fix, just a workaround and it is tedious for a big project.
I think #neuronaut 's comment is correct.
See following questions:
Scala object MODULE$
Singletons as Synthetic classes in Scala?
The singleton class (MySCALAClass$ in your case) is not a subclass of the original class (MySCALAClass) and so the singleton object (MySCALAClass$.MODULE$) is not an instance of it either.

Doing an API, constructor for system private use only and another official, javadoc'ed and public to use. Advise on fix / pattern approach

I guess this is a bad pattern, whats the best approach to fix it?
I mean I would like everybody using a constructor with 2 arguments,but I need to leave default constructor because its implementing a listener which classloads it without args. I would like to hide default constructor to anyone else but the listener handler which uses it, and make the other the unique point to instantiate.
Is there any kind of annotation? any privacy modifier for certain classes (system caller one is not in the same package)?
This seems fine to me. You would do the same thing if you want to instantiate a class differently during unit testing.
Oh, I see you need a constructor that has more access than protected but less than public. Unfortunately that's not possible.
You could put both your class MyClass and the listener MyListener that needs to use the empty constructor in the same package. Then, set the access of the empty constructor to package-level:
package com.stackoverflow.foo;
public class MyClass {
MyClass () { // package-private (no explicit access modifier)
}
public MyClass(int a, int b) { // public
}
}
package com.stackoverflow.foo;
public class MyListener {
private MyClass ref = new MyClass(); // MyListener is on the same package as MyClass, so this is valid
}
This way, you ensure that only classes that are on the same package as MyClass can use the default constructor.

Categories

Resources