Circular Dependency in java- Design - java

How to prevent circular dependency, any design patterns??,otherwise it will cause stack overflow.
I was asked to redesign this.
class A {
static void method(){
B.method();
}
public static void main(String args[]){
method();
}
}
class B {
static void method(){
A.method();
}
}

This is not just circular dependency, this is an infinite recursion.
You will have to define an exit branch in either A.method() or in B.method(), for example:
class B{
static void method(){
if (someCondition) {
return;
}
A.method();
}
}
someCondition is calculated based on the business problem that is solved with this recursion (you know what it is).

At it's current state this is a will recur infinitely since there is no base case defined.
You would need to define atleast one of the methods with a conditional statement in order to make it break out after some state.
static void method(condition){
A.method();
}

Related

What does double initialization mean in Java methods

I only use double initialization in java for classes
ex:new ArrayList(){{add()}}
But I recently wrote a code as below by mistake and JVM did not get angry for my mistake.
public void test(){
{
{
....
}
}
}
After that made a simple example and saw the following but still didn' t understand anything expect order of running statements.
public class HelloWorld{
public static void main(String []args){
HelloWorld hw=new HelloWorld();
hw.test1();
System.out.println("----------");
hw.test2();
}
public void test1(){
{
{
System.out.println("1");
}
System.out.println("2");
}
System.out.println("3");
}
public void test2(){
System.out.println("a");
{
System.out.println("b");
{
System.out.println("c");
}
}
}
}
Result:
1
2
3
----------
a
b
c
So my question is that what does double or triple etc initializations mean in Java?
This is not double brace initilization. This is a block statement. From the docs:
A block is a group of zero or more statements between balanced braces and can be used anywhere a single statement is allowed.
A block statement encloses the statements within it in a different scope. So if you did:
public static int foo() {
{
int foo = 0;
}
return foo;
}
foo would not be in scope in the line return foo; and you would get an error
In your code, these nested blocks make no difference, as you are just printing, but each block will have a different scope

How to solve the fragile base class with helper methods

I have understood the fragile Base class problem, and I know that we can solve it using Composition over Inheritance or declaring private method in the superclass.
Now I'm trying to understand how to solve this problem using helper method, so I will put the classic code of fragile base class and then I will put my solution with helper method, tell me if I do something wrong please.
This is the code of a fragile base class (from wikipedia)
public class JavaApplicationProvaHello {
public class A {
private int i;
public void inc1(){
i++;
}
public void inc2(){
inc1();
}
}
//---------------------------
public class B extends A{
#Override
public void inc1(){
inc2();
}
}
//------------------------
public class Test{
public static void main(String[] args) {
B b = new B();
b.inc1();
}
}
}
Now I change the class A and put two private helper methods which will be called by the public method inc1 and inc2
public class A {
protected int i;
public void inc1(){
inc1Helper();
}
public void inc2(){
inc2Helper();
}
private void inc1Helper(){
i++;
}
private void inc2Helper(){
inc1Helper();
}
}
In my compiler everything works, I was asking myself if this is the best solution to solve fragile base class with helper methods. Thank you for the attention.
"Best" is an opinion.
In my opinion, a better answer would be to leave a Javadoc comment on inc2() stating that it calls inc1().
/** Increments <code>i</code> by calling <code>inc1()</code> */
public void inc2()
...
Then anyone who extends A can see that in the documentation. If they miss it, then they will know when they look at the stack trace for their stack overflow exception.
This way still requires a few lines in the file but requires no more actual lines of functional logic code and no more generated byte code. The very Wikipedia article you mention suggests (and for Java, nonetheless) documentation as one of the answers.

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.

AspectJ: pointcut after completed object initialization

I want to add an advice that runs for each object created from a set of classes (in my case, from a specific package) after initialization is complete. Consider this code:
public class Test {
public static void main(String[] args) {
new A();
new A(0);
new B();
new B(0);
new B(false);
}
}
class A {
public A() {
}
public A(int i) {
this();
}
}
class B extends A {
public B() {
}
public B(int i) {
this();
}
public B(boolean b) {
super(0);
}
}
for example, for new B(false), the advise should run after public B(boolean), but not after public A(int) of after public A(). Also note that I don't want to advise the constructor calls in main(); if objects are constructed from a 3rd party application that's not compiled with my aspect, the advise should still be there, i.e. the constructors themselves should be advised.
I thought this should work using some !cflowbelow() expression, but I had no luck. The closest I got is this:
after() : initialization(pkg.*.new(..))
&& !cflowbelow(withincode(pkg.*.new(..)))
&& !within(MyAspect) {
System.out.println(thisJoinPointStaticPart);
}
which gives this output:
initialization(test.A())
initialization(test.A(int))
initialization(test.A())
initialization(test.B())
initialization(test.A())
initialization(test.B(int))
initialization(test.A(int))
initialization(test.B(boolean))
i.e. this() executions are ignored correctly, but super() executions are not. Also, I fear this will ignore things like public B() {new A();} or similar, because new A(); is in a pkg.*.new(..) cflowbelow...
I can't imagine this isn't a use case that's useful over and over, but I didn't find any resources on it. An example where full initialization is necessary would be when logging newly created objects, but the toString() method uses the object's state. Advising anything else but the "subclass-most" constructor will yield in a log containing uninitialized values, and advising constructor calls will, as I said, not work with third party code (or code from a different package in my example).
For extra internet-cookies, how would I select the bottom-most (non-Object or other non-unadvised-superclass) constructor for injectting pre-initialization code?

What is the difference between ClassName.m() and (new ClassName()).m() m() is a static method

What is the difference between ClassName.m() and (new ClassName()).m() m() is a static method.
The difference is that in your second example you are creating an unnecessary object in memory.
It is still calling the same static method for the ClassName class.
It is recommended to use ClassName.m() to avoid unnecessary object creation and to provide context to the developers indicating that a static method is indeed being called.
Three things:
The second has an extra call, which means it might change the outcome. This may be bad, may not, but it is something to consider. See example on how this can work.
The second creates an extra object. That's bad.
The second implies you're calling a method on an object, not on the class itself, which confuses people who read it. That's also bad. See example for how this can be very bad!
Consider the following, reason 1:
class ClassName {
static int nextId;
static int m() { return nextId; }
int id;
ClassName() { id = nextId; nextId++; }
/**
C:\junk>java ClassName
2
2
3
*/
public static void main(String[] args) {
new ClassName();
new ClassName();
System.out.println(ClassName.m());
System.out.println(ClassName.m());
System.out.println((new ClassName()).m());
}
}
Consider the following, adding on to reason 2, as alluded to by #emory:
class ClassName {
// perhaps ClassName has some caching mechanism?
static final List<ClassName> badStructure = new LinkedList<ClassName>();
ClassName() {
// Note this also gives outside threads access to this object
// before it is fully constructed! Generally bad...
badStructure.add(this);
}
public static void main(String[] args) {
ClassName c1 = new ClassName(); // create a ClassName object
c1 = null; // normally it would get GC'd but a ref exist in badStructure! :-(
}
}
Consider the following, reason 3:
class BadSleep implements Runnable {
int i = 0;
public void run() {
while(true) {
i++;
}
}
public static void main(String[] args) throws Exception {
Thread t = new Thread(new BadSleep());
t.start();
// okay t is running - let's pause it for a second
t.sleep(1000); // oh snap! Doesn't pause t, it pauses main! Ugh!
}
}
From an external observer's perspective, there's no difference. Both ways result in a call to the method which can only do the exact same thing in either case. You should never do the second one, though, as it just doesn't make sense to create an object in that case.
If m() is a static method, it's generally correct practice to use ClassName.m() since m() is a method of ClassName, not an object of ClassName.

Categories

Resources