【问题标题】:Avoid exposing implementation details when implementing an observer pattern in Java?在 Java 中实现观察者模式时避免暴露实现细节?
【发布时间】:2023-03-08 23:31:01
【问题描述】:

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

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

这只是我需要咬紧牙关,还是有更好的方法?

【问题讨论】:

    标签: java design-patterns observer-pattern


    【解决方案1】:

    使用观察者模式,您正在观察的类不需要公开它们的实现。通常,通知其他类的类会有自己的关联接口供其他类实现。

    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)
                    {
                                    // ...
                    }
                });
    

    【讨论】:

      【解决方案2】:

      在 Java 中,这通常不被认为是真正暴露实现细节,但是,如果你真的想对其他类隐藏你的类的功能,那么你需要让你的类实现不同的接口,每个接口只暴露一个子集整体类功能。如果您随后确保其他类仅通过特定接口(可能通过工厂)访问您的类,那么您实际上隐藏了您的实现。

      例如:

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

      【讨论】:

        猜你喜欢
        • 2011-12-21
        • 1970-01-01
        • 2013-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-12
        • 2013-10-28
        相关资源
        最近更新 更多