The most widely used technique to allow other parts of our programs, to get objects of a certain type, is to create public constructors.
1: public class Product {
2: //..
3: public Product() {
4: }
5: //..
6: }
There is also another technique that provides various advantages and it would be highly recommendable for every programmer to know.
Classes can provide static factory methods. This methods are another way of returning instances.
1: public class Product {
2: //..
3: private int price;
4: private String description;
5:
6:
7: private Product(int price,String description) {
8: this.price = price;
9: this.description = description;
10: }
11: public static Product getNewProduct(int price,String description) {
12: return new Product(price,description);
13: }
14: //..
15: }
This are some of the advantages of using this technique:
Methods have names, so we can be more descriptive when constructing our objects.
Constructors cannot have names, but methods can, so by having this types of methods we can express more fluently how the object is constructed.
So instead of this:
1: new Product("ProductA",12);
We can create our objects like this:
1: Product.getNewProductWithValues("ProductA",12);
We don't have to create new objects if we don't want to.
Every time the keyword new is called, a new instance is created. In many occasions, specially in large systems, programmers need to be careful with resources. Some techniques to do that are:
-having cached objects and manage that they are cleaned properly.(Google for Singleton pattern).
-work with immutable objects which provide predefined state.(Google for Builder Pattern)
In the following piece of code you will see a very trivial implementation of a cached object:
1: public class Product {
2: private static Product product = new Product();
3: private Product() {
4: }
5: public static Product getDefaultProduct() {
6: return product;
7: }
8: }
This type of methods can have a subclass as a return type.
By using this type of methods, we can have big flexibility because we can use sub-classes as return types.
This is a very interesting feature which can allow us to create very powerful factories:
In the following example you can see how the static factory method can be used to create instances of subtypes or implementing types.
:
:
1: public final class ProductFactory {
2: public static Product getProduct(boolean condition) {
3: if(condition) {
4: return new HomeMadeProduct();
5: }
6: else {
7: return new FactoryMadeProduct();
8: }
9: }
10: }