我从C#转到Java,发现在C#中事件是一等公民,事件处理程序可以是私有方法。而在Java项目中,我需要使用观察者模式来实现事件通知。
由于观察者需要将其回调方法暴露给被观察对象类(Observable),这似乎暴露了观察者的细节实现给其他无关的类。虽然可以将这些方法的访问级别设置为包级别,使得消费者仅能在同一包内使用,但我仍感觉不太舒服。
这只是我需要咬紧牙关忍受的问题,还是有更好的解决方案?
我从C#转到Java,发现在C#中事件是一等公民,事件处理程序可以是私有方法。而在Java项目中,我需要使用观察者模式来实现事件通知。
由于观察者需要将其回调方法暴露给被观察对象类(Observable),这似乎暴露了观察者的细节实现给其他无关的类。虽然可以将这些方法的访问级别设置为包级别,使得消费者仅能在同一包内使用,但我仍感觉不太舒服。
这只是我需要咬紧牙关忍受的问题,还是有更好的解决方案?
public interface Observer
{
public void handleSomeEvent(Object someObjectOfImportance);
}
public class Observable
{
public void register(Observer observer);
}
Observer
接口并注册自己,而不会暴露任何实现细节。它确实暴露了它实现了一个接口,但这并不指定它是如何实现的。或者,您可以提供匿名实现。public class SomeObserverImplementation implements Observer
{
public void handleSomeEvent(Object someObjectOfImportance)
{
// I can do whatever I want here
}
}
更新 如果你担心你的类现在正在暴露新接口,有一些方法可以解决。其中一种方法是创建一个匿名实现。另一种方法是你可以拥有一个私有内部类来实现Observable接口。
public class IDontWantOthersToKnowIObserve
{
private class HiddenObserver implements Observer
{
public void handleSomeEvent(Object someObjectOfImportance)
{
...
}
}
... in some method ...
theObservable.register(myHiddenObserver);
}
使用匿名实现:
theObservable.register(new Observer()
{
public void handleSomeEvent(Object someObjectOfImportance)
{
// ...
}
});
E.g:
public interface Observer<T>
{
public void notify(T event);
}
public interface PublicFace
{
public void doSomething();
}
public class SomeClass implements Observer<Event>, PublicFace
{
public void notify(Event event)
{
// ...
}
public void doSomething()
{
// ...
}
}
public class FaceFactory
{
public static PublicFace getPublicFaceInstance()
{
return new SomeClass();
}
}