Java : preferred design when multiple methods share same arguments (class member ?) - java

Context: I believe that object creation and management in Java has a cost that we should bear in mind while programming. However, I don't know how big that cost is. Hence my question:
I have multiple functions that share the same arguments:
detectCollision(ArrayList<Mobile>, ArrayList<Inert>, double dt)
updatePositions(ArrayList<Mobile>, double dt)
etc.
As I see it, there are two ways to organize them (see code below):
define (possibly static, but not necessarily) methods and forward the arguments for each call
create a temporary object with private member variables and remove argument list.
Note that the Mover object has no private internal state and is just a bunch of algorithms that use the arguments ArrayList<Mobile>, ArrayList<Inert>, double dt.
Question: Which approach is the prefered one ? Does it have a cost ? Is there a more standard alternative ?
Here is a snippet illustrating the first point:
public class Mover{
public static void updatePositions(ArrayList<Mobile>, double dt){...}
/* remove the static keyword if you need polymorphism, it doesn't change the question */
public static Collisions detectCollision(ArrayList<Mobile>, ArrayList<Inert>, double dt){...}
//etc.
}
Here is a snippet illustrating the second point:
public class Mover{
public Mover(ArrayList<Mobile>, ArrayList<Inert>, double dt){...}
public void updatePositions(){...}
public Collisions detectCollision(){...}
//etc.
private ArrayList<Mobile> mobiles;
private ArrayList<Inert> inerts;
//etc.
}

I'd recommend you to go with the second variant. Besides the good readability it will also allow you to extend the class later (see SOLID -> open / closed principle). In general, I'd never create such utility classes, as it is not OOP (OOP Alternative to Utility Classes).

While I think that static utility methods are not necessarily a Bad Thing™, you should be aware of the semantics of these methods. One of the most important points here is that static means that a method may not take part in any form of polymorphism. That is: It may not be overridden.
So regarding the design, the second option offers a greater degree of flexibility.
A side note: Even if you choose the second approach, you might eventually dispatch to a (non-public) static method internally:
class Mover {
private final List<? extends Mobile> mobiles;
public void updatePositions(){
MyStaticUtilityMethods.updatePositions(this.mobiles);
}
}
Note that I'm not generally recommending this, but pointing it out as one option that may be reasonable in many cases.
It might be off-topic, but there is another degree of freedom for the design here. You could (and at least should consider to) go one step further: As far as one can guess (!) from the method names, you might consider having interfaces PositionUpdater and a CollisionDetector. Then you could store instances of classes implementing these interfaces inside your Mover class, and dispatch the actual call to these. This way, you can easily combine the different aspects of what comprises a "Mover".
(I know, this does not answer the actual question. In fact, it just "defers" it to whether the PositionUpdater should receive the data as arguments, or receive them at construction time...)
You could then assign instances of different implementations of the PositionUpdater interface to a Mover instance. For example, you could have concrete classes called LinearMovementPositionUpdater and RandomWalkPositionUpdater. Passing instances of these classes (which are both implementing the PositionUpdater interface) to the Mover allows you to change one aspect of the implementation of a Mover - basically, without touching any code! (You could even change this at runtime!).
This way, the responsibilities for
updating the positions
detecting the collisions
are clearly encapsulated, in view of several of the SOLID principles that already have been mentioned in another answer.
But again: This is just a hint. Judging whether this approach is actually sensible and applicable in one particular case is what software engineers get all the $$$ for.

The problem you're having here is mostly due to having an orchestrated model (and which probably has an anaemic domain model to accompany it).
If instead you use an event driven approach these methods would simply disappear and be replaced by event handlers each of which would respond to the appropriate events independently of the other, taking whatever information they need from the initial event.
This means that you wouldn't have to deal with passing parameters or working out which parameters to pass -- each 'handler (method)' would know what it needs and would take it, rather than having to have an external orchestrator understand what data is needed and pass it in.
The orchestrator model breaks encapsulation by having it 'know' about the information needs of the components it is orchestrating.
Now, this isn't a java specific problem. It applies to most modern object-oriented languages. It doesn't matter if you're doing java, c-sharp, or c++. It's a general pattern.
To break away from this thinking, read about DDD (Domain Driven Design) and Event Sourcing.

Related

When we change the implementation of a method, do we have to recompile dependent classes?

Let's say that we have the following method in class TaxCalculator:
public double calculateTax(double income) {
return income * 0.3;
}
And we use this method in the Main class like this:
var calculator = new TaxCalculator();
double tax = calculator.calculateTax(100_000);
System.out.println(tax);
If I change the implementation of the calculateTax method to:
public double calculateTax(double income) {
return income * 0.4;
}
Do I need to recompile both the TaxCalculator class and the Main class?
I know this question sounds very silly, but I heard in a lecture that if we don't use interfaces, every change we make in tightly-coupled code (like the one I showed above) will force us to recompile all the classes that depends on the class we made the change.
And this sounds weird to me, because the Main class doesn't know the implementation of the method we've made the change.
Thanks in advance for any help!
Yeah, that lecturer was just dead wrong. More generally, this is a very outdated notion that used to be a somewhat common refrain, and various lecturers still espouse it:
The idea that, if you have a class, you make a tandem interface that contains every (public) method in that class; given that the class already occupies the name of the concept, the interface can't be given a good name, and thus, an I is prefixed. You have a class Student and a matching interface IStudent.
Don't do that. It's a ton of typing, even if you use tools to auto-generate it, everytime you change one you are then forced to change the other, and there is no point to it.
There are exotic and mostly irrelevant ways in which you get a 'more tight coupling' between a user of the Student class and the Student class code itself vs. having that user use IStudent instead. It sounds like either you or more likely perhaps the lecturer is confused and presumed that this tight coupling implies that any change in Student.java would thus require a recompile.
Furthermore, if those examples are from the lecture, oh boy. double is absolutely not at all acceptable for financial anything. That should most likely be an int or long, representing cents (or whatever passes for 'atomic monetary unit' for the currency in question; pennies for pounds, satoshis for bitcoin, yen for yen, and so on). In rare cases, BigDecimal. In any case, not, ever, double or float.
You need to recompile B, where B uses something from A, if:
You change the value of a constant in A that is used directly used by B, and that constant was 'CTC' (Compile Time Constant). Only the primitives and strings can be CTC, and they are CTC if the field is static final, and is immediately initialized (vs. initialized in a separate static {} block), and whose expression is itself CTC, which means its comprised of literals and possibly simple operations between CTCs, e.g. in static final int a = 5; static final int b = a + 10;, b is also CTC. In contrast, e.g. static final long c = System.currentTimeMillis(); is not a compile time constant because System.currentTimeMillis() isn't, for obvious reasons.
You change a signature of any element in A that B uses. Even if the caller (B.java here) can be recompiled with zero changes. For example, you have in A.java: void foo(String param) and you change that void foo(Object param). Even though foo("hello") is a valid call to either method, you still need to recompile here. Relevant elements are the name of the method, the types of the parameters (not the names), and the return type. Changing the exceptions you throw is fine. Deleting something in A that B used is, naturally, also something that'd require a recompile.
And that's essentially it. The interjection of an interface doesn't meaningfully change this list - if that constant is in the interface, the same principle applies (if you change it, you have to recompile users of this constant), and if you change signatures, you'd have to change them in the interface as well, and we're back where we started.
Adding an interface does have some generally irrelevant bonuses.
As a caveat, any such attempt must always answer the rather poignant question of: But how do callers make an instance? If the lecturer uses IStudent student = new Student(); they messed that up, and the few mostly irrelevant benefits of using an interface are gone.
If there are meaningfully different implementations available (quick rule of thumb: If you can come up with good news for all relevant types, this is the case), using an interface is 'correct' and none of this applies. For example, java.util.List is the interface, java.util.LinkedList and java.util.ArrayList are meaningfully different implementations of the same idea.
It's slightly easier to make an implementation of the interface specifically for test purposes. However, mocks and extending the class are generalized solutions to this problem too and usually work just as well, and more generally making a test-specific impl requires more care than just a rote application of the 'make a mirroring interface' principle.
You get an extra level of access - you can have public things in the class that nevertheless aren't mirrored in the interface, and thus, are not 'accessible' via the interface. There is a single good reason to make things public when they aren't really meant for external consumption: When you have a multi-package system. Java's module system acknowledges this too, and (via the 'exported package' concept) also introduces, effectively, another access level (a public thing in a non-exported package is not accessible from other modules, it's not as public as a public thing in an exported package). This is outdated, and there are ways around it even in a multi-package library, and it doesn't actually stop much - you cannot enforce callers to 'code to the interface'1
Well, you can, but those are a bit clunky, and those would also stop another package in the same project, which was the whole point. You can use hacks to get around this, but if you're willing to use these hacks, you can just make those public, but not actually meant for external consumption non-public and use the same hackery.

Find a Decorator of a particular type when using the Decorator Pattern?

