英文:
Observable that stores last value, but cannot push new ones?
问题
让我们假设我有一个 `Person` 接口,其中有一个 `name` 可观察对象:
```java
interface Person {
Observable<String> name;
}
然后是它的实现:
class David implements Person {
Observable<String> name = BehaviorSubject.createDefault("David");
}
现在有一个问题,因为我无法获取 name
可观察对象的当前值:
class Main {
public static void main(String[] args) {
Person person = PersonFactory.create();
System.out.println(??person.name.currentValue??);
}
}
我不想在我的接口中将名称公开为 BehaviorSubject,因为那样每个人都可以更改名称,这不是我想要的。
我在某种程度上理解可观察对象的逻辑,所以我知道它们不被设计用于存储任何值。那么在 RxJava 中,“带有当前值的不可变可观察对象” 是什么?
在 Android 中有 LiveData
和 MutableLiveData
。据我理解,MutableLiveData
相当于 BehaviorSubject
,那么在 RxJava 中相当于 LiveData
的是什么?
<details>
<summary>英文:</summary>
Let's say I have an `Person` interface, that have an `name` observable:
interface Person {
Observable<String> name;
}
And it's implementation:
```java
class David implements Person {
Observable<String> name = BehaviorSubject<>.createDefault("David");
}
And now there is a problem, because I can't get current value of name
observable:
class Main {
public static void main(String[] args) {
Person person = PersonFactory.create();
System.out.println(??person.name.currentValue??);
}
}
I don't want to expose the name as BehaviorSubject in my interface, because then everyone would be able to change the name, which isn't what I want.
I kind of understand a logic of Observables, so I know they aren't designed to store any value. So what is "an immutable observable with current value" in RxJava?
In Android there is a LiveData
and MutableLiveData
. To my understanding MutableLiveData
is the equivalent of BehaviorSubject
, so what is the equivalent of LiveData
in RxJava?
答案1
得分: 1
定义变量name
的类型为内部主题,主题内部为David
,并使用hide()
方法将其公开为可观察对象。使用hide
将确保外部世界无法调用onNext
,即无法改变名称。在这里查看hide()
的文档
class David implements Person {
private PublishSubject<String> nameSubject = BehaviorSubject.createDefault("David");
public Observable<String> observeName() {
return nameSubject.hide();
}
// 如果希望外部世界更新名称
public void setName(String name) {
nameSubject.onNext(name);
}
}
英文:
Define the type of varaible name
as a subject internally to David
and use the hide()
method to expose as an observable. The use of hide will ensure the outside world can't invoke onNext
i.e. mutate the name. See the docs for hide() here
class David implements Person {
private PublishSubject<String> nameSubject = BehaviorSubject<>.createDefault("David");
public Observable<String> observeName() {
return nameSubject.hide();
}
// If you want the outside world to update the name
public void setName(String name) {
nameSubject.onNext(name)
}
}
答案2
得分: 0
我决定创建自己的`LiveData`,使用字段委托
interface LiveData<out T> {
val observable: Observable<out T>
val value: T
fun subscribe(onNext: Consumer<in T>): Disposable = observable.subscribe(onNext)
}
class MutableLiveData<T>(initial: T) : LiveData<T> {
private val subject: BehaviorSubject<T> = BehaviorSubject.createDefault(initial)
override val observable: Observable<out T> = subject
override var value: T
get() = subject.value
set(value) = subject.onNext(value)
fun mutate(mutationFunction: T.() -> Unit) {
value.mutationFunction()
value = value
}
}
英文:
I've decided to create my own LiveData
, using a field delegation
interface LiveData<out T> {
val observable: Observable<out T>
val value: T
fun subscribe(onNext: Consumer<in T>): Disposable = observable.subscribe(onNext)
}
class MutableLiveData<T>(initial: T) : LiveData<T> {
private val subject: BehaviorSubject<T> = BehaviorSubject.createDefault(initial)
override val observable: Observable<out T> = subject
override var value: T
get() = subject.value
set(value) = subject.onNext(value)
fun mutate(mutationFunction: T.() -> Unit) {
value.mutationFunction()
value = value
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论