code reuse in Methods.class vs strategy pattern and dependency injection [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Status: Answers of Fendy and Glen Best are equally acceptable and honored by me but since one can be accepted and bounty be given, I choose Fendy's answer.
Scenario:
If I have some code that has to be reused many times in many classes (rarely with minor parameter changes which is obvious) and concurrent threads, Which approach to go for?
The code that has to be reused can be any sane thing (with appropriate care of static and non-static context in mind and method making techniques). It can be an algorithm, A DB method doing connect,operate,close. Anything.
Make some class like MyMethods.class and put all those methods in it.
1.a. Make methods static and call (by all classes and concurrent threads) directly as MyMethods.someMethod();
1.b. Make methods non-static and at the time to call them, instantiate the whole class by MyMethods mm = MyMethods(); mm.someMethod();
Use Strategy pattern stated at https://en.wikipedia.org/wiki/Strategy_pattern (code attached here with).
Use dependency injection stated at https://en.wikipedia.org/wiki/Dependency_injection#Java
Problems:
Some people would say Unit test http://en.wikipedia.org/wiki/Unit_testing wont be possible with this approach, will make trouble in swaping out latter. if you want to test your class and use a mock version of the dependency
1.a. Will there be any problems with concurrent calls or multiple classes? specially in JDBC static methods for just an example?
1.b. I think it would make too much memory load as a whole class would be instanticated many times just to call one or two methods
Thats way over my head, do explain that and or any advantages/disadvantages
I do Not want to use a framework in context to this question.. Thats way over my head, do explain that and or any advantages/disadvantages
Awaiting any other strategies or recommendations, if any.
Request: Please only answer if you are experienced and know the implications deeply and can comprehensively, with your answer, help me and the community as a whole!
Code:
/** The classes that implement a concrete strategy should implement this.
* The Context class uses this to call the concrete strategy. */
interface Strategy {
int execute(int a, int b);
}
/** Implements the algorithm using the strategy interface */
class Add implements Strategy {
public int execute(int a, int b) {
System.out.println("Called Add's execute()");
return a + b; // Do an addition with a and b
}
}
class Subtract implements Strategy {
public int execute(int a, int b) {
System.out.println("Called Subtract's execute()");
return a - b; // Do a subtraction with a and b
}
}
class Multiply implements Strategy {
public int execute(int a, int b) {
System.out.println("Called Multiply's execute()");
return a * b; // Do a multiplication with a and b
}
}
// Configured with a ConcreteStrategy object and maintains
// a reference to a Strategy object
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return this.strategy.execute(a, b);
}
}
/** Tests the pattern */
class StrategyExample {
public static void main(String[] args) {
Context context;
// Three contexts following different strategies
context = new Context(new Add());
int resultA = context.executeStrategy(3,4);
context = new Context(new Subtract());
int resultB = context.executeStrategy(3,4);
context = new Context(new Multiply());
int resultC = context.executeStrategy(3,4);
System.out.println("Result A : " + resultA );
System.out.println("Result B : " + resultB );
System.out.println("Result C : " + resultC );
}
}

Your question actually has two meanings.
that has to be reused many times in many classes
It can be a context of design pattern (reusable component) or memory cost (class instantiation). Talking from two different perspective:
Memory Cost (I had little experience on this, but let me share my experience)
This section actually only cover 2 kind of instantiation.
First is static (or DI instantiation in composition root)
Eager instantiation, means all class will be instantiated when application start
One time instantiation only
Non-static
Lazy instantiation, means class will only be instantiated when needed
One time instantiation every use
In short, static will cost high if the class is many, and non-static will cost high if the request is high (inside for loop, for example). But it should not make your application heavy. Most operation in java / csharp are creates objects though.
Class Reusability
1 - mega monolithic code (one god class able to do almost everything)
Advantages:
Easy to search for code (still depends though), you know that every logic lies there so you just need to look at that big class
If it is static, you can just call it anywhere without worrying about the instantiation
Disadvantages:
Any modification for one method creates risk for error in other places
Violates SRP, means this class can be changed by various reason, not only one
Especially in versioning, it is harder to merge if modification happen in separated branches, resulting effort in synchronize code
1a / static class / singleton pattern
Advantages:
Easy to use
Can be used anywhere (just reference and call, and done)
Not need to instantiate object
Disadvantages:
Hard to unit test (it is hard to mock, and at latter time, you will find it is taking time to prepare the test environment. Especially with data
If stateful (has state), it is hard to determine current state, during debugging. Moreover, it is hard to determine which function changes the state, in can be changed from everywhere
Tend to have much parameters (maybe around 5-11)
Some point about static class: see this question
2 strategy pattern
Actually this has the same design with 3 or composition over inheritance.
3 dependency injection
Advantages:
Easy to mock and unit test
Must be stateless. It is easier to debug and unit test if the class is stateless
Support to be refactored
The disadvantage:
Hard to debug for those who does not familiar with interfaces (everytime you redirect to the method, it goes to interface's)
Creates layering which will resulting to mapping
State / Stateless
I think states plays important rules in your application design. Usually developers try to avoid having states in business logic code, such as:
// get data
if(request.IsDraft){
// step 1
// step 2
}
else{
// step 1
// step 3
}
Developers tend to put the logic in other stateless class, or at least methods such as:
// get data
if(request.IsDraft){
draftRequestHandler.Modify(request);
}
else{
publishedRequestHandler.Modify(request);
}
It will provide in better readability, and easier for modification and unit tests. There is one design pattern state pattern or hierarchial state machine pattern too, especially to handle some cases like this.
Single Responsibility Principle
IMHO, this principle is has the most benefit if followed. The advantages are:
In versioning, the changes are clear about which class has been modified and why
In DI, several smaller classes can be wired up, creating flexibility in both usage and unit test
Increase modularity, low coupling and high cohesion
TDD (Test Driven Development)
This design does not guarantee your code free of bugs. In cons of costing time at design phase and layering effort, it has the benefit of:
Easy to mock object for unit test
Easier to refactor because of unit test and modularity
Easier to maintain / extend
Some useful sources
Service Locator Anti Pattern
Using Decorator for cross-cutting concern
My 2 cents:
The benefit of using interface (also apply for composition ofer inheritance)
Doing top down design / DI design
Final Thoughts
Those designs and strategies are not the key which will determine your application structure. It still the architect who will determine it. I prefer to follow some principles such as SOLID, KISS and GRASP, rather than deciding what is the best structure. It is said that Dependency Injection follow the most of those principles, but too much abstraction and incorrect components design will resulting the same with the misuse of singleton pattern.

1.a. Make methods static and call (by all classes and concurrent threads) directly as MyMethods.someMethod();
1.b. Make methods non-static and at the time to call them, instantiate the whole class by MyMethods mm = MyMethods(); mm.someMethod();
The choice between these two depends on the functionality of MyMethods.class. If MyMethods is supposed to be stateless then it's a good approach to go with static methods. Otherwise, if one method call depends on another and MyMethods have states (i.e. non-final fields) then use the second option.
Use Strategy pattern stated at https://en.wikipedia.org/wiki/Strategy_pattern (code attached here with).
Use this pattern if MyMethods are to be extended with different classes for different purposes and if you select which code to run depending on your context. As the wiki says, if you the algorithm to be used is not known before the runtime (depends on some conditions) this is the way to go. According to your specification of MyMethods you do not have such problems.
Use dependency injection stated at https://en.wikipedia.org/wiki/Dependency_injection#Java
Same answer as above. The thing with dependency injection is in inversion of control. A class that uses MyMethods does not know about actual the implementation of MyMethods, but the injection of real implementation is delegated to some higher-level authority. It abstracts external dependencies from the context where it is going to be used. Again, if MyMethods are to be stateless and constant (not planned to change, and the behavior of methods within the class does not depend on the context where they are used) you do not need these patterns as it would just mean over engineering.
I would conclude that you should use Strategy or DI pattern if logic of MyMethods depends on the context from which they are run. If this is constant (e.g. Java's Math class does not care who or in what context someone calls sqrt(), max() or pow()) then static methods are the way to go.
Regarding problems:
Problems you stated are not present when you use MyMethods with static methods. You will have to test whether your methods return correct values for particular arguments and that's it. I don't believe that there would be much more trouble testing actual implementation of Strategy in Strategy pattern or implementation of interface that are injected through Dependency injection. What might be harder is testing the classes that use strategy because sometimes it's not easy to recreate the context in which particular strategy will be executed as it often depends on user input, but it's definitely not impossible. Dependency injection is, as far as I'm concerned, great for testing because you can separate unit under test from dependency which you can easily mock.

The main question: code reuse
If I have some code that has to be reused many times in many classes (rarely with minor parameter changes which is obvious) and concurrent threads, Which approach to go for?
Because you're not considering any cut-&-paste, I think you mean:
... reused many times by many classes ...
What you're asking is nothing special or specific. It's common that code is reused, either within a single app or across multiple apps.
The common answer: use object-oriented design/programming. Put the code in a class, create an object as an instance, call the object...
1a. Reuse via static methods:
Make methods static and call (by all classes and concurrent threads) directly as MyMethods.someMethod()
If your class is stateless (no instance variables), this is a great approach.
If your class has class-level state (static instance variables only), but the variables are read-only (immutable), this is a good approach.
If your class has class-level state (static instance variables only) and the variables change values (mutable), then this can be an appropriate approach. However, if you want your class to be accessible from multiple threads, you must make it thread-safe: make your methods synchronized, or have internal code that synchronizes (mutually-exclusive thread access) for all data reads and writes.
If your code has object-level state (non-static instance variables), this approach won't work - impossible to access non-static instance variables without instantiating an object.
1b. Reuse via non-static methods, with object instantiation:
Make methods non-static and at the time to call them, instantiate the whole class by MyMethods mm = MyMethods(); mm.someMethod();
If your class has static instance variables only, this is a poor approach, because instantiating the object achieves nothing
If your class has non-static instance variables - this is the only approach. Mandatory to instantiate an object to access the variables.
If the instantiated objects are to be used across multiple threads, they should be (in order of preference):
stateless (no instance variables) - really an option for 1a - no need to instantiate
immutable (read-only non-static instance variables)
synchronized on all data reads & writes
Use Strategy pattern
Strategy pattern can be good practice. But it has little to do with your overall question. Strategy pattern is used for a specific reason - to swap the implementation of algorithm/processing logic "on-the-fly" without impacting the caller.
Use dependency injection
Dependency injection is used for these reasons:
Factory & object cache functionality: removes from your code responsibility for object creation, caching and lookup
Intermediation for object sharing: allows various classes to share the same object instance (stored in a given scope/context), without the two classes directly passing the object between themselves
"Wiring control" between object instances - setting up object associations, and under CDI, support for interceptor, decorator and observer patterns
This can be very good practice, if used appropriately. In your case, this could only ever apply under option 1b. Dependency injection is all about object instantiation and provision into variables.
Problems:
Some people would say Unit test wont be possible
Mocking frameworks (and hand-coded unit testing) deal with replacing classes with mock logic, all the time. It's a very normal scenario. You can extend a class to mock it's logic - if it doesn't have final public methods. Also, you can transfer method declarations to an interface, have the class implement the interface, and then mock by implmenting the interface with a different class.
In other words, this is not a constraint/force affecting any of your options
1a. See above
1b. Memory Load
I think it would make too much memory load as a whole class would be instanticated many times just to call one or two methods
A small issue. Depending on the data within each object instance (the instance variables), each object instance could be as small as a dozen bytes or as large as megabytes - but usually slanted towards the lower end (often < 1kB). The memory consumption of class code itself is not replicated each time the class is instantiated.
Of course, it's good practice to minimise the volume of objects, according to your requirements - don't create a new instance if you already have a useable one. Create fewer object instances and share them across your app - passing them into constructor methods and setter methods. Dependency injection is a good way to share object instances "automatically" without passing them into constructors/setters.
See above
See above

Related

Singleton's other members

My question is broad, so I've split in two parts, and tried to be as specific as I can with what I know so far.
First part
A singleton holds a private static instance of itself. Some questions about singletons:
1. Should it's members also be static, or does that depend on the requirements?
2. If the answer to 1. is unequivocally yes, then what would be the point of having a private instance variable to begin with, if all members belong to the class?
3. Is the private instance needed because the JVM needs a referable object (THE singleton) to hold on to for the length of its (JVM's) life?
Second part
There is a requirement to make multiple concurrent remote calls within a tomcat hosted web application (the app utilizes GWT for some components, so I can utilize a servlet for this aforementioned requirement if a good solution requires this). Currently, I create an executor service with a cached thread pool into which I pass my callables (each callable containing an endpoint configuration), for each individual process flow that requires such calls. To me it would make sense if the thread pool was shared by multiple flows, instead of spawning pools of their own. Would a singleton holding a static thread pool be a good solution for this?
One note is that it is important to distinguish between the concept of a singleton (a class/object that has only a single instance) and the design pattern which achieves this via a class holding a single static instance of itself accessible in the global static name space. The concept of a singleton is frequently used in designs, the implementation of it via the singleton design pattern, however, is often frowned upon.
In the below, singleton is used to refer to the specific design pattern.
Part 1
A Singleton's members do not need to be static, and usually are not.
See 1.
A singleton (design pattern) requires an instance to itself in order to return that instance to users of the singleton, as well as keeping a reference to itself active to avoid garbage collection (as you suggest). Without this single instance, the object is essentially not an implementation of the singleton design pattern. You can create a class for which you only create a single instance and pass this class around where it is required (avoiding the global static namespace), and this would essentially be a recommended way to avoid using the singleton pattern.
Part 2:
Sharing your thread pools is probably wise (but depends on your requirements), and this can be done in a number of ways. One way would be to create a single pool and to pass this pool (inject it) into the classes that require it. Usual recommendation for this is to use something like Spring to handle this for you.
Using a singleton is also an option, but even if your thread pool here is encapsulated in a singleton, it is still generally preferable to inject this singleton (preferably referenced via an interface) into dependent objects (either via a setter or in their constructor) instead of having your objects refer to the singleton statically. There are various reasons for this, with testing, flexibility, and control over order of instantiation being some examples.
A Singleton's members need not be be static.
Invalidated by answer to point 1.
The instance of itself that the singleton need not be private either. You need an instance stored to a static member (public or private) if you have any other non-static member on the singleton. If there is any non-static member(it depends on your requirement) , then you need an instance to access that member(yes, JVM needs a referable object if the member is non-static)
Singleton member doesn't need to be static
Look at point 1
Singleton instance must be static (of course) and must be accessed by a static method; in addiction must have a private constructor to prevent new instance to be created
public class SingletonNumber10 {
public static SingletonNumber10 getInstance() {
if(null == instance) {
instance = new SingletonNumber10(10);
}
return instance;
}
private int number;
private static SingletonNumber10 instance;
private SingletonNumber10(int number) {
this.number = number;
}
public int getNumber() {
return this.number;
}
public static void main(String[] args) {
System.out.println(SingletonNumber10.getInstance());
System.out.println(SingletonNumber10.getInstance());
}
}
A singleton holds a private static instance of itself.
Not always, in fact, that's not even the best way to do it in Java.
public enum Director {
INSTANCE;
public int getFive() {
return 5;
}
}
Is a perfectly valid singleton, and is far more likely to remain the only copy in existence than a class that holds a private static instance of itself.
1. Should it's members also be static
No, the members should not be static, because then there is no need for a class, and therefore no need for that class to be a singleton. All static routines are subject to code maintenance issues, similar to C / C++ functions. Even though with singletons you won't have multiple instances to deal with, having the method off of an instance provides you with certain abilities to morph the code in the future.
2. If the answer to 1. is unequivocally yes.
It's not, so no need to answer #2.
3. Is the private instance needed because the JVM needs a
referable object (THE singleton) to hold on to for the
length of its (JVM's) life?
No, the private instance is needed because you have to have some ability to determine if the constructor was called previous to the access. This is typically done by checking to see if the instance variable is null. With race conditions and class loader considerations, it is incredibly difficult to make such code correct. Using the enum technique, you can ensure that there is only on instance, as the JVM internals are not subject to the same kinds of race conditions, and even if they were, only one instance is guaranteed to be presented to the program environment.
There is a requirement to make multiple concurrent remote calls within
a tomcat hosted web application (the app utilizes GWT for some components,
so I can utilize a servlet for this aforementioned requirement if a good
solution requires this). Currently, I create an executor service with a cached
thread pool into which I pass my callables (each callable containing an endpoint
configuration), for each individual process flow that requires such calls. To
me it would make sense if the thread pool was shared by multiple flows, instead
of spawning pools of their own. Would a singleton holding a static thread pool be
a good solution for this?
It depends. What are the threads in the pool going to be doing? If it's a thread to handle the task, eventually they will all get tied up with the long running tasks, possibly starving other critical processing. If you have a very large number of tasks to perform, perhaps restructuring the processing similar to the call-back patterns used in NIO might actually give you better performance (where one thread handles dispatching of call-backs for many tasks, without a pool).
Until you present a second way of handling the problem, or make more details of the operating environment available, the only solution presented is typically a good solution.
PS. Please don't expand on the details of the environment. The question submission process is easy, so if you want to expand on the second part, resubmit it as an independent question.

Singleton v/s class with static members & methods in Java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between static class and singleton pattern?
Why would one ever require one and only one instance? Same purpose can be achieved using classes with static member variables and static methods.
As far as I can find out, there might be two possible answers to it -
When your class needs to have state and you want only one object of it. From the design point of view, class with static methods & variables are considered to be the Utility classes and shouldn't be keeping any state.
If your class needs to take part in polymorphism and you want only one object of the class(es) which are in the inheritance tree.
It would be really helpful if someone can provide an example from real life scenario or from any Java API where Singleton objects need to participate in Polymorphism / Inheritance?
Collections.emptySet() is a typical example of a singleton that can't be implemented as a static class since, obviously, its goal is to be an instance of the java.util.Set interface. It's not costly to create, but it would be stupid to create a new instance each time an empty set is needed, since the unique instance can be reused.
Classes that perform logging or common access to data bases frequently follow the Singleton pattern. Basically anything that should have instance methods and that is costly to construct.
Scope and behavior are different concerns and should NOT be mixed. You may want your object to be available per use, per thread, per web request, per session or global (Singleton). The reasons for making these adjustments are likely due to resource management and ultimately performance. The behavior inside your class shouldn't have to change if you change its scope.
Singleton is pattern for taking a regular object and controlling its scope with just a little bit of bolt-on code. Ideally though, you really shouldn't really deal with scope at all inside your object and delegate that to a factory or container.
My answer is quite short but it's enough to use exactly common singleton instead of it's static implementation. The answer is:
Popular paradigm (yes it is!)
Threads (synchronization etc.)
Interface implementation (your static class has some restrictions)

sharing an object application wide

It's common to have an object used application wide.
What are the different patterns / models / ways to share an object through an application?
Is defining a "main class", then setting a member variable and extending all other classes from this "main class" a good way? Is creating a static class probably the better and cleaner way? What's your prefered pattern?
It's common to have an object used application wide. What are the different patterns / models / ways to share an object through an application?
One common way is to use the singleton pattern. I would avoid that though.
Is defining a "main class", then setting a member variable and extending all other classes from this "main class" a good way
Absolutely not. Aside from anything else, if it's an instance variable then it wouldn't be "shared" with instances of your other classes anyway. It's also a complete abuse of inheritance which would certainly bite you hard in any application of significant size - your other classes wouldn't logically have an inheritance relationship with your "main" class, would they? As a general rule, inheritance should only be used when it's really appropriate - not to achieve a quick fix.
What's your prefered pattern?
Dependency injection. When your application starts up, create all the appropriate objects which need to know about each other, and tell them (usually in the constructor) about their dependencies. Several different objects can all depend on the same object if that's appropriate. You can use one of the many dependency injection frameworks available to achieve this easily.
Dependency injection generally works better than using singletons because:
The class itself doesn't know whether or not the dependency is actually shared; why should it care?
Global state makes unit testing harder
Each class makes its dependencies clearer when they're declared - it's then easier to navigate around the application and see how the classes relate to each other.
Singletons and global factories are more appropriate when they're for things like logging - but even then, it means it's relatively hard to test the logging aspects of a class. It's a lot simpler to create a dependency which does what you need it to, and pass that to the object under test, than it is to add ways of messing around with a singleton (which usually remains "fixed" after initialization).
If you use a framework like Spring which has dependency injection, you can get all the benefits of "global" objects for free without needing to explicitly define them. You just create a reference to them in your application context and you can inject them into any object you'd like without worrying about issues with synchronizing.
Singleton pattern, AFAIK the preferable way in software engineering.
I believe what you are looking for is the Singleton Pattern. With this pattern you are ensured that only one instance of a class can be created in memory.
Example:
public class mySingletonClass {
private static mySingletonClass singleObject;
// Note that the constructor is private to prevent more than one
//instance of the class
private SingletonObjectDemo() {
// Optional Code
}
public static mySingletonClass getSingletonObject() {
if (singleObject == null) {
singleObject = new mySingletonClass();
}
return singleObject;
}
}
That said, you should try to avoid using it; but there are some acceptable cases, one of which is here.

Why use a singleton instead of static methods?

I have never found good answers to these simple questions about helper/utility classes:
Why would I create a singleton (stateless) instead of using static methods?
Why would an object instance be needed if an object has no state?
Often, singletons are used to introduce some kind of global state to an application. (More often than really necessary, to be honest, but that's a topic for another time.)
However, there are a few corner cases where even a stateless singleton can be useful:
You expect to extend it with state in the foreseeable future.
You need an object instance for some particular technical reason. Example: Synchonization objects for the C# lock or the Java synchronized statement.
You need inheritance, i.e., you want to be able to easily replace your singleton with another one using the same interface but a different implementation.Example: The Toolkit.getDefaultToolkit() method in Java will return a singleton whose exact type is system dependent.
You want reference equality for a sentinel value.Example: DBNull.Value in C#.
I could see a case for a stateless singleton being used instead of a static methods class, namely for Dependency Injection.
If you have a helper class of utility functions that you're using directly, it creates a hidden dependency; you have no control over who can use it, or where. Injecting that same helper class via a stateless singleton instance lets you control where and how it's being used, and replace it / mock it / etc. when you need to.
Making it a singleton instance simply ensures that you're not allocating any more objects of the type than necessary (since you only ever need one).
Actually i've found another answer not mentionned here: static methods are harder to test.
It seems most test frameworks work great for mocking instance methods but many of them no not handle in a decent way the mock of static methods.
In most programming languages classes elude a lot of the type system. While a class, with its static methods and variables is an object, it very often cannot implement an interface or extend other classes. For that reason, it cannot be used in a polymorphic manner, since it cannot be the subtype of another type. For example, if you have an interface IFooable, that is required by several method signatures of other classes, the class object StaticFoo cannot be used in place of IFooable, whereas FooSingleton.getInstance() can (assuming, FooSingleton implements IFooable).
Please note, that, as I commented on Heinzi's answer, a singleton is a pattern to control instantiation. It replaces new Class() with Class.getInstance(), which gives the author of Class more control over instances, which he can use to prevent the creation of unneccessary instances. The singleton is just a very special case of the factory pattern and should be treated as such. Common use makes it rather the special case of global registries, which often ends up bad, because global registries should not be used just willy-nilly.
If you plan to provide global helper functions, then static methods will work just fine. The class will not act as class, but rather just as a namespace. I suggest, you preserve high cohesion, or you might end up with weirdest coupling issues.
greetz
back2dos
There is a trade-off between using which one. Singletons may or may not have state and they refer to objects. If they are not keeping state and only used for global access, then static is better as these methods will be faster. But if you want to utilize objects and OOP concepts (Inheritance polymorphism), then singleton is better.
Consider an example: java.lang.Runtime is a singleton class in java. This class allows different implementations for each JVM. The implementation is single per JVM. If this class would have been static, we cannot pass different implementations based on JVM.
I found this link really helpful: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html?
Hope it helps!!
Singleton is not stateless, it holds the global state.
Some reasons which I can think of using Singleton are:
To avoid memory leaks
To provide the same state for all modules in an application e.g database connection
For me "Want Object State use Singleton, Want Function use static method"
It depends on what you want. Whenever you want the object state (e.g. Polymorphism like Null state instead of null, or default state), singleton is the appropriate choice for you whereas the static method use when you need function (Receive inputs then return an output).
I recommend for the singleton case, it should be always the same state after it is instantiated. It should neither be clonable, nor receive any value to set into (except static configuration from the file e.g. properties file in java).
P.S. The performance between these 2 are different in milliseconds, so focus on Architecture first.
According to GoF’s book Design Patterns, chapter ‘Singleton’, class operations have the following drawbacks compared to singletons (bold emphasis mine):
More flexible than class operations. Another way to package singleton’s functionality is to use class operations (that is, static member functions in C++ or class methods in Smalltalk). But both of these language techniques make it hard to change a design to allow more than one instance of a class. Moreover, static member functions in C++ are never virtual, so subclasses can’t override them polymorphically.

In Java, is there any disadvantage to static methods on a class?

Lets assume that a rule (or rule of thumb, anyway), has been imposed in my coding environment that any method on a class that doesn't use, modify, or otherwise need any instance variables to do its work, be made static. Is there any inherent compile time, runtime, or any other disadvantage to doing this?
(edited for further clarifications)
I know the question was somewhat open ended and vague so I apologize for that. My intent in asking was in the context of mostly "helper" methods. Utility classes (with private CTORs so they can't be instantiated) as holders for static methods we already do. My question here was more in line of these little methods that HELP OUT the main class API.
I might have 4 or 5 main API/instance methods on a class that do the real work, but in the course of doing so they share some common functionality that might only be working on the input parameters to the API method, and not internal state. THESE are the code sections I typically pull out into their own helper methods, and if they don't need to access the class' state, make them static.
My question was thus, is this inherently a bad idea, and if so, why? (Or why not?)
In my opinion, there are four reasons to avoid static methods in Java. This is not to say that static methods are never applicable, only to say that they should generally be avoided.
As others have pointed out, static methods cannot be mocked out in a unit test. If a class is depending on, say, DatabaseUtils.createConnection(), then that dependent class, and any classes that depend on it, will be almost impossible to test without actually having a database or some sort of "testing" flag in DatabaseUtils. In the latter case, it sounds like you actually have two implementations of a DatabaseConnectionProvider interface -- see the next point.
If you have a static method, its behavior applies to all classes, everywhere. The only way to alter its behavior conditionally is to pass in a flag as a parameter to the method or set a static flag somewhere. The problem with the first approach is that it changes the signature for every caller, and quickly becomes cumbersome as more and more flags are added. The problem with the second approach is that you end up with code like this all over the place:
boolean oldFlag = MyUtils.getFlag();
MyUtils.someMethod();
MyUtils.setFlag( oldFlag );
One example of a common library that has run into this problem is Apache Commons Lang: see StringUtilsBean and so forth.
Objects are loaded once per ClassLoader, which means that you could actually have multiple copies of your static methods and static variables around unwittingly, which can cause problems. This usually doesn't matter as much with instance methods, because the objects are ephemeral.
If you have static methods that reference static variables, those stay around for the life of the classloader and never get garbage collected. If these accumulate information (e.g. caches) and you are not careful, you can run into "memory leaks" in your application. If you use instance methods instead, the objects tend to be shorter-lived and so are garbage-collected after a while. Of course, you can still get into memory leaks with instance methods too! But it's less of a problem.
Hope that helps!
The main disadvantage is that you cannot swap, override or choose method implementations at runtime.
The performance advantage is likely negligible. Use static methods for anything that's not state dependent. This clarifies the code, as you can immediately see with a static method call that there's no instance state involved.
Disadvantage -> Static
Members are part of class and thus remain in memory till application terminates.and can't be ever garbage collected. Using excess of static members sometime predicts that you fail to design your product and trying to cop of with static /procedural programming. It denotes that object oriented design is compromised.This can result in memory over flow.
I really like this question as this has been a point I have been debating for last 4 years in my professional life. Static method make a lot of sense for classes which are not carrying any state. But lately I have been revised my though somewhat.
Utility classes having static methods is a good idea.
Service classes carrying business logic can be stateless in many cases. Initially I always added static methods in them, but then when I gained more familiarity with Spring framework (and some more general reading), I realized these methods become untestable as an independent unit as u cannot inject mock services easily into this class. E.g. A static method calling another static method in another class, there is no way JUnit test can short circuit tis path by injecting a dummy implementation at run time.
So I kind of settled to the thought that having utility static methods which do not need to call other classes or methods pretty much can be static. But service classes in general should be non static. This allows you to leverage OOPs features like overriding.
Also having a singleton instance class helps us to make a class pretty much like a static class still use OOPs concepts.
It's all a question of context. Some people have already given examples where static is absolutely preferable, such as when writing utility functions with no conceivable state. For example, if you are writing a collection of different sort algorithms to be used on arrays, making your method anything but static just confuses the situation. Any programmer reading your code would have to ask, why did you NOT make it static, and would have to look to see if you are doing something stateful to the object.
public class Sorting {
public static void quiksort(int [] array) {}
public static void heapsort(int[] array) { }
}
Having said that, there are many people who write code of some kind, and insist that they have some special one-off code, only to find later that it isn't so. For example, you want to calculate statistics on a variable. So you write:
public class Stats {
public static void printStats(float[] data) { }
}
The first element of bad design here is that the programmer intends to just print out the results, rather than generically use them. Embedding I/O in computation is terrible for reuse. However, the next problem is that this general purpose routine should be computing max, min, mean, variance, etc. and storing it somewhere. Where? In the state of an object. If it were really a one-off, you could make it static, but of course, you are going to find that you want to compute the mean of two different things, and then it's awfully nice if you can just instantiate the object multiple times.
public class Stats {
private double min,max,mean,var;
public void compute(float data[]) { ... }
public double getMin() { return min; }
public double
}
The knee jerk reaction against static is often the reaction of programmers to the stupidity of doing this sort of thing statically, since it's easier to just say never do that than actually explain which cases are ok, and which are stupid.
Note that in this case, I am actually using the object as a kind of special-purpose pass by reference, because Java is so obnoxious in that regard. In C++, this sort of thing could have been a function, with whatever state passed as references. But even in C++, the same rules apply, it's just that Java forces us to use objects more because of the lack of pass by reference.
As far as performance goes, the biggest performance increase of switching from a regular method is actually avoiding the dynamic polymorphic check which is the default in java, and which in C++ is specified manually with virtual.
When I tried last there was a 3:1 advantage of calling a final method over a regular method, but no discernible for calling static functions over final.
Note that if you call one method from another, the JIT is often smart enough to inline the code, in which case there is no call at all, which is why making any statement about exactly how much you save is extremely dangerous. All you can say is that when the compiler has to call a function, it can't hurt if it can call one like static or final which requires less computation.
The main problem you may face is, you won't be able to provide a new implementation if needed.
If you still have doubts ( whether your implementation may change in the future or not ) you can always use a private instance underneath with the actual implementation:
class StringUtil {
private static StringUtil impl = new DefaultStringUtil();
public static String nullOrValue( String s ) {
return impl.doNullOrValue();
}
... rest omitted
}
If for "some" reason, you need to change the implementation class you may offer:
class StringUtil {
private static StringUtil impl = new ExoticStringUtil();
public static String nullOrValue( String s ) {
return impl.doNullOrValue(s);
}
... rest omitted
}
But may be excessive in some circumstances.
No, actually the reason for that advice is that it provides a performance advantage. Static methods can be called with less overhead so any method that doesn't need a reference to this ought to be made static.
No there is no disadvantages, rather when you are not accessing any instance members in the method then there is no meaning of having it as an instance method. It is good programming skill to have it as a static method.
and adding to that you don't have to create any instances to access these methods and thus saving a memory and garbage collecting time.
In order to call the static methods you don't need to create class objects. The method is available immediately.
Assuming the class is already loaded. Otherwise there's a bit of a wait. :-)
I think of static as a good way to separate the functional code from procedural/state-setting code. The functional code typically needs no extension and changes only when there are bugs.
There's also the use of static as an access-control mechanism--such as with singletons.
One disadvantage is if your static methods are general and distributed in different classes as far as usage is concerned. You might consider putting all static methods that are general in a utility class.
There shouldn't be any disadvantages--there may even be a slight advantage in performance (although it wouldn't be measurable) since the dynamic lookup can be avoided.
It's nice to tag functions as functions instead of having them look like Methods--(and static "Methods" ARE functions, not methods--that's actually by definition).
In general a static method is a bad OO code smell--it probably means that your OO model isn't fully integrated. This happens all the time with libraries that can't know about the code that will be using it, but in integrated non-library code static methods should be examined to evaluate which of it's parameters it's most closely associated with--there is a good chance it should be a member of that class.
If a static method just takes native values, then you're probably missing a handful of classes; you should also keep passing native variables or library objects (like collections) to a minimum--instead containing them in classes with business logic.
I guess what I'm saying is that if this is really an issue, you might want to re-examine your modeling practices--statics should be so rare that this isn't even an issue.
As others have said, it provides a slight performance advantage and is good programming practice. The only exception is when the method needs to be an instance method for overriding purposes, but those are usually easily recognised. For example if a class provides default behaviour of an instance method, that happens not to need instance variables, that clearly can't be made static.
In general:
You should be writing your software to take advantage of interfaces and not implementations. Who's to say that "now" you won't use some instance variable, but in the future you will? An example of coding to interfaces...
ArrayList badList = new ArrayList(); //bad
List goodList = new ArrayList(); //good
You should be allowed to swap implementations, especially for mocking & testing. Spring dependency injection is pretty nice in this respect. Just inject the implementation from Spring and bingo you have pretty much a "static" (well, singleton) method...
Now, those types of APIs that are purely "utility" in purpose (i.e., Apache Commons Lang) are the exception here because I believe that most (if not all) of the implementations are static. In this situation, what are the odds that you will want to ever swap Apache Commons out for another API?
Specifically:
How would you elegantly handle the "staticness" of your implementation when you're targeting, say, a Websphere vs. Tomcat deployment? I'm sure there would be an instance (no pun intended) of when your implementation would differ between the two...and relying on a static method in one of those specific implementations might be dangerous...

Categories