I'm building an app that needs to use multiple types of similar sensors. Since the sensors could also have different behaviours, or combinations of behaviours, I decided to use the decorator pattern.
In short, I have a hierarchy that looks like this:
So any of the concrete ISensorDecorator classes can decorate (wrap) any of the concrete IMeasureSensor classes, but since a concrete ISensorDecorator also is a concrete IMeasureSensor, they can wrap each other. So for example
IMeasureSensor sensor = new FilteredSensorDecorator(
new CalibratedSensorDecorator(
new AccelerometerSensor()
)
);
is a valid statement that declares a filtered and calibrated accelerometer sensor.
Now let's say I have a method called setCalibration() in CalibratedSensorDecorator. Obviously I can't call
sensor.setCalibration();
because IMeasureSensor doesn't have a setCalibration() method. And trying to use
((CalibratedSensorDecorator)sensor).setCalibration()
won't work either, since sensor is a FilteredSensorDecorator.
How can I get to the CalibratedSensorDecorator in this particular case, and more generally to any specific decorator in any "chain" of decorators? I don't want to store them as separate variables, I want to do it dynamically.
Since its a design question, there won't be any right answer, you need to make choice which could be good or not that good.
You shouldn't add a method for particular class since it will violate the Liskov substitution principle
Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
You can initialize the calibration in constructor CalibratedSensorDecorator and use it while executing your required function.
If that doesn't meet your requirement, then may be CalibratedSensorDecorator doesn't belong in your sensor hierarchy. Consider separating it and use Strategy pattern to decide which one to use.
Edit 1:
what I understand it doesn't say that you shouldn't add methods to subtypes?
Yes, you are right. It doesn't prohibit from adding methods but if the methods are changing the state of an Object, then it should be re-considered. All these patterns are just the guidelines which can be tweaked as per our needs.
To explain my rationale:
Imagine you have create the setCalibration() on CalibratedSensorDecorator. You have following way to expose CalibratedSensorDecorator to either internal developer or to external developer. You have created a Factory which just returns IMeasureSensor as follows:
public IMeasureSensor getCalibratedSensor(){
...
}
Now the user of your API simply gets this and is happy that his/her current code is working. But realizes that he/she missed to setCalibration() which was found after hours of debugging. Moreover he/she has to write the type checking and type casting code to make use of this feature, which might not be great for clean code.
You should try to keep your classes as immutable as possible so that the debugging and maintenance are at ease. There is no harm in recreating the object since the older will be garbage collected.
Again its just my suggestion, its your decision to carefully consider what's best for your use-case. You can still go ahead with your new approach to create the method if its mandatory and ensure proper documentation has been made to make user understand the usage.
While the answer by Sagar discusses some (valid) reasons for considering using another approach than the decorator pattern, I came up with a working solution for the actual problem of finding the correct decorator.
/**
* Walks the decorator hierarchy recursively from the outside in (excluding the final
* IMeasureSensor which is not a ISensorDecorator), and returns the decorator of the given class.
* If none can be found, null is returned.
*/
IMeasureSensor findDecorator(IMeasureSensor sensor, Class decoratorClass){
if( ISensorDecorator.class.isAssignableFrom(sensor.getClass()) ){
return (sensor.getClass() == decoratorClass)
? sensor
: findDecorator(((ISensorDecorator) sensor).getDecoratee(), decoratorClass);
}
else
return null;
}
The method ISensorDecorator.getDecoratee() simply returns the "decoratee", i.e. the IMeasureSensor that the decorator decorates.
public IMeasureSensor getDecoratee(){
return mMeasureSensor;
}
You can then use findDecorator() to find a (the outermost) decorator of a given type like this:
IMeasureSensor sensor;
...
CalibratedSensorDecorator s = (CalibratedSensorDecorator) findDecorator(sensor, CalibratedSensorDecorator.class);

Why Encapsulation is called data hiding, if its not hiding the data?

