Skip to content

Commit bef4c84

Browse files
committed
1.2 Reworked overall phrasing
1 parent 8687417 commit bef4c84

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

Part 1 - Getting Started/2. Key types.md

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Key types
22

3-
Rx is based around two fundamental types, and several others that expand the functionality around them. Those two types are the `Observable` and the `Observer`. we will introduce those, as well as `Subject`s, which ease the learning curve.
3+
Rx is based around two fundamental types, while several others expand the functionality around the core types. Those two core types are the `Observable` and the `Observer`, which will be introduced in this chapter. We will also introduce `Subject`s, which ease the learning curve.
44

5-
Rx builds upon the [Observer](http://en.wikipedia.org/wiki/Observer_pattern) pattern. It is not unique in doing so. Event handling already exists in Java (e.g. JavaFX's EventHandler). These simpler approaches suffer in comparison to Rx:
5+
Rx builds upon the [Observer](http://en.wikipedia.org/wiki/Observer_pattern) pattern. It is not unique in doing so. Event handling already exists in Java (e.g. JavaFX's EventHandler). Those are simpler approaches, which suffer in comparison to Rx:
66

77
* Events through event handlers are hard to compose.
88
* They cannot be queried over time
@@ -12,13 +12,13 @@ Rx builds upon the [Observer](http://en.wikipedia.org/wiki/Observer_pattern) pat
1212

1313
## Observable
1414

15-
[Observable](http://reactivex.io/RxJava/javadoc/rx/Observable) is the first core element that we will see. Since Java does not support extension methods, this class contains a lot of the implementation in Rx. We will be examining it step by step throughout this book. For now, we must understand the `Subscribe` method. Here is one key overload of the method:
15+
[Observable](http://reactivex.io/RxJava/javadoc/rx/Observable) is the first core element that we will see. This class contains a lot of the implementation of Rx, including all of the core operators. We will be examining it step by step throughout this book. For now, we must understand the `Subscribe` method. Here is one key overload of the method:
1616

1717
```java
1818
public final Subscription subscribe(Subscriber<? super T> subscriber)
1919
```
2020

21-
This is the method that you use to receive the values emitted by the observable. As the values come to be pushed (through policies that we will discuss throughout this book), they are pushed to the subscriber, which is then responsible for the behaviour based on this example. The `Subscriber` here is an implementation of the `Observer`.
21+
This is the method that you use to receive the values emitted by the observable. As the values come to be pushed (through policies that we will discuss throughout this book), they are pushed to the subscriber, which is then responsible for the behaviour intended by the consumer. The `Subscriber` here is an implementation of the `Observer` interface.
2222

2323
An observable pushes 3 kinds of events
2424
* Values
@@ -28,7 +28,7 @@ An observable pushes 3 kinds of events
2828

2929
## Observer
3030

31-
We already saw one abstract implementation of the [Observer](http://reactivex.io/RxJava/javadoc/rx/Observer.html), `Subscriber`. `Subscriber` implements some extra functionality and we will see why it is needer later. For now, we should understand the simpler interface.
31+
We already saw one abstract implementation of the [Observer](http://reactivex.io/RxJava/javadoc/rx/Observer.html), `Subscriber`. `Subscriber` implements some extra functionality and should be used as the basis for our implementations of `Observer`. For now, it is simpler to first understand the interface.
3232

3333
```java
3434
interface Observer<T> {
@@ -38,24 +38,24 @@ interface Observer<T> {
3838
}
3939
```
4040

41-
Those three methods are the behaviour that is executed every time the observable pushes a value. The observer's will have its `onNext` called zero or more times, optionally followed by an `onCompleted` or an `onError`. No calls happen after a call to `onError` or `onCompleted`.
41+
Those three methods are the behaviour that is executed every time the observable pushes a value. The observer will have its `onNext` called zero or more times, optionally followed by an `onCompleted` or an `onError`. No calls happen after a call to `onError` or `onCompleted`.
4242

43-
You'll see a lot of the `Observable`, but not so much of the `Observer`. While it is important to understand the `Observer`, you'll be using a lot of method overloads that hide it.
43+
When developing Rx code, you'll see a lot of `Observable`, but not so much of `Observer`. While it is important to understand the `Observer`, there are shorthands that that remove the need to instantiate it yourself.
4444

4545

4646
## Implementing Observable and Observer
4747

48-
You could manually implement `Observer` or extend `Observable`. In reality that may be unnecessary, since Rx provides all the building blocks you need. It is also dangerous, as interaction between parts of Rx includes conventions and internal plumming that are not obvious. It is both simpler and safer to use the many tools that Rx gives you for generating the functionality that you need.
48+
You could manually implement `Observer` or extend `Observable`. In reality that will usually be unnecessary, since Rx already provides all the building blocks you need. It is also dangerous, as interaction between parts of Rx includes conventions and internal plumming that are not obvious to a beginner. It is both simpler and safer to use the many tools that Rx gives you for generating the functionality that you need.
4949

50-
To subscribe to an observable, it is not necessary to provide instances of Observer at all. There are overloads to `subscribe` that take the functions to be executed for `onNext`, `onError` and `onSubscribe`, hiding the creation of instances. It is not even necessary to provide each of those functions. You can even provide a subset of them, i.e. for `onNext` or for `onNext` and `onError`.
50+
To subscribe to an observable, it is not necessary to provide instances of `Observer` at all. There are overloads to `subscribe` that simply take the functions to be executed for `onNext`, `onError` and `onSubscribe`, hiding away the instantiation of the corresponding `Observer`. It is not even necessary to provide each of those functions. You can provide a subset of them, i.e. just `onNext` or just `onNext` and `onError`.
5151

52-
The introduction of lambda functions in Java 1.8 makes these overload very convenient for our examples.
52+
The introduction of lambda functions in Java 1.8 makes these overloads very convenient for the short examples that exist in this book.
5353

5454
## Subject
5555

56-
Subjects are an extension of the `Observable` that also implements the `Observer` interface. The idea may sound odd at first, but they make things a lot simpler in some cases. They can have events pushed to them, which they then push further to their own subscribers. This makes them ideal entry points into Rx code: when you have values coming in from outside of Rx, you can push them into a `Subject`, turning them into an observable. You can think of them as entry points to an Rx pipeline.
56+
Subjects are an extension of the `Observable` that also implements the `Observer` interface. The idea may sound odd at first, but they make things a lot simpler in some cases. They can have events pushed to them (like observers), which they then push further to their own subscribers (like observables). This makes them ideal entry points into Rx code: when you have values coming in from outside of Rx, you can push them into a `Subject`, turning them into an observable. You can think of them as entry points to an Rx pipeline.
5757

58-
`Subject` has two parameter types: the input type and the output type. This is not because `Subject` is the right place transform your values. There are transformation operators to do that, which we will see later.
58+
`Subject` has two parameter types: the input type and the output type. This was designed so for the sake of abstraction and not because the common uses for subjects involve transforming values. There are transformation operators to do that, which we will see later.
5959

6060
There are a few different implementations of `Subject`. We will now examine the most important ones and their differences.
6161

@@ -82,9 +82,15 @@ Output
8282

8383
As we can see in the example, `1` isn't printed because we weren't subscribed when it was pushed. After we subscribed, we began receiving the values that were pushed to the subject.
8484

85+
This is the first time we see `subscribe` being used, so it is worth paying attention to how it was used. In this case, we used the overload which expects one [Function](http://reactivex.io/RxJava/javadoc/rx/functions/Function.html) for the case of onNext. That function takes an argument of type `Integer` and returns nothing. Functions without a return type are also called actions. We can provide that function in different ways:
86+
* we can supply an instance of `Action1<Integer>`,
87+
* implicitly create one using a [lambda expression](http://en.wikipedia.org/wiki/Anonymous_function#Java) or
88+
* pass a reference to an existing method that fits the signature.
89+
In this case, `System.out::println` has an overload that accepts `Object`, so we passed a reference to it. `subscribe` will call `println` with the arriving values as the argument.
90+
8591
### ReplaySubject
8692

87-
`ReplaySubject` has the special feature of caching all the values pushed to it. When a new subscription is made, the event sequence is replayed from the start for the new subscriber.
93+
`ReplaySubject` has the special feature of caching all the values pushed to it. When a new subscription is made, the event sequence is replayed from the start for the new subscriber. After catching up, every subscriber receives new events as they come.
8894

8995
```java
9096
ReplaySubject<Integer> s = ReplaySubject.create();
@@ -124,7 +130,7 @@ Late: 2
124130
Late: 3
125131
```
126132

127-
Our late subscriber now missed the first value, which fell off our buffer of size 2.
133+
Our late subscriber now missed the first value, which fell off the buffer of size 2. Similarily, old values fall off the buffer as time passes, when the subject is created with `createWithTime`
128134

129135
```java
130136
ReplaySubject<Integer> s = ReplaySubject.createWithTime(150, TimeUnit.MILLISECONDS, Schedulers.immediate());
@@ -148,7 +154,7 @@ Late: 3
148154

149155
### BehaviorSubject
150156

151-
`BehaviorSubject` only remembers the last value. It is similar to a `ReplaySubject` with a buffer of size 1. An initial value can be provided on creation, therefore guaranteeing that a value will be available immediately on subscription.
157+
`BehaviorSubject` only remembers the last value. It is similar to a `ReplaySubject` with a buffer of size 1. An initial value can be provided on creation, therefore guaranteeing that a value always will be available immediately on subscription.
152158

153159
```java
154160
BehaviorSubject<Integer> s = BehaviorSubject.create();
@@ -180,7 +186,7 @@ s.subscribe(
180186
);
181187
```
182188

183-
An initial value is available if anyone subscribes before the first value is pushed
189+
An initial value is provided to be available if anyone subscribes before the first value is pushed.
184190

185191
```java
186192
BehaviorSubject<Integer> s = BehaviorSubject.create(0);
@@ -198,7 +204,7 @@ Since the defining role of a `BehaviorSubject` is to always have a value readily
198204

199205
### AsyncSubject
200206

201-
`AsyncSubject` also caches the single last value. The difference now is that it doesn't emit anything until the sequence completes. Its use is to emit a single value and immediately complete.
207+
`AsyncSubject` also caches the last value. The difference now is that it doesn't emit anything until the sequence completes. Its use is to emit a single value and immediately complete.
202208

203209
```java
204210
AsyncSubject<Integer> s = AsyncSubject.create();
@@ -218,7 +224,7 @@ Note that, if we didn't do `s.onCompleted();`, this example would have printed n
218224

219225
## Implicit contracts
220226

221-
As we already mentioned, there are contracts in Rx that are not obvious in the code. An important one is that no events are emitted after a termination event (`onError` or `onCompleted`). The implemented subjects respect that:
227+
As we already mentioned, there are contracts in Rx that are not obvious in the code. An important one is that no events are emitted after a termination event (`onError` or `onCompleted`). The implemented subjects respect that, and the `subscribe` method also prevents some violations of the contract.
222228

223229
```java
224230
Subject<Integer, Integer> s = ReplaySubject.create();
@@ -233,6 +239,8 @@ Output
233239
0
234240
```
235241

242+
Safety nets like these are not guaranteed in the entirety of the implementation of Rx. It is best that you are mindful not to violate the contract, as this may lead to undefined behaviour.
243+
236244
#### Continue reading
237245

238246
| Previous | Next |

0 commit comments

Comments
 (0)