What are static factory methods?

前端 未结 14 677
粉色の甜心
粉色の甜心 2020-11-22 06:08

What\'s a \"static factory\" method?

相关标签:
14条回答
  • 2020-11-22 06:41

    We avoid providing direct access to database connections because they're resource intensive. So we use a static factory method getDbConnection that creates a connection if we're below the limit. Otherwise, it tries to provide a "spare" connection, failing with an exception if there are none.

    public class DbConnection{
       private static final int MAX_CONNS = 100;
       private static int totalConnections = 0;
    
       private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();
    
       private DbConnection(){
         // ...
         totalConnections++;
       }
    
       public static DbConnection getDbConnection(){
    
         if(totalConnections < MAX_CONNS){
           return new DbConnection();
    
         }else if(availableConnections.size() > 0){
             DbConnection dbc = availableConnections.iterator().next();
             availableConnections.remove(dbc);
             return dbc;
    
         }else {
             throw new NoDbConnections();
         }
       }
    
       public static void returnDbConnection(DbConnection dbc){
         availableConnections.add(dbc);
         //...
       }
    }
    
    0 讨论(0)
  • 2020-11-22 06:41

    A static factory method is good when you want to ensure that only one single instance is going to return the concrete class to be used.

    For example, in a database connection class, you may want to have only one class create the database connection, so that if you decide to switch from Mysql to Oracle you can just change the logic in one class, and the rest of the application will use the new connection.

    If you want to implement database pooling, then that would also be done without affecting the rest of the application.

    It protects the rest of the application from changes that you may make to the factory, which is the purpose.

    The reason for it to be static is if you want to keep track of some limited resource (number of socket connections or file handles) then this class can keep track of how many have been passed out and returned, so you don't exhaust the limited resource.

    0 讨论(0)
  • 2020-11-22 06:43

    A factory method a method that abstracts away the instantiation of an object. Generally factories are useful when you know that you need a new instance of a class that implements some interface but you don't know the implementing class.

    This is useful when working with hierarchies of related classes, a good example of this would be a GUI toolkit. You could simply hard-code calls to the constructors for concrete implementations of each widget but if you ever wanted to swap one toolkit for another you'd have a lot of places to change. By using a factory you reduce the amount of code you would need to change.

    0 讨论(0)
  • 2020-11-22 06:45

    NOTE! "The static factory method is NOT the same as the Factory Method pattern" (c) Effective Java, Joshua Bloch.

    Factory Method: "Define an interface for creating an object, but let the classes which implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses" (c) GoF.

    "Static factory method is simply a static method that returns an instance of a class." (c) Effective Java, Joshua Bloch. Usually this method is inside a particular class.

    The difference:

    The key idea of static factory method is to gain control over object creation and delegate it from constructor to static method. The decision of object to be created is like in Abstract Factory made outside the method (in common case, but not always). While the key (!) idea of Factory Method is to delegate decision of what instance of class to create inside Factory Method. E.g. classic Singleton implementation is a special case of static factory method. Example of commonly used static factory methods:

    • valueOf
    • getInstance
    • newInstance
    0 讨论(0)
  • 2020-11-22 06:45

    One of the advantages of the static factory methods with private constructor(object creation must have been restricted for external classes to ensure instances are not created externally) is that you can create instance-controlled classes. And instance-controlled classes guarantee that no two equal distinct instances exist(a.equals(b) if and only if a==b) during your program is running that means you can check equality of objects with == operator instead of equals method, according to Effective java.

    The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types (Item 30) provide this guarantee.

    From Effective Java, Joshua Bloch(Item 1,page 6)

    0 讨论(0)
  • 2020-11-22 06:46

    The static factory method pattern is a way to encapsulate object creation. Without a factory method, you would simply call the class's constructor directly: Foo x = new Foo(). With this pattern, you would instead call the factory method: Foo x = Foo.create(). The constructors are marked private, so they cannot be called except from inside the class, and the factory method is marked as static so that it can be called without first having an object.

    There are a few advantages to this pattern. One is that the factory can choose from many subclasses (or implementers of an interface) and return that. This way the caller can specify the behavior desired via parameters, without having to know or understand a potentially complex class hierarchy.

    Another advantage is, as Matthew and James have pointed out, controlling access to a limited resource such as connections. This a way to implement pools of reusable objects - instead of building, using, and tearing down an object, if the construction and destruction are expensive processes it might make more sense to build them once and recycle them. The factory method can return an existing, unused instantiated object if it has one, or construct one if the object count is below some lower threshold, or throw an exception or return null if it's above the upper threshold.

    As per the article on Wikipedia, multiple factory methods also allow different interpretations of similar argument types. Normally the constructor has the same name as the class, which means that you can only have one constructor with a given signature. Factories are not so constrained, which means you can have two different methods that accept the same argument types:

    Coordinate c = Coordinate.createFromCartesian(double x, double y)
    

    and

    Coordinate c = Coordinate.createFromPolar(double distance, double angle)
    

    This can also be used to improve readability, as Rasmus notes.

    0 讨论(0)
提交回复
热议问题