Grouping together "main" methods and their "helper" methods in Java - java

Avoiding large, monolithic methods is considered a good practice. I, personally, like to identify all pieces of code that serve a unique, unambiguous purpose and refactor them into a method. This way, the code reads more like a book.
The obvious problem with this approach is that my class ends up having a large number of methods available outside their intended scope, which I find highly undesirable.
There are ways to create nested functions in Java, but since the feature is not directly supported by the language, the resulting code is generally unfathomably ugly --at least, to me.
One could also use nested classes. What I don't like about this solution is that it's somewhat clumsy --is it?-- when some of the involved methods in the "grouping together" are overridden methods.
Rather vague question, but anyway I'd like to know how people go about doing this.
EDIT: Example of what I mean:
public class ClassWithTwoMainMethods {
private int var1;
private int var2;
public void doSomething(int a) {
if (conditionToCheck(a)) {
doSomethingSpecific();
}
}
private void doSomethingSpecific() {
...
}
private boolean conditionToCheck(int a) {
...
}
public void doSomethingElse(int a, int b) {
doSomethingElseHelper1(a+b);
doSomethingElseHelper2();
doSomethingElseHelper3();
}
private void doSomethingElseHelper1(int arg) {
...
}
private void doSomethingElseHelper2() {
...
}
private void doSomethingElseHelper3() {
...
}
}
At first glance, it isn't obvious that the class above has one "main" method with two "helpers" that should not be used anywhere else, and another "main" method with three helpers.

I use "worker objects" for this. A worker object exists only inside of a method and helps to achieve a goal. A typical example for this is String except that this worker is so useful that methods often return it.
So what I do is I group methods in a worker object, create it in a public API method (i.e. something is supposed to be used and documented in the public API) and let it do it's thing:
public void doSomethingElse(int a, int b) {
new Worker( a, b ).run();
}
This approach has some benefits:
You can test those workers in isolation.
It keeps code together that belongs together
It helps to avoid cluttering the namespace of a class. It does pollute the global namespace somewhat, though.
It allows you to reuse workers in different classes.
I can lessen the restrictions on fields for workers. For main classes, I prefer fields that don't change. In workers, fields are often more like local variables. That way, I can reduce the number of method parameters but I need to write more unit tests.

Related

using instance initializer to deal with constructor overloading

A pattern I sometimes see is that a constructor might take either no argument or one argument. Now, I wonder whether the 'better' approach is to move common code to the most defined constructor - or to use the instance initializer in this case. For example, one way of always generating an ID for every class created:
public SomeClass(){
this("Hello");
}
public SomeClass(String s){
this.s = s;
this.id = generateId();
}
versus writing it like this:
{
this.id = generateId(); // method does not depend on the class
}
public SomeClass(){
this("Hello");
}
public SomeClass(String s){
this.s = s;
}
The reason for using the Instance Initializer would be because I want to always run the method when the class is created, and in the future someone else might change the class's constructors and forget to do this. Whilst it is less likely to remove the instance initializer (without realizing what you are doing).
But on the other hand, I am not sure how about readability in this case.
The examples are a bit contrived, not real-world examples.
The reason for using the Instance Initializer would be because I want
to always run the method when the class is created, and in the future
someone else might change the class's constructors and forget to do
this. Whilst it is less likely to remove the intance initializer
(without realising what you are doing).
Doing the one (using the Instance Initializer) or the other one (constructor) should not be used as trick to avoid coding error when the class is modified.
And anyway, why Initializer would give better insurance about it ?
You want to ensure that the constructor do what it designed to do ?
Writing an unit test that validates this behavior and that is automatically executed at each build.
That's all.
I think the reasonable solution here:
private final Whatever id = generateId();
In other words:
make sure the compiler knows that this should be initialized (so use final)
and instead of using an init block (rather uncommon) simply do initialize once, "in place"
I have never seen a use of instnace initializer in real life. (I actually did see it and played with it for a bit in one of theoretical questions on this site). In real life though you often can see a static initializer block:
public class Bla {
static {
//do something
}
....
}
As for common code what could be done is to have a method called init() that is called by all constructors. In your example it would look like
public SomeClass(){
this("Hello");
}
public SomeClass(String s){
init();
this.s = s;
}
private init() {
this.id = generateId(); // method does not depend on the class
}

What are the benefits of code blocks inside a method?

