2012-01-06 16 views
7

Vengo a Java desde C# donde los eventos son ciudadanos de primera clase y los controladores de eventos pueden ser métodos privados. Ahora estoy trabajando en un proyecto Java donde, por supuesto, necesito usar un patrón Observer para implementar eventos.¿Evita exponer detalles de implementación al implementar un patrón de observador en Java?

Dado que el Observer necesita exponer sus métodos de devolución de llamada oyente/manejador a la clase Observable, parece que esto está exponiendo la implementación de los detalles del Observer a otras clases no preocupadas. Puedo establecer el acceso a estos métodos al nivel de paquete que mantendría estos detalles de implementación ocultos para los consumidores de mi paquete, pero todavía tiene un mal "olor" para mí.

¿Esto es solo algo que necesito para apretar los dientes y pelar o hay una forma mejor?

Respuesta

9

Con el patrón Observer, sus clases que están observando no necesitan exponer sus implementaciones. A menudo, su clase que notifica a otras clases tendrá su propia interfaz asociada para implementar esas otras clases.

public interface Observer 
{ 
    public void handleSomeEvent(Object someObjectOfImportance); 
} 

public class Observable 
{ 
    public void register(Observer observer); 
} 

Cualquier clase puede implementar la interfaz Observer y registrarse a sí mismo sin necesidad de exponer los detalles de implementación. Expone que implementa una interfaz, pero eso no especifica cómo lo implementa. Alternativamente, podría proporcionar una implementación anónima.

public class SomeObserverImplementation implements Observer 
{ 
    public void handleSomeEvent(Object someObjectOfImportance) 
    { 
     // I can do whatever I want here 
    } 
} 

actualización Si está preocupado de que su clase es ahora exponer una nueva interfaz hay algunas maneras de trabajar alrededor de ella. Una es crear una implementación anónima. Otra es que puede tener una clase interna privada que implemente la interfaz Observable.

public class IDontWantOthersToKnowIObserve 
{ 
    private class HiddenObserver implements Observer 
    { 
     public void handleSomeEvent(Object someObjectOfImportance) 
     { 
      ... 
     } 
    } 

    ... in some method ... 
    theObservable.register(myHiddenObserver); 
} 

Para utilizar una aplicación en el anonimato:

theObservable.register(new Observer() 
      { 
       public void handleSomeEvent(Object someObjectOfImportance) 
       { 
           // ... 
       } 
      }); 
+0

Gracias! ¡Gran respuesta! – HolySamosa

1

En Java esto normalmente no se considera como muy exponen los detalles de implementación, sin embargo, si realmente desea ocultar la funcionalidad de su clase a partir de otras clases entonces necesita que su clase implemente diferentes interfaces, cada una de las cuales solo expone un subconjunto de la funcionalidad general de la clase. Si luego se asegura de que otras clases solo accedan a su clase a través de una interfaz particular (posiblemente a través de una fábrica), entonces efectivamente ocultará su implementación.

por ejemplo:

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