observable 组合_Java中的通用Observable:在继承上偏爱组合

observable 组合

Android provides Observable class and Observer interface for implementing Observable pattern. However, this isn’t an elegant solution because what if we want to make a custom View class observable? Custom view class will extend View, so it cannot extend Observable class.

Android提供了Observable类和Observer接口,用于实现Observable模式。 但是,这不是一个很好的解决方案,因为如果我们想使自定义View类成为可观察的怎么办? 自定义视图类将扩展View,因此它不能扩展Observable类。

Furthermore, as Joshua Bloch says in his book Effective Java: we should favour Composition over Inheritance, and as such, it is against good software design to extend a class just for a single behaviour.

而且,正如约书亚·布洛赫(Joshua Bloch)在他的《有效的Java》一书中所说:我们应该更偏重于组合而不是继承,因此,仅针对单个行为扩展类是不利于良好的软件设计的。

Possible solution would be to use an Observable interface and implement it, instead of extending the Observable class.

可能的解决方案是使用Observable接口并实现它,而不是扩展Observable类。

This is how we can use a simple Observable interface:

这是我们如何使用简单的Observable接口的方法:

public interface Observable {

interface Listener{
void callback();
}

void registerListener(Listener listener);
void unregisterListener(Listener listener);
}

(This works but still the callback methods need to be predefined in the Observable.Listener interface. We will return to this point in a minute.)

(这是可行的,但仍然需要在Observable.Listener接口中预定义回调方法。我们将在一分钟内返回至此。)

Here, the callback would be implemented in two steps:

在这里,回调将分两步实现:

1. Observable: Observable object, say customView class, would need to implement Observable interface.

1. Observable:Observable对象(例如customView类)将需要实现Observable接口。

2. Observer: either creating an anonymous Listener object inline or implement Observable.Listener interface:

2.观察者:内联创建匿名Listener对象或实现Observable.Listener接口:

class CustomView implements Observable.Listener{
@Override
callback(){
// do something }
}

Problem here is that we need to define the callback methods in the interface itself (in above case, the method is “void callback() ”. So we cannot reuse this Interface across the codebase since not every Observable will want to call the Observer on this method.

这里的问题是我们需要在接口本身中定义回调方法(在上述情况下,该方法是“ void callback()”。因此,由于并非每个Observable都希望在其上调用Observer,因此我们无法在代码库中重用此接口。这种方法。

So the question is: is there a way we can create an Observable interface whereby the Listener interface will be defined later by the class implementing the Observable interface?

所以问题是:有没有一种方法可以创建一个Observable接口, 以便稍后由实现Observable接口的类定义Listener接口

Answer: Yes! It is possible via Generics!

答:可以! 可以通过泛型!

Consider the below code:

考虑下面的代码:

public interface Observable<ListenerType> {
void registerListener(ListenerType listener);
void unregisterListener(ListenerType listener);
}

Now, we have a generic ListenerType (which we aren’t aware of at the time of writing the interface).

现在,我们有了一个通用的ListenerType(在编写接口时我们还不知道)。

It is left to the Observable to implement this interface and thereby define the callback methods!

留给Observable来实现此接口,从而定义回调方法

Here’s how the Observable class will look like now:

这是Observable类现在的样子:

public class CustomView implements Observable<CustomView.Listener> {
private Listener mListener;
// Listener interface and callbacks are now defined inside the Observable object class
public interface Listener {
void notifyDrawComplete();
void notifyCircleShiftedByX(int x);
}
@Override
public void registerListener(Listener listener) {
mListener = listener;
}
@Override
public void unregisterListener(Listener listener) {
mListener = null;
}
}

Here’s how the Observer class will look like:

这是Observer类的样子:

public class MainActivity extends AppCompatActivity implements CustomView.Listener {
private CustomView mCustomView = new CustomView();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
// register in onStart
mCustomView.registerListener(this);
}
@Override
protected void onStop() {
super.onStop();
// very important to unregister in onStop to avoid memory leak
mCustomView.unregisterListener(this);
}
@Override
public void notifyDrawComplete() {
// do something..
}
@Override
public void notifyCircleShiftedByX(int x) {
// do something..
}
}

We are able to implement Observable pattern by just writing one generic interface! Instead of one class and one interface which Android provides, and which hinders composition.

我们只需编写一个通用接口就能实现Observable模式! 而不是Android提供的一个类和一个接口,它阻碍了合成。

This way, the Observable interface doesn’t have to know anything about either the Observer or the Observable and can therefore be written in a very generic way and used across the complete code base.

这样,Observable接口不必了解Observer或Observable的任何知识,因此可以以非常通用的方式编写并在整个代码库中使用。

I must give credit to Vasiliy’s course on Udemy from where I learnt this. https://www.udemy.com/course/android-architecture/ Highly recommend this course.

我必须从我学到的知识归功于Vasiliy关于Udemy的课程。 https://www.udemy.com/course/android-architecture/强烈推荐这门课程。

翻译自: https://medium.com/swlh/generic-observable-in-java-favour-composition-over-inheritance-3bdc3981d779

observable 组合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值