在Java中实现观察者模式时,避免暴露实现细节?

时间:2012-01-06 21:00:36

标签: java design-patterns observer-pattern

我是从C#来到Java,其中事件是一等公民,事件处理程序可以是私有方法。我现在正在开发一个Java项目,我当然需要使用Observer模式来实现事件。

由于Observer需要将其侦听器/处理程序回调方法暴露给Observable类,因此似乎将Observer的详细信息的实现暴露给其他不关心的类。我可以将这些方法的访问权限设置为包级别,这样可以将这些实现细节隐藏到我的包的消费者身上,但它对我来说仍然有一种“嗅觉”。

这只是我需要咬牙和裸露的东西还是有更好的方法?

2 个答案:

答案 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();
  }
}