Converting a public method into a private method - java

I recently refactored some code which converted a public method that was only being used in conjure with another public method, into one call.
public class service() {
public String getAuthenticatedUserName() {
return SecurityContext.getName();
}
public getIdentityUserIdByUsername(String username) {
return db.getUser(username).getId();
}
}
which was being utilised in a few other classes as service.getIdentityUserIdByUsername(service.getUsername()), which seemed redudant. A new method was created combining the two calls.
public getIdentityUserId() {
return getIdentityUserIdByUsername(getUsername());
}
The getIdentityUserIdByUsername() is still being utilised in other classes without the need for getUsername(). However, the getUserName() method is no longer used in other classes.
My example is much simpler than the implementation, the method has test coverage that is a bit awkward to do (mocking static classes without Powermock and a bit of googling etc). In the future it's likely we will need the getUsername() method, and the method will not change.
It was suggested in code review that the getUsername() method should now be private due to it not being called anywhere else. This would require the explicit tests for the method be removed/commented out which seems like it would be repeated effort to rewrite or ugly to leave commented out code.
Is it best practice to change the method to private or leave it public because it has explicit coverage and you might need it in the future?

Is it best practice to change the method to private or leave it public because it has explicit coverage and you might need it in the future?
IMO, you are asking the wrong question. So called "best practice" doesn't come into it. (Read the references below!)
The real question is which of the alternatives is / are most likely to be best for you. That is really for you to decide. Not us.
The alternatives are:
You could remove the test case for the private method.
You could comment out the test case.
You could fix the test case so that it runs with the private version of the method.
You could leave the method as public.
To make a rational decision, you need to consider the technical and non-technical pros and cons of each alternative ... in the context of your project. But don't be too concerned about making the wrong decision. In the big picture, it is highly unlikely that making the wrong choice will have serious consequences.
Finally, I would advise to avoid dismissing options just because they are "code smell". That phrase has the same issue as "best practice". It causes you to dismiss valid options based on generalizations ... and current opinions (even fashions) on what is good or bad "practice".
Since you want someone else's opinion ("best practice" is just opinion!), mine is that all of the alternatives are valid. But my vote would be to leave the method as public. It is the least amount of work, and an unused method in an API does little harm. And as you say, there is a reasonable expectation that the method will be used in the future.
You don't need to agree with your code reviewer. (But this is not worth making enemies over ...)
References:
No Best Practices by James Bach
There is no such thing as "Best Practices": Context Matters. by Ted Neward.

It can make sense to want to test private methods. The industry standard way to do this, which has quite some advantages, is this:
Ensure that the test code lives in the same package as the code it tries to test. That doesn't mean same directory; for example, have src/main/java/pkg/MyClass.java and src/test/java/pkg/MyClassTest.java.
Make your private methods package private instead. Annotate them with #VisibleForTesting (from guava) if you want some record of this.
Separately from this, the entry space for public methods (public in the sense of: This is part of my API and defines the access points where external code calls my code) is normally some list of entrypoints.. if you have it at all. More often there is no such definition at all. One could say that all public methods in all public types implicitly form the list (i.e. that the keyword public implies that it is for consumption by external code), which then by tautology decrees that any public method has the proper signature. Not a very useful definition. In practice, the keyword public does not have to mean 'this is API accessible'. Various module systems (such as jigsaw or OSGi) have solutions for this, generally by letting you declare certain packages as actually public.
With such tooling, 'treeshaking' your public methods to point out that they need no longer be public makes sense. Without them... you can't really do this. There is such a notion as 'this method is never called in my codebase, but it is made available to external callers; callers that I don't have available here, and the point is that this is released, and there are perhaps projects that haven't even started being written yet which are intended to call this'.
Assuming you do have the tree-shaking concept going, you can still leave them in for that 'okay maybe not today but tomorrow perhaps' angle. If that applies, leave it in. If you can't imagine any use case where external code needs access to it, just delete it. If it really needs to be recovered, hey, there's always the history in version control.

If the method is a public static then you can leave it as is because there is no impact of it being public. It is aside effect free method, it being exposed will never cause any harm.
If it is a object level public method then -
1) Keep it if it is like an API. It has well defined input, output and delivers a well defined functionality and has tests associated with it. It being public doesn't harm anything.
2) Make it private immediately if it has side effects. If it causes others methods to behave differently because it changes the state of the object then it is harmful being public.

Related

Making side-effect free methods static

