This question already has answers here:
Constructors vs Factory Methods [closed]
(10 answers)
When to use a Constructor and when to use getInstance() method (static factory methods)?
(6 answers)
Closed 9 years ago.
Well, i have a very conceptual question. A lot of things look like fabrics, where i'm not sure where the great benefit is.
As example
public class MyObject {
public MyObject() {
}
public static MyObject create() {
return new MyObject();
}
public void doSomething(){
// some code...
};
}
The only benefits from my point of view is a bid less to code. In my opinion, no impact on performance happens. Are there other benefits?
MyObject myobject = new MyObject();
or
MyObjecct myobject = MyObject.create();
Thanks
You are correct in that there is no significant performance difference; and the reasons for using this form are primarily about readability of the code.
In general if you use the static create function you would declare the constructor private thus ensuring your users can ONLY create objects with the static function
In general I don't think the static create adds much to code, ad for ordinary everyday objects a new is probably clearer and more direct.
However there are some cases that I think the static constructor is useful:
For construction of large complicated objects, especially objects involving a lot of complexity in initialisation - often a simple constructor misleads library users into assuming the construction task is fast and easy.
If you have multiple constructors with ambiguous parameters you can use the static function name to make it more readable, for example you might have createFromFile(String FileName) and createFromJSONEncoding(String Data)
You want to control if a new object is ACTUALLY created - for example if this is a read-only resource you might be keeping a buffer of the resources already open and if the library user requests the same resource twice you can simply give them an already cached copy (as opposed to making a new duplicate copy)
Joshua Bloch addresses this concern in Effective Java, Chapter 2, Item 1: Consider static factory methods instead of constructors; here are a few highlights:
"One advantage of static factory methods is that, unlike constructors, they
have names." -- you can't have two different constructors that take an int argument, but you can have two static factory methods called createWithAge(int age) and createWithHeight(int height)
"A second advantage of static factory methods is that, unlike constructors,
they are not required to create a new object each time they’re invoked."
"A third advantage of static factory methods is that, unlike constructors,
they can return an object of any subtype of their return type."
As you see, the concern is hardly related to performance (except for reusing cached instances), but mainly to object oriented design.
DISCLAIMER: Oops, I just saw the same answer (far better explained) already being posted for a different question: https://stackoverflow.com/a/3169644/262683. My bad...
There is no answer to this question.
The fact is that both patterns are legitimate ways to construct objects that are applicable to particular situations.
Static factory methods are important in situations where instance control is very important, such as in systems that maintain object caches or pools.
The new operator is apt for its simplicity and is rather important for classes that are designed for inheritance.
You are asking what is the best practice. The answer is that the best practice depends on your goals and, as always for questions of this sort, the best practice is that which makes smart use of available tools to reach a scalable and maintainable solution.
I suggest that this question be closed.
The case I see where you might need to use create:
You have to control creation of every instance of your class. For example, you count number of objects created or link them somehow and if number of instances reached your desired maximum throw exception.
Also factory pattern might be interesting to read about.
If you're not sure, just create via new
And if you choose to go with create you'd probably want to make your constructor private
It is a (simplistic) Factory Pattern. Please check the applicability section of the Wikipedia entry to see where it is used.
Now when you don't wan't any other class to create your class' object then you make you class constructor private:
private MyObject()
now any class wanting to create your class object will have to do this :
MyObjecct myobject = MyObject.create();
Because now doing this inside some other class MyObject myobject = new MyObject(); will cause compiler error.
Related
This question already has answers here:
Constructors vs Factory Methods [closed]
(10 answers)
Closed 3 years ago.
In the new date package in Java 8, we changed from using "new Date()" to "LocalDate.of()".
Date d = new Date(year, month, dayOfMonth); //Old way
LocalDate d2 = LocalDate.of(year, month, dayOfMonth); //new way
When you want a new object you usually use the new keyword. This is an intuitive way to create a new object.
Sometimes, when you need a singleton with delayed initialization you can use a static method to get the instance. In this case you must call it getInstance() so developers know what to expect.
This new syntax makes the code less intuitive. It forces you to learn how to deal with specific objects instead of simply using them.
Are there any good reasons under the hood for this change?
Usually static factory methods are preferred to constructors for several reasons,
They have a name and that makes your code much more readable.
static factory methods can have covariant return types, but
constructor can't. This allows your API users to work with the interface, not the implementation, allowing you more room to change the concrete types in future releases. Also it reduces the conceptual surface area of the API too.
Unlike constructors, static factory methods can do certain
optimizations. On the contrary, every time you call a constructor,
you expect it to return a new object. For an instance, check out
the implementation of the static factory method
Collections.emptyList();
public static final List EMPTY_LIST = new EmptyList<>();
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
It eagerly creates a singleton list and returns it on every invocation saving unnecessary overhead that would occur when constructors were used.
Due to the above reasons, static factories are preferred to constructors in today's programming. However, you can still use the new keyword with constructors as circumstances warrant.
There is a problem with new: your code depends on the concrete class. Thus changing/evolving the code is a more difficult task.
A factory is much more manageable because (1) the user code is not dependant on the concrete type (2) the code that choose the concrete type is in a single place. Then the final code is much more secure/evolvable, etc.
getInstance() is not a good name for a factory, it is more the name of a singleton method. "get" is not intended to create something, just to get something already existant. createInstance or create is much more explicit for factories (many of them, even in Java are called such - examine createImage and alike). But alas, for reasons explicited by #slaw in comments, you need to be more precise to help the user choose between argument semantic, thus things like createFromYears, createFromMinutes, etc. That may be slightly verbose, then of seems to be a good compromise. Finally it is more easy (IMHO) to use of*() than createImage() with a lot of parameters to explain what arguments are...
There a design pattern called Fluent interface, which allows "chaining" of methods, see Wikipedia. It's supposed to very readable, imitating natural speech ("get x of y with z").
It's not especially chaining in your example (given it consists of only one method call), but it makes sense to use the same paradigm everywhere.
I'd like to create a few immutable objects for my codebase. What's the best way to really deliver the message that a given class is intended to be immutable? Should I make all of my fields final, and initialize during object construction? (This seems really awkward...) Should I create some Immutable interface, and have objects implement it? (Since Java doesn't have some standard interface behind this, I thought they had some other way of dealing with it.) What's the standard way this is dealt with? (If it's simply done by adding a bunch of comments around the fields exclaiming that they shouldn't be modified once initialized, that's fine too.)
Should I make all of my fields final, and initialize during object construction?
Yes. And ensure that those types are themselves immutable, or that you create copies when you return values from getter methods. And make the class itself final. (Otherwise your class on its own may be immutable, but that doesn't mean that any instance of your class would be immutable - because it could be an instance of a mutable subclass.)
(This seems really awkward...)
It's hard to know what to suggest without knowing how you find it to be awkward - but the builder pattern can often be useful. I usually use a nested static class for that, often with a static factory method. So you end up with:
Foo foo = Foo.newBuilder()
.setName("asd")
.setPoints(10)
.setOtherThings("whatever")
.build();
Yes and no. Making all fields final is not a guarantee in and of itself. If you'd like to get really in-depth with this there are a number of chapters in Effective Java by Joshua Bloch dealing with immutability and the considerations involved. Item 15 in Effective Java covers the bulk of it and references the other items in question.
He offers these five steps:
Don’t provide any methods that modify the object’s state (known as muta-
tors).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
Ensure exclusive access to any mutable components.
One way to learn how to do all of this is to see how the language designers make classes immutable by reviewing the source for classes like String which are immutable (for example see http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java).
Write a unit test that will fail if your coworkers make the class mutable.
Using Mutability Detector, you can write a test like this:
import static org.mutabilitydetector.unittesting.MutabilityAssert.assertImmutable;
#Test public void isImmutable() {
assertImmutable(MyImmutableThing.class)
}
If a coworker comes along, and, for example, adds a setter method to your class, the test will fail. Your use case is one of the core purposes of Mutability Detector.
Disclaimer: I wrote it.
This question already has answers here:
Why do we need immutable class?
(20 answers)
Closed 8 years ago.
I found an article with an interesting piece of code:
public class Employee {
private String firstName;
private String lastName;
//private default constructor
private Employee(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public static Employee valueOf (String firstName, String lastName) {
return new Employee(firstName, lastName);
}
}
I am really curious in understanding the advantage of creating this kind of classes.
I understand that here that an object of this class would be immutable, because there is no way of changing its variable values once initialized. I never did something like this before, and i dont really understand the advantage of it.
Why is it a good practice?
Could you name a situation where this approach can be used?
What about constants or read only variables? Is not that very similar?
In the article says, that this is not good for the performance of the application. But why?
The example you have mentioned is of an Immutable Objects. Its widely used concepts in programming languages.
Quoting from the link above. The advantages are
are simple to construct, test, and use
are automatically thread-safe and have no synchronization issues
do not need a copy constructor
do not need an implementation of clone
allow hashCode to use lazy initialization, and to cache its return value
do not need to be copied defensively when used as a field
make good Map keys and Set elements (these objects must not change state while in the collection)
have their class invariant established once upon construction, and it never needs to be checked again
always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object - throws an exception, it's never left in an undesirable or indeterminate state
Immutable classes are:
thread-safe by default (concurrent write never occurs)
cachable
You can read a lot about them in the conext of the language Java in Effective Java.
-Why is it a good practice?
Because you can pass the class around and be sure it will never be modified by a "rogue" code. Same for Java Strings, they're immutable.
-Could you name a situation where this approach can be used?
It's very useful on big projects where many teams work together, or when designing a framework or an API. In these situations, since you're not responsible of parts of the code, you can never trust that an object you pass to other parts of the code won't be altered. Use immutability if you need to ensure the object won't be modified.
-What about constants or read only variables? Is not that very similar?
Not in Java because we have neither const nor read-only. All we have is the final keyword that ensures an object reference won't be modified beyond first assignment. But the underlying object can still be modified even if the reference can not. Immutable classes ensure an object state won't be altered after creation.
-In the article says, that this is not good for the performance of the application. But why?
Because every time you need to modify the object, you need to create new instances. Same for Strings, you can't do myString.append("42"), you need to do myString = myString+"42", which creates a new String object.
The main advantage of immutable classes is thread-safety. Most problems with threading come from having shared, mutable state. By making objects immutable, it is far easier to reason about them especially in multi-threaded environments.
The article says "creating immutable objects can hit performance of an app." I'm not sure why it says this. It's totally wrong. There is nothing inherent about immutable objects that could affect the application's performance.
If you are using hashTables, having immutable objects is good because you dont need to recalculate the hashCode when the state of the object changes(as they are unchangeable).
The article says:
To make a class immutable you can define its all constructors private and then create a public static method to initialize and object and return it.
Actually, that is wrong. These two concepts aren't really related.
E.g. you could declare the constructor of your Employee class public and it would still be immutable.
Or you could pass a mutable Object as a parameter to the factory method or declare a mutator method
-> Employee would be mutable although you're using a factory method and a private constructor.
In your given example he is making constructor as private, and thus controlling the object creation from outside directly.
Meaning : Since constructor is private, you can't do
Employee e = new Employee("steve","jobs");
from outside of this class.
By doing so, the programmer of this class, is taking object creation for this class into his control.
This is very beneficial, when you are writing very huge Server side class, for which creating an object may take lot of memory due to its size. Now how do you protect from your clients, of not creating more objects for your class?
Answer for above question is simple, by making your constructor private and you yourself creating objects for your class when ever you want in static method.
Note: Static methods can be accessed directly by using class name.
Note: This kind of design patterns will be heavily used in singleton design patterns, which requires only one object for a given 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...
Back couple of months ago I attended a presentation hosted by two representative of an independent software development company. It was mainly about good software design and practices.
The two guys were talking mainly about Java and I remember them saying, that in some circumstances it is very good practice to use getInstanceOf() instead of the constructor. It had something to do with making always calling getInstanceOf() from different classes rather than constructor and how it was it is much better approach on larger scale projects.
As you can see I cannot remember much from it now :/ but I remember that the arguments that they used were really convincing. I wonder if any of you ever came across such a design and when, would you say, is it useful? Or do you think it isn't at all?
Consider static factory methods instead of constructors—Joshua Bloch
They were probably talking about the static factory method pattern (and not the reflection API method for dynamically creating objects).
There at several advantages of a method such as getInstanceOf() over a constructor and using new. The static factory method can...
Choose to create a different sub-class of the main class if that is desirable in certain cases (based on environmental conditions, such as properties and other objects/singletons, or method parameters).
Choose to return an existing object instead of creating one. For an example of this, see Boolean.valueOf(boolean) in the Java API.
Do the same thing as the constructor - just return a new instance of the class itself.
Provide many different kinds of ways to construct a new object and name those methods so they are less confusing (e.g. try this with constructors and you soon have many different overloads). Sometimes this is not even possible with constructors if you need to be able to create an instance two different ways but only need the same type of parameters. Example:
// This class will not compile!
public class MyClass {
public MyClass(String name, int max) {
//init here
}
public MyClass(String name, int age) {
// init here
}
}
// This class will compile.
public class MyClass2 {
private MyClass2() {
}
public static MyClass2 getInstanceOfMax(String name, int max) {
MyClass2 m2 = new MyClass2();
// init here
return m2;
}
public static MyClass2 getInstanceOfAge(String name, int age) {
MyClass2 m2 = new MyClass2();
// init here
return m2;
}
}
Do any combination of the above.
And, on top of all that it hides the detail of instantiating an instance from other classes and so can be varied in the future (construction encapsulation).
A constructor can only ever create a new instance of an object of the exact type requested. It cannot be varied later.
Some disadvantages of this pattern are:
The factory methods are static so cannot be inherited in sub-classes; a parent constructor is easily accessible to sub-classes.
The factory method names can vary widely and this could be confusing for some (new) developers.
You also asked for personal experience. Yes, I frequently use both patterns. For most classes constructor but when there are much more advanced needs then I use the static factory. I also work on projects in other languages (proprietary, but similar to Java) where this form of construction is mandated.
I suspect you mean the newInstance method on the Class class. You would invoke it like this: MyClass foo = MyClass.newInstance();
This form of object instantiation is popular in creational patterns; it's useful when you want to specify the concrete, runtime type of an object externally, such as in a properties or XML file.
If Drew is right, newInstance() is part of the Java Reflection API. So it is not as natural as using a constructor.
Why it would be recommended to use it on a large project may come with the fact that it leads to Java Bean programming style and clearly makes the creation of the object something particular. On large project, creating object shouldn't be a cross-cutting concern but rather a clearly identified responsibility, often from one source / factory. But IMHO, you get all of those advantages and many more with IoC pattern.