What is the difference between following two class in terms of data hiding(encapsulation).
In below example , I can access the value of member by making it public.
Eg: 1
public class App {
public int b = 10;
public static void main(String[] args) {
System.out.println(new App().b);
}
}
In below example, I can access the value of member by using getter method.
Eg : 2
class DataHiding
{
private int b;
public DataHiding() {
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
In both the above examples, I can access the value of member. Why Eg : 2, is called data hiding (encapsulation) ? If its not hiding the data.
Why Eg : 1 is not called encapsulated ?
What is it about
As you tagged this question with both java and object oriented programming oop, I suppose you are implicitly thinking about Java Beans. Nevertheless this is a question quite common across languages, take the wikipedia page on this matter :
In programming languages, encapsulation is used to refer to one of two
related but distinct notions, and sometimes to the combination1
thereof:
A language mechanism for restricting access to some of the object's
components.
A language construct that facilitates the bundling
of data with the methods (or other functions) operating on that
data.
Some programming language researchers and academics use the first
meaning alone or in combination with the second as a distinguishing
feature of object-oriented programming, while other programming
languages which provide lexical closures view encapsulation as a
feature of the language orthogonal to object orientation.
The second definition is motivated by the fact that in many OOP
languages hiding of components is not automatic or can be overridden;
thus, information hiding is defined as a separate notion by those who
prefer the second definition.
So encapsulation is not really about hiding data or information it about enclosing pieces of data in a language component (a class in Java). A Java Beans encapsulate data.
That being said, while encapsulation is one of the main feature of object oriented programming paradigm, at some point in the history of language design it was seen as not enough to help design better software.
History
One key practice to achieve better software design is decoupling, and encapsulation helps on that matter. Yet a cluster of data was not enough to help achieve this goal, other efforts in OOP pioneering were made in different language at that time, I believe SIMULA is the earliest language to introduce some kind of visibility keywords among other concepts like a class. Yet the idea of information hiding really appears later in 1972 with data that is only relevant to the component that uses it to achieve greater decoupling.
But back to the topic.
Answers to your questions
In this case data is encapsulated and public
This is commonly known as a global variable and it is usually regarded as a bad programming practice, because this may lead to coupling and other kind of bugs
Data is encapsulated and public (through method accessors)
This class is usually referred to as a Java Bean, these are an abomination if used in any other than what they were designed for.
These object were designed to fulfill a single role and that is quite specific is according to the specification
2.1 What is a Bean?
Let's start with an initial definition and then refine it:
“A Java Bean is a reusable software component that can be manipulated visually in a builder tool.”
Why is it an abomination nowadays ? Because people, framework vendors usually misuse them. The specification is not enough clear about that, yet there's some statement in this regard :
So for example it makes sense to provide the JDBC database access API as a class library rather than as a bean, because JDBC is essentially a programmatic API and not something that can be directly presented for visual manipulation.
I'd rather quote Joshua Bloch (more in this question and answer) :
"The JavaBeans pattern has serious disadvantages." - Joshua Bloch, Effective Java
Related points
As explained above one key practice to achieve better software is decoupling. Coupling has been one of the oldest battlefront of software engineers. Encapsulation, information hiding have a lot to do with the following practices to help decoupling for numerous reasons:
the Law of Demeter, breaking this law means the code has coupling. If one has to traverse a whole data graph by hand then, there's no information hiding, knowledge of the graph is outside of the component, which means the software is therefore less maintainable, less adaptable. In short : refactoring is a painful process. Anemic domain model suffer from that, and they are recognized as an anti-pattern.
A somehow modern practice that allows one to not break the Law of Demeter is Tell, Don't Ask.
That is, you should endeavor to tell objects what you want them to do; do not ask them questions about their state, make a decision, and then tell them what to do.
immutability, if data has to be public it should be immutable. In some degree if data is not needed, one module can introduce side effects in another ; if this was true for single threaded programs, it's even more painful with multi-threaded softwares. Today softwares and hardware are getting more and more multi-threaded, threads have to communicate, if an information has to be public it should be immutable. Immutability guarantee thread-safety, one less thing to worry about. Also immutability has to be guaranteed on the whole object graph.
class IsItImmutable {
// skipping method accessors for brevity
// OK <= String is immutable
private final String str;
// NOK <= java.util.Date is mutable, even if reference is final a date can be modified
private final Date date;
// NOK <= Set operations are still possible, so this set is mutable
private final Set<String> strs;
// NOK <= Set is immutable, set operations are not permitted, however Dates in the set are mutable
private final Set<Date> udates = Collections.unmodifiableSet(...);
// OK <= Set is immutable, set operations are not permitted, String is immutable
private final Set<String> ustrs = Collections.unmodifiableSet(...);
}
Using mutators and accessors hides the logic, not the name of the methods. It prevents users from directly modifying the class members.
In your second example, the user has no idea about the class member b, whereas in the first example, the user is directly exposed to that variable, having the ability to change it.
Imagine a situation where you want to do some validation before setting the value of b, or using a helper variable and methods that you don't want to expose. You'll encapsulate the logic in your setter and by doing that, you ensure that users cannot modify the variable without your supervision.
Encapsulation is not data hiding it is information hiding. You are hiding internal structure and data implementation, as well as data access logic.
For instance you can store your integer internally as String, if you like. In first case changing that internal implementation would mean that you have to also change all code that depends on b being an int. In second case accessor methods will protect internal structure and give you int, and you don't have to change the rest of the code if internals have changed.
Accessor methods also give you opportunity to restrict access to the data making it read-only or write-only in addition to plain read-write access. Not to mention other logic that can verify integrity of data going into the object as well as changing object state accordingly.
What happens if you want to retrieve the state of B without being able to change its value? you would create the getter but not the setter, you can't accomplish that by accessing B as a public int.
Also, in both methods get and set, if we had a more complex object, maybe we want to set or get some property or state of the object.
Example.
private MyObject a;
public setMyObjectName(String name){
MyObject.name = name;
}
public getMyObjectName(){
return MyObject.name;
}
This way we keep the object encapsulated, by restricting access to its state.
In java, all methods are virtual. This means, that if you extend some class, you can override the result of a method. Imagine for example the next class (continuing on your example):
class DataHidingDouble extends DataHiding{
public int getB(){
return b*2;
}
}
this means that you maintain control over what b is to the outer world in your subclass.
imagine also some subclass where the value of b comes from something that is not a variable, eg. a database. How are you then going to make b return the value if it is a variable.
It hides the data, not the value. Because the class is responsible for maintaining the data, and returning the correct value to the outside world.

OOP: Any idiom for easy interface extraction and less verbose auto-forwarding?

EDIT
Even though I use a pseudo-Java syntax below for illustration, this question is NOT limited to any 1 programming language. Please feel free to post an idiom or language-provided mechanism from your favorite programming language.
When attempting to reuse an existing class, Old, via composition instead of inheritance, it is very tedious to first manually create a new interface out of the existing class, and then write forwarding functions in New. The exercise becomes especially wasteful if Old has tons of public methods in it and whereas you need to override only a handful of them.
Ignoring IDE's like Eclipse that though can help with this process but still cannot reduce the resulting verbosity of code that one has to read and maintain, it would greatly help to have a couple language mechanisms to...
automatically extract the public methods of Old, say, via an interfaceOf operator; and
by default forward all automatically generated interface methods of Old , say, via a forwardsTo operator, to a composed instance of Old, with you only providing definitions for the handful of methods you wish to override in New.
An example:
// A hypothetical, Java-like language
class Old {
public void a() { }
public void b() { }
public void c() { }
private void d() { }
protected void e() { }
// ...
}
class New implements interfaceOf Old {
public New() {
// This would auto-forward all Old methods to _composed
// except the ones overridden in New.
Old forwardsTo _composed;
}
// The only method of Old that is being overridden in New.
public void b() {
_composed.b();
}
private Old _composed;
}
My question is:
Is this possible at the code level (say, via some reusable design pattern, or idiom), so that the result is minimal verbosity in New and classes like New?
Are there any other languages where such mechanisms are provided?
EDIT
Now, I don't know these languages in detail but I'm hoping that 'Lispy' languages like Scheme, Lisp, Clojure won't disappoint here... for Lisp after all is a 'programmable programming language' (according to Paul Graham and perhaps others).
EDIT 2
I may not be the author of Old or may not want to change its source code, effectively wanting to use it as a blackbox.
This could be done in languages that allow you to specify a catch-all magic method (eg. __call() in php). You could catch any function call here that you have not specifically overriden, check if it exists in class Old and if it does, just forward the call.
Something like this:
public function __call($name, $args)
{
if (method_exists($old, $name))
{
call_user_func([$obj, $name], $args);
}
}
First, to answer the design question in the context of "OOP" (class-oriented) languages:
If you really need to replace Old with its complete interface IOld everywhere you use it, just to make New, which implements IOld, behave like you want, then you actually should use inheritance.
If you only need a small part of IOld for New, then you should only put that part into the interface ICommon and let both Old and New implement it. In this case, you would only replace Old by ICommon where both Old and New make sense.
Second, what can Common Lisp do for you in such a case?
Common Lisp is very different from Java and other class-oriented languages.
Just a few pointers: In Common Lisp, objects are primarily used to structure and categorize data, not code. You won't find "one class per file", "one file per class", or "package names completely correspond to directory structure" here. Methods do not "belong" to classes but to generic functions whose sole responsibility it is to dispatch according to the classes of their arguments (which has the nice side effect of enabling a seamless multiple dispatch). There is multiple inheritance. There are no interfaces as such. There is a much stronger tendency to use packages for modularity instead of just organizing classes. Which symbols are exported ("public" in Java parlance) is defined per package, not per class (which would not make sense with the above obviously).
I think that your problem would either completely disappear in a Common Lisp environment because your code is not forced into a class structure, or be quite naturally solved or expressed in terms of multiple dispatch and/or (maybe multiple) inheritance.
One would need at least a complete example and large parts of the surrounding system to even attempt a translation into Common Lisp idioms. You just write code so differently that it would not make any sense to try a one-to-one translation of a few forms.
I think Go has such a mechanism, a struct can embed methods from another struct.
Take a look here. This could be what you are asking as second question.

Should Java methods be static by default?

Say you're writing method foo() in class A. foo doesn't ever access any of A's state. You know nothing else about what foo does, or how it behaves. It could do anything.
Should foo always be static, regardless of any other considerations? Why not?
It seems my classes are always accumulating many private helper methods, as I break tasks down and apply the only-write-it-once principle. Most of these don't rely on the object's state, but would never be useful outside of the class's own methods. Should they be static by default? Is it wrong to end up with a large number of internal static methods?
To answer the question on the title, in general, Java methods should not be static by default. Java is an object-oriented language.
However, what you talk about is a bit different. You talk specifically of helper methods.
In the case of helper methods that just take values as parameters and return a value, without accessing state, they should be static. Private and static. Let me emphasize it:
Helper methods that do not access state should be static.
1. Major advantage: the code is more expressive.
Making those methods static has at least a major advantage: you make it totally explicit in the code that the method does not need to know any instance state.
The code speaks for itself. Things become more obvious for other people that will read your code, and even for you in some point in the future.
2. Another advantage: the code can be simpler to reason about.
If you make sure the method does not depend on external or global state, then it is a pure function, ie, a function in the mathematical sense: for the same input, you can be certain to obtain always the same output.
3. Optimization advantages
If the method is static and is a pure function, then in some cases it could be memoized to obtain some performance gains (in change of using more memory).
4. Bytecode-level differences
At the bytecode level, if you declare the helper method as an instance method or as a static method, you obtain two completely different things.
To help make this section easier to understand, let's use an example:
public class App {
public static void main(String[] args) {
WithoutStaticMethods without = new WithoutStaticMethods();
without.setValue(1);
without.calculate();
WithStaticMethods with = new WithStaticMethods();
with.setValue(1);
with.calculate();
}
}
class WithoutStaticMethods {
private int value;
private int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
class WithStaticMethods {
private int value;
private static int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
The lines we are interested in are the calls to helper(...) on the classes WithoutStaticMethods and WithStaticMethods.
Without static methods
In the first case, without static methods, when you call the helper method the JVM needs to push the reference to the instance to pass it to invokespecial. Take a look at the code of the calculate() method:
0 aload_0
1 aload_0
2 getfield #2 <app/WithoutStaticMethods.value>
5 iconst_2
6 aload_0
7 getfield #2 <app/WithoutStaticMethods.value>
10 imul
11 invokespecial #3 <app/WithoutStaticMethods.helper>
14 ireturn
The instruction at 0 (or 1), aload_0, will load the reference to the instance on the stack, and it will be consumed later by invokespecial. This instruction will put that value as the first parameter of the helper(...) function, and it is never used, as we can see here:
0 iload_1
1 iload_2
2 imul
3 iconst_1
4 iadd
5 ireturn
See there's no iload_0? It has been loaded unnecessarily.
With static methods
Now, if you declare the helper method, static, then the calculate() method will look like:
0 aload_0
1 getfield #2 <app/WithStaticMethods.value>
4 iconst_2
5 aload_0
6 getfield #2 <app/WithStaticMethods.value>
9 imul
10 invokestatic #3 <app/WithStaticMethods.helper>
13 ireturn
The differences are:
there's one less aload_0 instruction
the helper method is now called with invokestatic
Well, the code of the helper function is also a little bit different: there's no this as the first parameter, so the parameters are actually at positions 0 and 1, as we can see here:
0 iload_0
1 iload_1
2 imul
3 iconst_1
4 iadd
5 ireturn
Conclusion
From the code design angle, it makes much more sense to declare the helper method static: the code speaks for itself, it contains more useful information. It states that it does not need instance state to work.
At the bytecode level, it is much more clear what is happening, and there's no useless code (that, although I believe the JIT has no way to optimize it, would not incur a significant performance cost).
If a method does not use instance data, then it should be static. If the function is public, this will give the important efficiency boost that you don't need to create a superfluous instance of the object just to call the function. Probably more important is the self-documentation advantage: by declaring the function static, you telegraph to the reader that this function does not use instance data.
I don't understand the sentiment of many posters here that's there's something wrong with having static functions in a Java program. If a function is logically static, make it static. The Java library has many static functions. The Math class is pretty much filled with static functions.
If I need, say, a function to calculate a square root, the rational way to do it would be:
public class MathUtils
{
public static float squareRoot(float x)
{
... calculate square root of parameter x ...
return root;
}
}
Sure, you could make a "more OOPy" version that looked like this:
public class MathUtils
{
private float x;
public MathUtils(float x)
{
this.x=x;
}
public float squareRoot()
{
... calculate square root of this.x ...
return root;
}
}
But aside from meeting some abstract goal of using OOP whenever possible, how would this be any better? It takes more lines of code and it's less flexible.
(And yes, I now there's a square root function in the standard Math class. I was just using this as a convenient example.)
If the only place a static function is used and is every likely to be used is from within a certain class, then yes, make it a member of that class. If it makes no sense to call it from outside the class, make it private.
If a static function is logically associated with a class, but might reasonably be called from outside, then make it a public static. Like, Java's parseInt function is in the Integer class because it has to do with integers, so that was a rational place to put it.
On the other hand, it often happens that you're writing a class and you realize that you need some static function, but the function is not really tied to this class. This is just the first time you happened to realize you need it, but it might quite rationally be used by other classes that have nothing to do with what you're doing now. Like, to go back to the square root example, if you had a "Place" class that included latitude and longitude, and you wanted a function to calculate the distance between two places and you needed a square root as part of the calculation, (and pretending there was no square root function available in the standard library), it would make a lot of sense to create a separate square root function rather than embedding this in your larger logic. But it wouldn't really belong in your Place class. This would be a time to create a separate class for "math utilities" or some such.
You ask, "Should foo always be static, regardless of any other considerations?" I'd say "Almost, but not quite."
The only reason I can think of to make it not static would be if a subclass wants to override it.
I can't think of any other reasons, but I wouldn't rule out the possibility. I'm reluctant to say "never ever under any circumstances" because someone can usually come up with some special case.
Interesting question. In practical terms, I don't see the point in making class A's private helper methods static (unless they're related to a publicly-accessible static method in A, of course). You're not gaining anything -- by definition, any method that might need them already has an instance of A at its disposal. And since they're behind-the-scenes helper methods, there's nothing to say you (or another co-worker) won't eventually decide one of those stateless helpers might actually benefit from knowing the state, which could lead to a bit of a refactoring nuisance.
I don't think it's wrong to to end up with a large number of internal static methods, but I don't see what benefit you derive from them, either. I say default to non-static unless you have a good reason not to.
No. Never. Static methods should be an exception. OO is all about having Objects with behaviour which revolves around the object's state. Imho, ideally, there shouldn't be any (or very few) static methods, because everything unrelated to the object's state could (and to avoid leading the concept of an object ad absurdum, should) be placed in a plain old function at module level. Possible exception for factories because Complex.fromCartesian (to take a wikipedia example) reads so well.
Of course this (edit: Module-level functions) isn't possible in a single-paradigm OO language (edit: like Java) - that's why I'm such a devoted advocate of multi-paradigm language design, by the way. But even in a language exclusively OO, most methods will revolve around the object's state and therefore be nonstatic. That is, unless your design has nothing to do with OO - but in this case, you're using the wrong language.
I usually
Perform these steps in order, as needed:
a) I write some code in a member method, figure out that I can probably re-use some of this code and
Extract to non-static method
b) Now I'll see if this method needs access to state or if I can fit its needs into one or two parameters and a return statement. If the latter is the case:
Make method (private) static
c) If I then find that I can use this code in other classes of the same package I'll
Make method public and move Method to a package helper class with default visibility
E.g. In package com.mycompany.foo.bar.phleeem I would create be a class PhleeemHelper or PhleeemUtils with default visibility.
d) If I then realize that I need this functionality all over my application, I
Move the helper class to a dedicated utility package
e.g. com.mycompany.foo.utils.PhleeemUtils
Generally I like the concept of least possible visibility. Those who don't need my method shouldn't see it. That's why I start with private access, move to package access and only make things public when they are in a dedicated package.
Unless you pass in an object reference, a static method on an class enforces that the method itself cannot mutate the object because it lacks access to this. In that regard, the static modifier provides information to the programmer about the intention of the method, that of being side-effect free.
The anti-static purists may wish to remove those into a utility class which the anti-utility purists surely object to. But in reality, what does artificially moving those methods away from their only call site achieve, other than tight coupling to the new utility class.
A problem with blindly extracting common utility methods into their own classes is those utilities should really be treated as a new public API, even if it's only consumed by the original code. Few developers, when performing the refactoring, fail to consider this. Fast-forward to other devs using the crappy utility class. Later on somebody makes changes to the extension to suit themselves. If you're lucky a test or two breaks, but probably not.
I generally don't make them static but probably should. It's valuable as a hint to tell the next coder that this method CANT modify the state of your object, and it's valuable to give you a warning when you modify the method to access a member that you are changing the nature of the method.
Coding is all about communicating with the next coder--don't worry about making the code run, that's trivial. So to maximize communication I'd say that if you really need such a helper, making it static is a great idea. Making it private is critical too unless you are making a Math. like class.
Java conflates the concepts of module, namespace, adt, and class, as such to claim that some class-oriented OO-purity should prevent you from using a java class as a module, namespace, or adt is ridiculous.
Yes the methods should be static. Purely internal support methods should be private; helper methods protected; and utility functions should be public. Also, there is a world of difference between a static field, a static constant, and a public static method. The first is just another word for 'global variable'; and is almost always to be avoided, even mediation by accessor methods barely limits the damage. The second is treating the java class as a namespace for a symbolic constant, perfectly acceptable. The third is treating the java class as a module for a function, as a general rule side-effects should be avoided, or if necessary, limited to any parameters passed to the function. The use of static will help ensure that you don't inadvertently break this by accessing the object's members.
The other situation you will find static methods invaluable is when you are writing functional code in java. At this point most of the rules-of-thumb developed by OO-proponents go out the window. You will find yourself with classes full of static methods, and public static function constants bound to anonymous inner functors.
Ultimately java has very weak scoping constructs, conflating numerous concepts under the same 'class' and 'interface' syntax. You shouldn't so much 'default' to static, as feel free to use the facilities java offers to provide namespaces, ADT's, modules, etc as and when you feel the need for them.
I find it difficult to subscribe to those avoid-static-methods theories. They are there to promote a completely sanitary object-oriented model anti-septically cleansed of any deviation from object relationships. I don't see any way essential to be anti-septically pure in the practice object-orientedness.
Anyway, all of java.util.Arrays class are static. Numeric classes Integer, Boolean, String have static methods. Lots of static methods. All the static methods in those classes either convert to or from their respective class instances.
Since good old Gosling, et al, proved to be such useful role models of having static methods - there is no point avoiding them. I realise there are people who are perplexed enough to vote down my response. There are reasons and habits why many programmers love to convert as much of their members to static.
I once worked in an establishment where the project leader wanted us to make methods static as much as possible and finalize them. On the other hand, I am not that extreme. Like relational database schema design, it all depends on your data modelling strategy.
There should be a consistent reason why methods are made static. It does not hurt to follow the standard Java library pattern of when methods are made static.
The utmost importance is programming productivity and quality. In an adaptive and agile development environment, it is not only adapting the granularity of the project to respond effectively to requirements variation, but also adapting programming atmosphere like providing a conformable coding model to make best use of the programming skill set you have. At the end of the day (a project almost never ends), you want team members to be efficient and effective, not whether they avoided static methods or not.
Therefore, devise a programming model, whether you want MVP, injection, aspect-driven, level of static-avoidance/affinity, etc and know why you want them - not because some theoretical nut told you that your programming practice would violate oo principles. Remember, if you work in an industry it's always quality and profitability not theoretical purity.
Finally what is object-oriented? Object-orientation and data normalization are strategies to create an orthogonal information perspective. For example, in earlier days, IBM manuals were written to be very orthogonal. That is, if a piece of info is written somewhere in a page within those thousands of manuals, they avoid repeating that info. That is bad because you would be reading learning how to perform a certain task and frequently encounter concepts mentioned in other manuals and you would have to be familiar with the "data model" of the manuals to hunt those connecting pieces of info thro the thousands of manuals.
For the same reason, OS/2 failed to compete with Microsoft because IBM's concept of orthogonality was purely machine and data based and IBM was so proudly declaring their true object-orientedness vs Microsoft's false object-orientedness pandering to human perspective. They had forgotten we humans have our own respective varying orthogonal perspectives of information that do not conform to data and machine based orthogonality or even to each other.
If you are familiar with the topology of trees, you would realise that you could pick any leaf node and make it the root. Or even any node, if you don't mind having a multi-trunk tree. Everyone thinks his/her node is the root when in fact any could be the root. If you think your perspective of object-orientation is the canon, think again. More important is to minimise the number of nodes that are accepted as candidate roots.
There needs to be a compromise between effectiveness and efficiency. There is no point in having an efficient data or object model that can be hardly effectively used by fellow programmers.
If it does nothing with objects of this class, but actually belong to this class (I would consider moving it elsewhere), yes it should be static.
Don't use static if you can avoid it. It clashes with inheritance ( overriding ).
Also, not asked but slightly related, don't make utility methods public.
As for the rest, I agree with Matt b. If you have a load of potentially static methods, which don't use state, just put them in a private class, or possibly protected or package protected class.
It depends i.g. java.lang.Math has no method which isn't static.
(You could do a static import to write cos() instead of Math.cos())
This shouldn't be overused but as some code that is intented to be called as a utility it would be acceptable. I.g Thread.currentThread()
A static method is used to identify a method (or variable for that matter) that does not have to do with the objects created from that class but the class itself. For instance, you need a variable to count the number of objects created. You would put something like: 'private static int instances = 0;' and then put something in the constructor for that class that increments 'instances' so you may keep count of it.
Do think hard before creating a static method, but there are times when they are a good solution.
Joshua Bloch in "Item 1: Consider Static Factory Methods Instead of Constructors" in Effective Java makes a very persuasive case that static methods can be very beneficial. He gives the java.util.Collections class's 32 static factory methods as an example.
In one case, I have a hierarchy of POJO classes whose instances can be automatically serialized into XML and JSON, then deserialized back into objects. I have static methods that use Java generics to do deserialization: fromXML(String xml) and fromJSON(String json). The type of POJO they return isn't known a priori, but is determined by the XML or JSON text. (I originally packaged these methods into a helper class, but it was semantically cleaner to move these static methods into the root POJO class.)
A couple of other examples:
Using a class as a namespace to group related methods (eg, java.lang.Math).
The method truly is a private class-specific helper method with no need to access instance variables (the case cited here). Just don't sneak a this-equivalent into its argument list!
But don't use statics unthinkingly or you run the danger of falling into a more disorganized and more procedural style of programming.
No, the use of statics should be quite niche.
In this case the OP is likely 'hiding' state in the parameters passed into the static method. The way the question is posed makes this non-obvious (foo() has no inputs or outputs), but I think in real world examples the things that should actually be part of the object's state would fall out quite quickly.
At the end of the day every call to obj.method(param) resolves to method(obj, param), but this goes on at a way lower level than we should be designing at.
If it's only ever used by methods in A and wouldn't have any use outside it, then it should be static (and, probably, be placed in a Helper Class. It doesn't have any use outside A now, but there's no guarantee it will never have. Otherwise, it shouldn't.
If it doesn't have anything to do with the state of A, it could be useful at other places...
Anyway, that doesn't make a good reason for Java methods to be static by default.
Talking about this last issue, they shouldn't be static by default, because having to write 'static' make people think before writing static methods. That's a good practice when you have heterogeneous teams (the ones where Java is most useful).
When you write a static method you should keep in mind that you'r gonna use it at use-site with static-import (make it look class free) and thus it should behave just like a function which doesn't something and may or may not return something and is isolated with the state of class it belongs to. So static methods should be a rare situation.
If you seem to be making a lot of helper methods, then consider using package-private instance methods instead of private ones. Less typing, less boilerplate since you can re-use them as a helper to other classes in the same package.
I think "private static" (edit: for methods) is kind of an oxymoron in Java. The main point of static methods in my mind is to provide access to functions outside of the context of object instances. In other words, they're practically only ever useful if they're public. If you're only calling a method from within the context of a single object instance, and that method is private, it makes no sense to make it static. (edit: but, it makes no practical difference).
In this sort of case, I usually try to make the methods abstract enough that they're useful in other contexts, and I make them public in a utility class. Look at it as writing supporting library code, and think hard about your api.
Most static methods are written because
You break down a complex method into submethods, or
You wish String (or Date, or...) had some functionality that it doesn't have
The first is not bad per se, but it's often a sign that you're missing objects. Instead of working with default types such as String or List, try inventing your own classes and move the static methods to those classes.
The second reason produces the always-popular StringUtil, DateUtil, FooUtil classes. These are problematic because you have no way to discover that they exist, so programmers often write duplicates of these utility methods. The solution, again, is to avoid using String and Date all the time. Start creating your own objects, perhaps by wrapping the original object. The static methods become non-static methods of the new object.
If foo() doesn't have anything to do with Object A then why is the method in there?
Static methods should still be relevant. If there isn't anything going on then why have you written a method that has no association with it?
If foo is private, it may be anything, static or not. But, most of the time it will be not static as these is one less word to type. Then, if you need to use the state because you've changed your code, you can do it right away.
When it is protected or public, it depends on what it does. A rule of thumb is to make it not static when it isn't a part of the instance's behaviour, and make it static when it makes sense to call it without any object.
If you are unsure, ask yourself if it makes sense to override the method in a subclass.
I think letting the methods in Java to be static will result in a rather chaotic implementation by beginner who haven't understand OO correctly. We've been there and think about it. If the methods were static as default how hard it is for us to understand the OO principle?
So yes, once you mastered the concept, it is a bit itchy to have static all over the methods (as result of refactoring). Nothing we ca do about that I think.
NB: Let me guess, are you by any chance have read Clean Code?
Plenty of interesting answers.
If you desperately seek a rule, then use this:
If the code is only ever used by instance methods of a single class, then make it an instance method - it is simply an extraction of code out of an instance context - which could be refactored back into (or out of) methods that access instance state.
If the code is used by MORE THAN ONE class, and contains no access to instance variables in the class in which the method resides, then make it static.
End of story.

Categories

Resources