简体   繁体   中英

Non static methods vs Utilty with static methods

I am creating an application in Java which performs data movement task ( like copy, move, etc. )

At the higher level, I can provide these operations on object level.

Sample code:

public class DataSource {

   public boolean copy(DataSource dsDestination);

   public boolean copy(DataSource dsDestination, Filter filter);

   public boolean move(DataSource dsDestination);

   public boolean exists();

   // some other 10-15 methods

}

Or I can provide a utility with static methods:

public class DataSourceUtil {


   public static boolean copy(DataSource dsSource, DataSource dsDestination);

   public static boolean copy(DataSource dsSource, DataSource dsDestination, Filter filter);

   public static boolean move(DataSource dsSource, DataSource dsDestination);

   public static boolean exists(DataSource dsSource);

   // some other 10-15 methods

}

Which one is better approach in terms of memory management?

The golden rule is: static is an abnormality within good OO design. You only use it if there are good reasons to do so.

You see, static leads to direct coupling between your classes. And it makes testing harder. Of course, the static methods themselves can be easily tested, but what would happen if you want to test a method that calls those static methods (and you have the need to influence what the static method is doing)? Then you might be tempted to turn to Powermock in order to mock those static calls. Which is not really a great idea.

If you insist on separating functionality, you better use interfaces, like:

public class DataSource {
 ... ctor, equals, ... methods
}

public interface DataSourceCopyAbility {
  public void copy(DataSource source, DataSource destintion);

plus corresponding impl class.

EDIT: of course, convenience can be a valid reason to use static methods; for example I am using Objects.requireNonNull() all the time in code. But : those are standard API calls. When I am using them in my code, I really dont mind them to be running. I know that will never ever want to "mock" around such kind of static method invocations!

Finally: I assume you want to return true when your operations passed. Bad idea : booleans should only be used to distinguish between true and false. They are not return codes!

If such a complex operation as copying a DataSource fails - then throw an exception! Or if you really want to go without exceptions, define your own specific ReturnCode class that gives you insight into failing operations!

Forget about memory management.

No matter which method you use, you are still going to create two DataSource objects to call copy or move . There is little difference in memory usage.

What you should focus on instead, is readability and aesthetics :).

Compare these two:

someData.copy(otherData);
DataSourceUtils.copy(someData, otherData);

The second one is more verbose. Also, it seems that we need some other stuff ( DataSourceUtils ) to help with copying data. It would be less code to write and make more sense if we let the data copy itself (first one).

Another point that I want to point out is that you can add a To in the first one to make it a lot more readable:

someData.copyTo(otherData);

You can't do this with the second method.

I agree with @Jon Skeet , as all the operations need source object which is Datasource itself, then they should be instance methods. They are similar to equals in Object class.

From testable point-of-view instance methods are easy to test.

It depends on the functionality that you are writing in these methods..If the functionality is not using any object specific field values then using static methods would be the correct option.

ie make sure the variable information that you are using is not specific to object and data is common to class level

Memory management point of view, by the way, they are equivalent. The functions are share their compiled codes which is stored into the read only memory area. Only the difference between those two are the this pointer context. So it should not occupy any more space if you choose static or non static. Most of the compiled languages are following same manner.

Drawing from the experience of Apache Commons Lang library and java.lang.Objects , the advantage of static methods is that they can provide protection from NullPointerException

It is quite common to see something like this in Java code:

if (x != null &&  a.equals(otherX)) ...

or the practice of putting the literal on the left side:

if ("literal".equals(str)) ...

These are all NPE-protection ways. This is one of the reasons for the abovementioned liberary, and the case for static methods:

if (ds.copy(dest) == true) ...  // may throw NPE

if (DataSourceUtil.copy(ds, dest) == true) ...  // NPE protection

the difference:

dataSource.copy();

copy is not my responsibility and it is a responsibility of DataSource.

DataSourceUtil.copy();

copy is my responsibility,but source code has been written in a utility class to avoid duplication.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM