1*8a52c783SCole Faust**Design:** Convention, **Status:** [Accepted](README.md) 2*8a52c783SCole Faust 3*8a52c783SCole Faust## Favor Static Factory Methods Over Constructors 4*8a52c783SCole Faust 5*8a52c783SCole FaustThis page describes the structures and conventions used to initialize a class. 6*8a52c783SCole Faust 7*8a52c783SCole Faust### Static Factory Methods vs. Constructors 8*8a52c783SCole FaustStatic factory methods are preferable than constructors for the following reasons: 9*8a52c783SCole Faust- Static factory methods provide meaningful names compared with constructors, which improves the readability of the codes by describing the objects being returned. 10*8a52c783SCole Faust```java 11*8a52c783SCole Faust// With static factory method, giving a hint that a foobar provider with default settings is being created. 12*8a52c783SCole FaustFoobarProvider defaultProvider = FoobarProvider.defaultFoobarProvider(); 13*8a52c783SCole Faust 14*8a52c783SCole Faust// With constructor 15*8a52c783SCole FaustFoobarProvider defaultProvider = new FoobarProvider(); 16*8a52c783SCole Faust``` 17*8a52c783SCole Faust- They are useful when work with immutable classes as we can reuse the same object instead of creating new object every time when it is invoked. 18*8a52c783SCole Faust- Static factory methods can return any subtype of that class and this gives us flexibility to write a separate factory class to return different subclasses if needed. 19*8a52c783SCole Faust 20*8a52c783SCole FaustThere are a few disadvantages of static factory methods: 21*8a52c783SCole Faust- It might not be straightforward for the users to use static factory method to create new instances compared with constructors, but this can be improved by providing a set of common method names such as `create()` and smart IDEs such as IntelliJ and Eclipse can also give hints and help auto-completing. 22*8a52c783SCole Faust- Classes without public or protected constructors cannot be subclassed, but this could encourage us to use composition instead of inheritance. 23*8a52c783SCole Faust 24*8a52c783SCole FaustIn general, we should favor static factory methods over constructors. 25*8a52c783SCole Faust 26*8a52c783SCole Faust### Example 27*8a52c783SCole Faust```java 28*8a52c783SCole Faustpublic class DefaultCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable { 29*8a52c783SCole Faust 30*8a52c783SCole Faust private static final DefaultCredentialsProvider DEFAULT_CREDENTIALS_PROVIDER = new DefaultCredentialsProvider(builder()); 31*8a52c783SCole Faust 32*8a52c783SCole Faust private DefaultCredentialsProvider(Builder builder) { 33*8a52c783SCole Faust this.providerChain = createChain(builder); 34*8a52c783SCole Faust } 35*8a52c783SCole Faust 36*8a52c783SCole Faust public static DefaultCredentialsProvider create() { 37*8a52c783SCole Faust return DEFAULT_CREDENTIALS_PROVIDER; 38*8a52c783SCole Faust } 39*8a52c783SCole Faust 40*8a52c783SCole Faust public static Builder builder() { 41*8a52c783SCole Faust return new Builder(); 42*8a52c783SCole Faust } 43*8a52c783SCole Faust 44*8a52c783SCole Faust public static final class Builder { 45*8a52c783SCole Faust // ... 46*8a52c783SCole Faust } 47*8a52c783SCole Faust // ... 48*8a52c783SCole Faust} 49*8a52c783SCole Faust 50*8a52c783SCole Faust 51*8a52c783SCole Faust// There are two ways to create new instance 52*8a52c783SCole FaustDefaultCredentialsProvider defaultCredentialsProvider1 = DefaultCredentialsProvider.create(); 53*8a52c783SCole FaustDefaultCredentialsProvider defaultCredentialsProvider2 = DefaultCredentialsProvider.builder().build; 54*8a52c783SCole Faust``` 55*8a52c783SCole Faust### Naming Conventions 56*8a52c783SCole FaustThe naming conventions for the static factory methods: 57*8a52c783SCole Faust- `create()`, `create(params)` when creating a new instance 58*8a52c783SCole Fausteg: `DynamoDBClient.create()` 59*8a52c783SCole Faust- `defaultXXX()` when returning an instance with default settings. 60*8a52c783SCole Fausteg: `BackoffStrategy.defaultStrategy()` 61