You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Designing clean interfaces is one of the most important aspect of API design.
8
8
One of the SOLID principle **[Interface segregation](https://en.wikipedia.org/wiki/Interface_segregation_principle)**
9
-
talks about designing smaller client-specific interfaces instead of designing
9
+
talks about designing smaller client-specific interfaces, instead of designing
10
10
one general purpose interface. Interface design is the key to clean and
11
-
effective API's for your libraries and applications.
11
+
effective APIs for your libraries and applications.
12
12
13
13
> Code for this section is inside [ch01 package](https://github.com/shekhargulati/java8-the-missing-tutorial/tree/master/code/src/main/java/com/shekhargulati/java8_tutorial/ch01).
14
14
15
15
If you have designed any API then with time you would have felt the need to add
16
-
new methods to the API. Once API is published it becomes impossible to add
16
+
new methods to the API. Once an API is published, it becomes difficult to add
17
17
methods to an interface without breaking existing implementations. To make this
18
-
point clear, let's suppose you are building a simple `Calculator` API that
19
-
supports `add`,`subtract`, `divide`, and `multiply` operations. We can write
20
-
`Calculator` interface as shown below. ***To keep things simple we will use
21
-
int.***
18
+
point clear, suppose you are building a simple `Calculator` API that supports
19
+
`add`,`subtract`, `divide`, and `multiply` operations. We can write a
20
+
`Calculator` interface, as shown below. ***To keep things simple we will use
21
+
`int`.***
22
22
23
23
```java
24
24
publicinterfaceCalculator {
@@ -33,8 +33,8 @@ public interface Calculator {
33
33
}
34
34
```
35
35
36
-
To back this `Calculator` interface you created a `BasicCalculator`
37
-
implementation as shown below.
36
+
To back this `Calculator` interface, you created a `BasicCalculator`
37
+
implementation, as shown below.
38
38
39
39
```java
40
40
publicclassBasicCalculatorimplementsCalculator {
@@ -66,9 +66,9 @@ public class BasicCalculator implements Calculator {
66
66
67
67
## Static Factory Methods
68
68
69
-
Calculator API turned out to be very useful and easy to use. Users just have to
70
-
create an instance of `BasicCalculator` and then they can use the API. You start
71
-
seeing code like the one shown below.
69
+
Suppose the Calculator API turned out to be very useful and easy to use. Users
70
+
just have to create an instance of `BasicCalculator`, and then they can use the
71
+
API. You start seeing code like that shown below.
72
72
73
73
```java
74
74
Calculator calculator =newBasicCalculator();
@@ -78,10 +78,10 @@ BasicCalculator cal = new BasicCalculator();
78
78
int difference = cal.subtract(3, 2);
79
79
```
80
80
81
-
Oh no!! Users of the API are not coding to `Calculator` interface instead they
82
-
are coding to implementation. Your API didn't enforced users to code to
83
-
interfaces as the `BasicCalculator` class was public. If you make
84
-
`BasicCalculator` package protected then you would have to provide a static
81
+
Oh no! Users of the API are not coding to `Calculator` interface -- instead,
82
+
they are coding to its implementation. Your API didn't enforce users to code to
83
+
interfaces, as the `BasicCalculator` class was public. If you make
84
+
`BasicCalculator` package protected, then you would have to provide a static
85
85
factory class that will take care of providing the `Calculator` implementation.
86
86
Let's improve the code to handle this.
87
87
@@ -94,7 +94,7 @@ class BasicCalculator implements Calculator {
94
94
}
95
95
```
96
96
97
-
Next, we will write a factory class that will give us the `Calculator` instance
97
+
Next, we will write a factory class that will give us the `Calculator` instance,
98
98
as shown below.
99
99
100
100
```java
@@ -106,23 +106,23 @@ public abstract class CalculatorFactory {
106
106
}
107
107
```
108
108
109
-
Now, users will be forced to code to `Calculator` interface and they will not
110
-
have access to implementation details.
109
+
Now, users will be forced to code to the `Calculator` interface, and they will
110
+
not have access to implementation details.
111
111
112
-
Although we have achieved our goal but we have increased the surface area of our
113
-
API by adding a new class `CalculatorFactory`. Now users of the API have to
112
+
Although we have achieved our goal, we have increased the surface area of our
113
+
API by adding the new class `CalculatorFactory`. Now users of the API have to
114
114
learn about one more class before they can use the API effectively. This was the
115
115
only solution available before Java 8.
116
116
117
-
**Java 8 allows you to declare static methods inside an interface**. This will
118
-
allow API designers to define static utility methods like `getInstance` in the
119
-
interface itself. Hence keeping API short and lean. The static methods inside an
120
-
interface could be used to replace static helper classes(`CalculatorFactory`)
121
-
that we normally create to define helper methods associated with a type. For
122
-
example, `Collections` class is a helper class that defines various helper
123
-
methods to work with Collection and associated interfaces. The methods defined
124
-
in `Collections` class could easily be added to `Collection` or any of its child
125
-
interface.
117
+
**Java 8 allows you to declare static methods inside an interface**. This allows
118
+
API designers to define static utility methods like `getInstance` in the
119
+
interface itself, hence keeping the API short and lean. The static methods
120
+
inside an interface could be used to replace static helper classes
121
+
(`CalculatorFactory`) that we normally create to define helper methods
122
+
associated with a type. For example, the `Collections` class is a helper class
123
+
that defines various helper methods to work with Collection and its associated
124
+
interfaces. The methods defined in the `Collections` class could easily be added
125
+
to `Collection` or any of its child interfaces.
126
126
127
127
The above code can be improved in Java 8 by adding a static `getInstance` method
128
128
in the `Calculator` interface itself.
@@ -148,10 +148,10 @@ public interface Calculator {
148
148
## Evolving API with time
149
149
150
150
Some of the consumers decided to either extend the `Calculator` API by adding
151
-
methods like `remainder` or write their own implementation of `Calculator`
151
+
methods like `remainder`, or write their own implementation of the`Calculator`
152
152
interface. After talking to your users you came to know that most of them would
153
-
like to have a `remainder` method added to `Calculator` interface. It looked a
154
-
very simple API change so you added one more method to the API.
153
+
like to have a `remainder` method added to the `Calculator` interface. It looked
154
+
a very simple API change, so you added one more method to the API.
155
155
156
156
```java
157
157
publicinterfaceCalculator {
@@ -174,19 +174,20 @@ public interface Calculator {
174
174
175
175
Adding a method to an interface broke the source compatibility of the API. This
176
176
means users who were implementing `Calculator` interface would have to add
177
-
implementation for `remainder` method otherwise their code will not compile.
178
-
This is a big problem for API designers as it makes API difficult to evolve.
179
-
Prior to Java 8, it was not possible to have method implementations inside
180
-
interfaces. This often becomes a problem when it was required to extend an API
181
-
i.e. adding one or more methods to the interface definition.
177
+
implementation for the `remainder` method, otherwise their code would not
178
+
compile. This is a big problem for API designers, as it makes APIs difficult to
179
+
evolve. Prior to Java 8, it was not possible to have method implementations
180
+
inside interfaces. This often became a problem when it was required to extend an
181
+
API, i.e. adding one or more methods to the interface definition.
182
182
183
183
To allow API's to evolve with time, Java 8 allows users to provide default
184
184
implementations to methods defined in the interface. These are called
185
-
**default** or **defender** methods. The class implementing the interface is not
186
-
required to provide implementation of these methods. If implementing class
187
-
provides the implementation then implementing class method implementation will
188
-
be used else default implementation will be used. `List` interface has few
189
-
default methods defined like `replaceAll`, `sort`, and `splitIterator`.
185
+
**default**, or **defender** methods. The class implementing the interface is not
186
+
required to provide an implementation of these methods. If an implementing class
187
+
provides the implementation, then the implementing class method implementation
188
+
will be used -- otherwise the default implementation will be used. The `List`
189
+
interface has a few default methods defined, like `replaceAll`, `sort`, and
0 commit comments