A few days ago I made a code review and I noticed that several static methods have been introduced. When I talked to the colleague who opened the pull request, he told me that he makes side-effect free (not pure) methods static as it would help to deal with side effects. He stated that this way you easily see which methods lead to side effects and which don't.
Personally, I disagree here. Despite the fact that there are many static methods which cause side effects (just have a look at System), static methods often (not always) lead to problems, for instance during testing.
However, static isn't bad per se and I know every day is a school day. Is this a pattern I'm missing? What is the advantage of making a side-effect free method static?
static methods are only indirectly related to the concern of side effects. In the case of a private method, it can be made static if it doesn't dereference this. One of many consequences is that such a method does not mutate the object's state, which precludes one narrow class of side effects. Do not forget that the method may also accept arguments and mutate them; and even without that it can always access and/or mutate global state accessible over some static variable.
The real decision criteria are these:
Does the method dereference this?
Is the method subject to dynamic dispatch on the type of this?
If the answer to both questions is "no", then the method can safely become static.
The complaint that "static methods create problems for testing" is related to 2. above. In testing we sometimes have to provide mock overrides of a method. In that case the answer to 2. is "yes" and the method fails the criteria.
A private method should always be static if it can. In the split-second it takes to notice the static marker you will have gained the following important knowledge: the method doesn't deal with the object's state and doesn't call any other instance methods.
If a public method satisfies the criteria to become static, then it quite likely doesn't even belong to the class it's in because it has no coupling to it. In most cases such a method is a candidate for relocation into a static utility class.
Finally, the concept of pure functions (as opposed to just side effect-free) does matter here: pure functions are the least likely to ever need mocking. They are usually simple and fast to execute and their outcome can be controlled simply by supplying the appropriate input. Compare these two methods:
System.currentTimeMillis()—no side effects, but depends on global state and its output cannot be controlled. Often the fact that it's non-mockable means trouble in testing as the tests become non-repeatable.
Character.toUpperCase(char)—a pure function, performs a simple translation. You'll never have to mock this one.

Difference between #VisibleForTesting and #Deprecated int unit test

Let's say that there just so happens to be an existing long private method (one of which i'm not allowed to refactor into smaller pieces at this stage in the development process) but i really want to write a couple of regression-protection unit test for it, just for now.
i just heard of this #VisibleForTesting annotation, but am not too sure of its benefits and gotchas. Previously, i had always been marking things with #Deprecated and comments to try and make it VERY CLEAR like:
... some code ...
// ====================================== TESTING USE ONLY BELOW ======================================
#Deprecated // TESTING ONLY, DO NOT USE!
boolean testGiveAccessToSomethingPrivate() {
// call some private method and get the results
}
it seems that whenever i mark something as #VisibleForTesting it seems to expose the method for realz, without any indication to the user of the API that this method was only meant for testing... (whereas if i mark the method with #Deprecated, most IDEs will put a strike-through that warns other developers to not accidentally use the test method for their actual code
#Deprecated
When the method is marked #Deprecated, programmers use this method will know maybe this method will be removed, different behavior ... in future version. And if that happen, your code will be broken and you will rework. So, they should use this function very carefully or should replace by other function. (often programmer who made this api will make another similar function without deprecated for you to use).
#VisibleForTesting
You have learnt public private protected ... and you use it well. But in real world, everything not as our imagination. For example, your class have a private variable, and you want to test this variable, how can?
class SimpleClass() {
private int a;
public simpleMethod() {
if (a < 0) {
// do something
} else {
// do another thing
}
}
}
One way is changing scope of variable a to package level, because your test file will be same package with file to be tested. But another programmer jumps into and they will ask their self: "Why someone put modifier of a is package level? I think private level is better". (of course, they don't know or don't mind reading your test code because life is so busy). So you will have a way for their to know by using #VisibleForTesting. They read this and Google and know: "Ahhhh, I understood. He want this variable is testable".
That's a very short story about those two annotations. The similar is: They don't change the way your code run. Not change anything but notify for other people to know something. Very famous annotation every Java Developer knew and similar is #Override
The difference is: #Deprecated for someone using your code, and #VisibleForTesting for someone reading your code. Let make life's programmer easier in both case.
Hope this help :)

How do you organize class source code in Java?

By now my average class contains about 500 lines of code and about 50 methods.
IDE is Eclipse, where I turned “Save Actions” so that methods are sorted in alphabetical order, first public methods, and then private methods.
To find any specific method in the code I use “Quick Outline”. If needed, “Open Call Hierarchy” shows the sequence of methods as they called one by one.
This approach gives following advantages:
I can start typing new method without thinking where to place it in the code, because after save it will be placed by Eclipse to appropriate place automatically.
I always find public methods in the upper part of the code (don’t have to search the whole class for them)
However there are some disadvantages:
When refactoring large method into smaller ones I’m not very satisfied that new private methods are placed in different parts of code and therefore it’s little bit hard to follow the code concept. To avoid that, I name them in some weird way to keep them near each one, for example: showPageFirst(), showPageSecond() instead of showFirstPage(), showSecondPage().
May be there are some better approaches?
Organize your code for its audiences. For example, a class in a library might have these audiences:
An API client who wants more detail on how a public method works.
A maintainer who wants to find the relevant method to make a small change.
A more serious maintainer who wants to do a significant refactoring or add functionality.
For clients perusing the source code, you want to introduce core concepts. First we have a class doc comment that includes a glossary of important terms and usage examples. Then we have the code related to one term, then those related to another, then those related to a third.
For maintainers, any pair of methods that are likely to have to change together should be close by. A public method and its private helper and any constants related to it only should show up together.
Both of these groups of users are aided by grouping class members into logical sections which are separately documented.
For example, a collection class might have several mostly orthogonal concerns that can't easily be broken out into separate classes but which can be broken into separate sections.
Mutators
Accessors
Iteration
Serializing and toString
Equality, comparability, hashing
Well, naming your methods so that they'll be easier to spot in your IDE is really not good. Their name should reflect what they do, nothing more.
As an answer to your question, probably the best thing to do is to split you class into multiple classes and isolate groups of methods that have something in common in each of such classes. For example , if you have
public void largeMethodThatDoesSomething() {
//do A
//do B
//do C
}
which then you've refactored such that:
public void largeMethodThatDoesSomething() {
doA();
doB();
doC();
}
private void doA() {};
private void doB() {};
private void doC() {};
you can make a class called SomethingDoer where you place all these 4 metods and then use an instance of that class in your original class.
Don't worry about physically ordering your methods inside the class, if you can't see it just use Ctrl-O and start typing the method name and you will jump straight to it.
Having self-describing method names results in more maintainable code than artificially naming them to keep them in alphabetical order.
Hint: learn your shortcut keys and you will improve your productivity
Organizing the way you described sounds better than 99% of the Java code I have seen so far. However, on the other side, please make sure your classes don't grow too much and methods are not huge.
Classes should usually be less than 1000 lines and methods less than 150.

Thread safe class vs Utility class with all static methods

