> In that example the constructor parameters were just moved
Not really. In the "Original" example there's no constructor in sight, as that's just a standalone procedural-style method, not a class.
The second one turns the method into a class.
> is there some cost
As GP mentions, this incurs mental costs: "In more complex classes, it’s often hard to even identify that this has happened. Is this permanent object state, or just an internal temporary variable that made it easier to leap around methods?"
In terms of performance, this depends on the language/runtime/type, but in general you'll get heap allocation instead of a stack, and it will use the GC.
Also if the lifetime of the private fields is the same of GuessStatisticsMessage, so you'll waste memory if they're complex objects that don't need to live for as long as the class. Depends, YMMV. I once had a memory leak-ish issue due to that in a Ruby app.
EDIT:
> Once again, it was presented in the context of naming things....not object or data structures
This is fine, but the example is not even good in terms of names. `make` is a terrible method name [1], and, turning local variables into long-lived object variables doesn't improve their names, it only muddies the waters like GP mentioned.
It all doesn't matter, these are code fragments that are not in context of a full program.
Lets look at the labels on these code blocks (in a chapter called "Chapter 2: Meaningful Names")
> Listing 2-1
> Variables with unclear context.
> Listing 2-2
> Variables have a context.
What part of that would even suggest that they are indicating the most performant, idealized code?
They are non-complete random code fragments meant to discuss one of the hardest problems in computer science...naming things.
It is simply a poor example of "Variables have a context" being more readable than "Variables with unclear context", not a suggestion that the lifting principle is required.
This is _simply_ an example that is similar to the extract and inversion method that all of us that get brought in to break up legacy monoliths have to do because often things are a big ball of much with vars that look more like it was written in the language Brainfuck or obfuscated Perl than anything reasonable.
That is not anything that the Clean camp, or even Bob came up with...it is often the reality when trying to save systems from architectural erosion or....
But seriously if you consider 'clean code' as cargo culting design choices without though from any source, you are going to be screwed no matter what.
The number of competing needs related to a dozen types of cohesion along with a dozen types of coupling will never reduce to a simple set of rules.
Strings are interned either in the string pool, or even if you use New...which this code wasn't, anything newer than 8u20 will dedupe and duplicate strings will only have a single instance even if they aren't in the string pool. So long lived strings total space usage isn't really massive.
If you choose to save the size of a pointer with what appears a short lived single computational class anyway, sacrificing readability and maintainability, you will have far greater problems than inefficient memory use.
The parameters have moved to a class method, still within the class, which is now public, but still taking a string and an intrinsic int, the string, as being passed as a parameter is already in the string pool or perhaps on the heap outside the string pool if it was created with New,
Nothing has been elevated outside of the block scope.
Where is anything that was claimed about raising variables to global scope as was suggested above apply.
You still have a constructor btw, just the make() method overloading the missing class construction.
The parameters are just placeholders, they have to be instantiate when invoked even if the implicit construction is hidden.
But in the beginning example and the refactored example they have the same instance variables, with the latter being marked private but that doesn't impact the lifecycle.
The question being if the refactored version uses the new private methods as callable or if optimization removes them.
The point being is that blaming performance regressions on this type of refactoring to improve readability is on thin ground for java.
This example does nothing to suggest that global state APIs etc.. that are a problem in react relate at all to the recommendation, which are still containing everything in a local scope.
I thank you for taking the time to answer, but what I am looking for is how this somehow lifts vars to a global scope, which it doesn't.
Original (labeled bad by the book):
Modified version: Once again, it was presented in the context of naming things....not object or data structures.Often one has to resort to spherical cows to explain things.
(Edited to add the overloaded constructor params)