我是从C#来到Java,其中事件是一等公民,事件处理程序可以是私有方法。我现在正在开发一个Java项目,我当然需要使用Observer模式来实现事件。
由于Observer需要将其侦听器/处理程序回调方法暴露给Observable类,因此似乎将Observer的详细信息的实现暴露给其他不关心的类。我可以将这些方法的访问权限设置为包级别,这样可以将这些实现细节隐藏到我的包的消费者身上,但它对我来说仍然有一种“嗅觉”。
这只是我需要咬牙和裸露的东西还是有更好的方法?
答案 0 :(得分:9)
使用Observer模式,您正在观察的类不需要公开它们的实现。通常,通知其他类的类将有其自己的关联接口供其他类实现。
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)
{
// ...
}
});
答案 1 :(得分:1)
在Java中,这通常不被认为是真正暴露实现细节,但是,如果您真的想要从其他类隐藏类的功能,那么您需要让您的类实现不同的接口,每个接口只暴露一个子集整体课程功能。如果您确保其他类只通过特定接口(可能通过工厂)访问您的类,那么您可以有效地隐藏您的实现。
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();
}
}