I've seen a method, which contains several blocks:
public class SomeClass {
public void someMethod() {
{
...
}
{
...
}
{
...
}
}
}
What are the benefits of such structure compared to the usual approach (put the code of each of the blocks into its own method and call them from someMethod) ?
What could be the reason the author of that source wrote it that way?
They can be useful for organising local variables:
{
List<String> someTemporaryThing = getTemporaryThing();
processTemporaryThing1(someTemporaryThing);
processTemporaryThing2(someTemporaryThing);
}
// other code that doesn't need to see someTemporaryThing
Of course, if you have more than a few lines in one of these it might be a good idea to make it a separate method.
I haven't found any other use for them.
This is legacy from C, where, originally, variables could be declared only at the start of a code block (i.e. right after a {).
In Java, it is only useful if, as you said already, you don't want to move the code in these blocks to separate methods, but want to keep their variables out of your method's scope. This could theoretically get some increase in performance compared to taking the stuff out to methods.

Understanding the Builder/Factory Pattern

I'm trying to clean up some code I have written for reading data. I have two sources of data: a database and a file. Both currently have separate classes and both classes have optional, non common, parameters in the constructors provided (at the moment traditional telescoping constructors).Both classes Implement interface MyData and when I instantiate the objects I always instantiate a MyData object.
I want to merge these classes into a single class and make the instantiation as clean as possible but I can't figure out how. Im certain its a mixture of builder and factory patterns.The user should never have to see the underlying type MyDatabaseData and MyFileData, just MyData. Can someone help me by sketching out a similar example just to set me off in the right direction
Keep the classes separate since they do different things. Combining them will only make a giant mess and violates the Single Responsibility Principle.
If you don't want the users to see the classes, then make the classes package private.
Then you make a new Builder or Factory class that takes parameters and figures out which class to instantiate.
Hope this helps.
A builder pattern would look like this:
MyDatabaseData data = MyDatabaseData.create()
.authenticate("admin", "rumpelstielchen")
.get();
public class MyDatabaseData {
private MyDatabaseData() { }
public static MyDatabaseBuilder create() {
return new MyDatabaseBuilder(new MyDatabaseData());
}
}
public class MyDatabaseBuilder {
private MyDatabaseData data;
MyDatabaseBuilder(MyDatabaseData data) {
this.data = data;
}
public MyDatabaseData get() {
return data; // Do checks and yield the final result
}
public MyDatabaseBuilder authenticate(String user, String password) {
...
return this; // For chaining calls
}
}
Whether to use common base classes/interfaces is a matter of suitability:
public class MyDatabaseBuilder extends MyBuilder<MyDatabaseData>
However you will probably need to do specific things and hence need child classes. Development not necessarily will become easier, maintaining 4 classes with parallel evolutions.

Java Constructor and static method

When should I use a constructor and when should I use static method?
Can you explain above with small snippet? I skimmed through a few threads but I'm still not clear with this.
Joshua Bloch advises to favor static factory methods instead of constructors (which I think is a good practice). Couple of advantages and disadvantages :
Advantages of static factory methods :
unlike constructors, they have names
unlike constructors, they are not required to create a new object each time they're invoked (you can cache instances : e.g. Boolean.valueOf(..)
unlike constructors, they can return an object of any subtype of their return type (great flexibility)
Disadvantages of static factory methods :
They are not really distiguishable from other static methods (it's hard to find out how to initialize an object if you are not familiar with the API)
The main disadvantage (if you use only static factory methods, and make constructors private) is that you cannot subclass that class.
Use a public constructor when you only ever want to return a new object that type and you want simplicity.
A good example is StringBuilder as it's mutable and you are likely to want a new object each time.
public String toString() {
StringBuilder sb = new StringBuilder();
// append fields to the sb
return sb.toString();
}
Use a static factor method when you might want to re-use objects (esp if immutable), you might want to return a sub-class or you want descriptice construction. A good example is EnumSet which has a number of static factories which do different things even though some have the same arguments.
EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);
In this case, using a static factory makes it clear what the difference between these two ways of construction the set.
Also EnumSet can return two different implementations, one optimised for enums with a small number of values (<= 64) RegularEnumSet and another for many values called JumboEnumSet
Always use a constructor if your class has a state (even for a single instance; singleton pattern ).
Only use static for utility methods like in java.lang.Math
Example:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
Doesn't change any state (instance variables) of an object, thus it can be declared static.
Use constructor when you need an object and other stuffs like functions and variables having one copy for every object.
when you want to do something without creating object then use static method.
Example:
public class Test {
public int value;
public static int staticValue;
public int getValue() {
return ++value;
}
public static int getStaticValue() {
return ++staticValue;
}
}
public class TestClass {
public static void main(String[] args) {
Test obj = new Test();
Test obj1 = new Test();
S.o.p(obj.getValue());
S.o.p(obj1.getValue));
S.o.p(Test.getStaticValue());
S.o.p(Test.getStaticValue());
}
}
Static factory methods have names, constructors don't. Thus factory methods can carry natural documentation about what they do that constructors can't. For example, see the factory methods in the Guava Libraries, like ImmutableMap.copyOf(otherMap). While this might have little effect on behaviour of construction, it has a huge effect on readability of the code. Definitely consider this if you're publishing an API.
Also you can use a factory when you need to do any more complicated configuration of the object you're creating, especially if you need to publish to other threads (registering in pools, exposing as an MBean, all manner of other things...) to avoid racy publication. (See e.g. Java Concurrency In Practice section 3.2)
Static methods that do something (e.g. Math.min) are not really the same thing as static factories, which can be considered direct replacements for constructors, with added flexibility, evolvability and (often) clarity.
Whenever you need to create an instance of an object you will have to use the constructor.
So, if you want to create a Car object, then you will need a constructor for that.
The keyword static means, that your method can be called without creating an instance.
class Car
{
private int num_of_seats;
public Car(int number_of_seats)
{
this.num_of_seats = number_of_seats;
}
// You want to get the name of the class that has to do with
// this class, but it's not bounded with any data of the class
// itself. So you don't need any instance of the class, and
// you can declare it as static.
static String getClassName()
{
return "[Car]";
}
}
In general you will use static class with data that are not correlated with the instance of the object.
Another example is:
class Ring
{
private List nodes;
public Ring(List nodes)
{
this.nodes = nodes;
}
// You want to calculate the distance of two ids on the ring, but
// you don't care about the ring. You care only about the ids.
// However, this functionality logical falls into the notion of
// the ring, that's why you put it here and you can declare it
// as static. That way you don't have to manage the instance of
// ring.
static double calculateDistance(int id_1, int id_2)
{
return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
}
}
As the posts above say, it's just a matter of what you want to do and how you want to do it. Also, don't try to understand everything rightaway, write some code then try different approaches of that code and try to understand what your code does. Examples are good, but you need to write and then understand what you did. I think it's the only way you will figure out
why you do staff the way you have to do.
Static methods do not have to instantiate new objects everytime. Since object instantiation is expensive it allows instances to be cached within the object. So, it can improve performance.
This is the explanation from the Effective Java :
This allows immutable classes (Item 15) to use preconstructed
instances, or to cache instances as they’re constructed, and dispense
them repeatedly to avoid creating unnecessary duplicate objects. The
Boolean.valueOf(boolean) method illustrates this technique: it never
creates an object. This technique is similar to the Flyweight pattern
[Gamma95, p. 195]. It can greatly improve performance if equivalent
objects are requested often, especially if they are expensive to
create.
i.e. if you want to use a singleton, which means that you have only one instance of the object, which might be shared with others, then you need a static method, which will internally will call the constructor. So, every time someone wants an instance of that object you will return always the same, thus you will consume memory only for one. You always need a constructor in object oriented programming, in every OO language. In java an in many other languages the default constructor of an object is implied, and built automatically. But you need some custom functionality you have to make your own.
Above you see a few good examples of the usage. However, if you have something specific in your mind, please let us know. I mean if you have a specific case where you are not sure if you should use a static method or a constructor. Anyhow, you will definitely need a constructor, but I am not sure about the static method.

Change private member to default for testing

Is that good idea to change private class members to default(package access) for testing their behavior? I mean test case should destinate in test directory but in same package as tested member's class.
EDIT: All you guys tell the true. But classes have helper private methods often. And these methods can be complicated so need to be tested. And that is too bad - to test public methods for ensure correct working for private complicated methods. Don't you think so?
I generally prefer writing my classes and tests in a way that writing the tests against the public API makes sense. So basically I'm saying if you need to access the private state of your class under test you're probably already too involved in the internals of that class with your test..
No, it isn't. Because changing the test object may change the result. If you really need to call private members or methods during test, it's safer to add an accessor. This still changes the class, but with a lower risk. Example:
private void method() { /* ... */ }
// For testing purpose only, remove for production
#Deprecated // just another way to create awareness ;)
void testMethod() {
method();
}
OK - one more solution, if you need to test private methods: you can call any method with reflection and instantiation API.
Assuming, we have:
public class SomeClass {
private Object helper(String s, String t) { /* ... +/ }
}
then we can test it like
#Test public void testHelper() {
try {
SomeClass some = new SomeClass();
Method helperMethod = some.getClass().getDeclaredMethod("helper", String.class, String,class);
helperMethod.setAccessible(true);
Object result = helperMethod.invoke(some, "s", "t");
// do some assert...
catch(Exception e) {
// TODO - proper exception handling
}
}
I understand what you mean about needing to test private methods, and I also see why people say only test the public methods. I have just encountered some legacy code that has a lot of private methods, some of which are called by public methods, but some are threads, or called by threads, which are kicked off when the object is constructed. Since the code is riddled with bugs and lacks any comments I am forced to test the private code.
I have used this method to address the issue.
MainObject.cs
class MainObject
{
protected int MethodOne(); // Should have been private.
....
}
TestMainObject.cs
class ExposeMainObject : MainObject
{
public int MethodOne();
}
class TestMainObject
{
public void TestOne()
{
}
}
Since the test objects aren't shipped I can't see a problem with it, but if there is please tell me.
Testing trumps privacy modifiers. Really, how often is a bug caused by having "a little too much" visibility for a method? Compared to bugs caused by a method that was not fully tested?
It would be nice if Java had a "friend" option, like C++. But a limitation in the language should never be an excuse for not testing something.
Michael Feathers chimes in on this debate in "Working Effectively with Legacy Code" (excellent book), and suggests that this may be a smell of a sub-class that wants to be extracted (and have public methods).
In our shop (~ 1M LOC), we replace 'private' with '/TestScope/' as an indicator that a method should be effectively private, but still testable.
Trying to circumvent 'private' with reflection is IMHO a smell. It's making the tests harder to write, read, and debug in order to retain a 'fetish' of privacy, which you're working around anyway. Why bother?

Categories