xref: /aosp_15_r20/external/aws-sdk-java-v2/docs/design/FavorStaticFactoryMethods.md (revision 8a52c7834d808308836a99fc2a6e0ed8db339086)
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