When ever I see a class documented as thread safe, I wonder why it was not designed to be a utility class with all static methods like java.lang.Math, etc.
I'm missing valid driving force whenever I design a class in the scenarios like no state but chained methods in a single class.
Example 1: How about a class A that has a 'thread-safe field' S; I mean, the object 'S' itself is thread-safe. Can we declare all the methods and fields like S in class A to be static.
I hope my explanation is clear enough. Please clarify.
Note: Exclude javabeans, property holding classes, etc.. My question was regarding classes which perform some actions based on input params, they might need to make use of other classes as well.
I apologize that I edited the question. First draft was totally ambiguous.
I can easily imagine a situation where a class is required to have state, yet it's also a requirement to be thread-safe. I use queues for worker-threads for example. It HAS to be thread-safe and definitely has to have state in it. (namely the elements in the queue)
EDIT:
Note: Exclude javabeans, property holding classes, etc.. My question was regarding classes which perform some actions based on input params, they might need to make use of other classes as well.
If by that you mean that your question is about truly stateless classes, then -by definition- your observation is correct. Those can almost always be expressed in static utility classes.
EDIT2:
I think you are being somewhat mislead by the fact, that a lot of times when we see static we can relax about thread-safety. (Though it's not true in every case, just a rule of thumb) While thread-safety and statelessnes can go hand in hand in a way, static is an orthogonal concept. Furthermore, statelessnes does give you thread safety but thread safety doesn't have to mean stateless. If that would be the case, the whole concept of synchronized would be unnecessary.
For testability and since static fits OO like fist fits nose.
Testable code requires that you can CREATE your tested object in a controlled way. I don't want to have to execute someone's code just because it's called from somewhere within object I'm testing. I want to test my object in isolation - assuming it's collaborators work fine. Using static methods from some tools makes me use PowerMock for testability OR kiss isolation good-bye and execute that code as well while I'm testing. Powermock is a problem (since it uses it's own classloader), so is testing more than I want.
Static means procedural code. That's fine sometimes, since procedural is fine sometimes. But try to use OO features (inheritance, polymorphism) with static methods to find another reason when NOT to use static.
Simple example illustrating this: http://www.javaworld.com/javaworld/javaqa/2001-05/01-qa-0504-oo.html?page=1 - by no means exhaustive, but shows the point I hope.
Other examples are listed in #JB Nizet's comment on the answer above.
I know this is a late answer, but honestly, I had my fair share of problems with testing objects using static methods from 'instanceless' classes and the usually sought-after solution aka PowerMock.

Java: Best practices for turning foreign horror-code into clean API...?

I have a project (related to graph algorithms). It is written by someone else.
The code is horrible:
public fields, no getters/setters
huge methods, all public
some classes have over 20 fields
some classes have over 5 constructors (which are also huge)
some of those constructors just leave many fields null
(so I can't make some fields final, because then every second constructor signals errors)
methods and classes rely on each other in both directions
I have to rewrite this into a clean and understandable API.
Problem is: I myself don't understand anything in this code.
Please give me hints on analyzing and understanding such code.
I was thinking, perhaps, there are tools which perform static code analysis
and give me call graphs and things like this.
Oh dear :-) I envy you and not at the same time..ok let's take one thing at a time. Some of these things you can tackle yourself before you set a code analyzing tool loose at it. This way you will gain a better understanding and be able to proceed much further than with a simple tool
public fields, no getters/setters
make everything private. Your rule should be to limit access as much as possible
huge methods, all public
split and make private where it makes sense to do so
some classes have over 20 fields
ugh..the Builder pattern in Effective Java 2nd Ed is a prime candidate for this.
some classes have over 5 constructors (which are also huge)
Sounds like telescoping constructors, same pattern as above will help
some of those constructors just left many fields null
yep it is telescoping constructors :)
methods and classes rely on each other in both directions
This will be the least fun. Try to remove inheritance unless you're perfectly clear
it is required and use composition instead via interfaces where applicable
Best of luck we are here to help
WOW!
I would recommend: write unittests and then start refactoring
* public fields, no getters/setters
start by making them private and 'feel' the resistance on compiler errors as metric.
* huge methods, all public
understand their semantics, try to introdue interfaces
* some classes have over 20 fields
very common in complex appilcations, nothing to worrie
* some classes have over 5 constructors (which are also huge)
replace them by by buider/creator pattern
* some of those constructors just left many fields null
see above answer
* methods and classes rely on each other in both directions
decide whether to to rewrite everything (honestly I faced cased where only 10% of the code was needed)
Well, the clean-up wizard in eclipse will scrape off a noticable percentage of the sludge.
Then you could point Sonar at it and fix everything it complains about, if you live long enough.
For static analysis and call graphs (no graphics, but graph structures), you can use Dependency Finder.
Use an IDE that knows something about refactoring, like IntelliJ. You won't have situations where you move one method and five other classes complain, because IntelliJ is smart enough to make all the required changes.
Unit tests are a must. Someone refactoring without unit tests is like a high-wire performer without a safety net. Get one before you start the long, hard climb.
The answer may be: patience & coffee.
This is the way I would do it:
Start using the code , e.g. from within a main method, as if it were used by the other classes - same arguments, same invocation orders. Do that inside a debugger, as you see each step that this class makes.
Start writing unit tests for that functionality. Once you have reached a reasonable coverage, you will start to notice that this class probably has too many responsibilities.
while ( responsibilities != 1 ) {
Extract an interface which expresses one responsibility of that class.
Make all callers use that interface instead of the concrete type;
Extract the implementation to a separate class;
Pass the new class to all callers using the new interface.
}
Not saying tools like Sonar, FindBugs etc. that some have already mentiones don't help, but there are no magic tricks. Start from something you do understand, create a unit test for it and once it runs green start refactoring piece by piece. Remember to mock dependencies as you go along.
Sometimes it is easier to rewrite something from scratch. Is this 'horrible code' working as intended or full of bugs? It is documented?
In my current project, deleting my predessor's work nearly in its entirety, and rewriting it from scratch, was the most efficient approach. Granted, this was an extreme case of code obfuscation, utter lack of meaningful comments, and utter incompetence, so your mileage may vary.
Though some legacy code might be barely comprehensible, still it can be refactored and improved to legibility in a stepwise fashion. Have you seen Joshua Kerievsky's Refactoring To Patterns book? -- it's good on this.

Categories