Constructor best practices
Asked Answered
R

3

6

Lets say we have a class with only 1 function, eg: compute DFS. Which of the following is preferred approach and why ?

Approach 1:

public class DFS {

    public DFS(Graph g) {
      dfs(g);  // <--- computation invoked from constructor.
    }

    private void DFS(Graph g) {
       // do dfs traversal
    }
}

Client:
DFS dfs = new DFS(graph);


Approach 2:
public class DFS {
    Graph g;
    public DFS(Graph g) {
       this.g = g
    }

    private void doDFS() {
       // do dfs traversal
    }
}

Client:
DFS dfs = new DFS(graph);
dfs.doDFS();
Renell answered 5/8, 2013 at 2:16 Comment(1)
How is a result going to be passed to the caller? Does the traversal have side effects?Freedwoman
T
7

The latter. The convention is that the constructor creates a blank object that is ready to do work, not an object that immediately begins to work.

Although both will function, the former is unclear.

Tasteful answered 5/8, 2013 at 2:23 Comment(0)
J
9

Constructors are meant to initialize the data fields in the object. Given the choices, the second approach seems more correct.

Although what might be better is to include the doDFS method in your graph object. It's usually bad practice to create an entire class for a single simple function. The doDFS method is specific to the graphs it works with, so including it in whatever graph class you have is natural.

Jittery answered 5/8, 2013 at 2:22 Comment(1)
I also choice second one as if you use IOC and dependency Injection later, the pattern will be like second one.Commute
T
7

The latter. The convention is that the constructor creates a blank object that is ready to do work, not an object that immediately begins to work.

Although both will function, the former is unclear.

Tasteful answered 5/8, 2013 at 2:23 Comment(0)
A
0

The answers are correct. I want to add a more convenient approach that is a best practice for this.

If there are two processes, one Construction and one Initialization, it is better not to add an unclarity to the instantiation. With 2nd approach, the user needs to run doDFS() right after instantiation (they should know that somehow! maybe commenting, maybe wiki, manual, etc)

But it can be super clear if we use the Static Factory Method here like this:

public class DFS {
    Graph g;

    private DFS(Graph g) { // Private DFS
        this.g = g
    }

    private void doDFS() { // Private doDFS
       // do dfs traversal
    }

    public static DFS createDFS(){
        Graph g = new DFS();
        g.doDFS();
        return g;
    }

}

Using this approach, the user is forced to do the following:

Graph g = Graph.createDFS();
Ant answered 21/12, 2023 at 10:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.