简体   繁体   中英

Consider providing static factory methods insteads of constructors

The normal way for a class to allow a client to obtain an instance is to provide a public contructor. Another way to do that is providing a public static factory method, which is simply a static method that returns an instance of the class. What are pros and cons by using static factory method?

This chapter from the book Effective Java explains it well: Consider Static Factory instead of Constructors . It explains all the pros and cons for both of them in the best way you can understand.

Just to quote the advantages and disadvantages from the book:

Advantages :

  • One advantage of static factory methods is that, unlike constructors, they have names.
  • 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.
  • A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances (This one can be ignored in Java 7)

Disadvantages :

  • The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed

  • A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.

You can study them in more detail in the link I gave.

The only con is more code to write, but it's still there, so you need at least some benefit for having a factory.

Factory is not required to always return a new object, that's one advantage.

Factory can instantiate any subclass it wants, that's another.

In my projects I often add factories just to make my client code look nicer. If you use a static import for the factory method, the call looks nicer than a new expression, especially if the name of class is not particularly concise, which is often the case.

Advantage: -One advantages of static factory methods is that, unlike constructors, they have names. -A second advantages of static factory methods is that, unlike constructors, they are not equired to create a new object each time they're invoked. -They can return an object of any subtype of their return type. Disavantage: -The main disadvatage of static factory methods is that classes without public or protected constructors cannot be subclassed. -They are not readily distinguishable from other static methods.

I would say to the original author of the question that static factory methods are a tool. Like all tools, they have uses for which they are best suited, other uses for which they are passable, and other things for which they are poorly adaptable. To cite a real world example, a hammer is great at driving nails, adequate for jacking open a sealed crate with the nail-removing end (a crowbar would still be much better), but useless for planing down a rough surface.

Factory methods refer to one of a set of creational design patterns, ie paradigms for creating objects. In some creational design patterns such as "Builder" and "Prototype", the use of the new operator for object creation isn't merely discouraged, it's considered harmful to the overall design goal. The creational design patterns that people talk about are...

  1. Factory methods
  2. Abstract factory methods
  3. Singleton pattern
  4. Builder
  5. Prototype

Generally speaking, a factory method is used to create an object from a group of related subclasses based on data that the user or designer supplies to the method. More concretely, though, a static factory method gives you control over object creation even when the object that is returned is the same every time. This can be very important when, for example, the process of creating an object is very expensive in terms of time and resources. In a situation like this, using a new operator to create objects might incur a terrible performance penalty.

One solution might be to maintain a reusable pool of objects. By using a static factory method, the application designer can provide logic to return a free, existing object if one is available. This would then save the potentially high cost of building a new object. This is exactly what is done with network database connections by connection managers that provide "connection pooling." Rather than build a new database connection every single time a client makes a request, connection objects are assigned from a pool of existing objects if one is available. This is an example of a circumstance in which using the new operator would actually be harmful to application performance and would undermine the software engineer's design goals.

A good time to consider using a factory method for creating objects rather than the new operator would be:

  • The object that would be created is belongs to one of a few possible subclasses of objects that could be created depending on supplied data.
  • There is a good reason to have more control over the object creation process than would be possible in a constructor, eg. the Singleton design pattern requires a static factory method.

A bad time to consider using a factory method would be:

  • Simple, lightweight objects

It's all about enumerating the software design problems, and then deciding which tools are best for solving it. Static factory methods are good for some things and not so good for others ... just like any tool.

One of the advantages is you can give the factory methods understandable names. It will help you easy to understand what function's work in your function and easy to maintain your code in the future. Take a look for this example, hope that it will help you.

    public class Contact {

    private Contact(String displayName, String phoneNumber, int contactType){
    //do something
    }

    //then we will have few functon static to get constructor private
    public static createContactUnknow(String phoneNumber){
        return new Contact("","00000000",0);
    }

    public static createContactValid(String displayName, String phoneNumber, int contactType){
        return new Contact(displayName, phoneNumber, contactType);
    }
}

    //then
    Contact myGirlFriend = Contact.createContactValid("xxxx","000000",1);
    Contact unknowFriend = Contact.createContactUnknow("45454545");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM