Cinco minutos para aprender el modo de observador

Aquí Insertar imagen Descripción

introducción

patrón de observador: una pluralidad de espectadores monitorear simultáneamente un objeto de tema cuando el sujeto es el objeto cambia, es serán notificados a todos los observadores.

Como el número de micro-canales públicos, cuando el autor publicó un documento, todos los abonados recibirán. Tal modo de observador puede lograr la difusión, mientras que en línea con el principio de apertura y cierre, la adición de nuevos espectadores sin cambiar el código original.

El diagrama UML patrón de observador a continuación
Aquí Insertar imagen Descripción
Asunto (tema): define el conjunto de observadores de registro, borrar, método de notificación observador
ConcreteSubject (tema específico)
observador (observadores): define el tema de los cambios realizados a la recepción de la notificación
ConcreteObserver (particularmente observador)

el modo de escritura a mano observador

Para el número de micro-canales públicos, por ejemplo, para escribir un modo de observador

tema abstracto

public interface MySubject {

    void registerObserver(MyObserver o);

    void removeObserver(MyObserver o);

    void notifyObserver();
}

Resumen de observador

public interface MyObserver {
    void update(String authorName, String articleName);
}

Los temas específicos

public class WeChatServer implements MySubject {

    private List<MyObserver> myObservers;
    private String authorName;
    private String articleName;

    public WeChatServer(String authorName) {
        myObservers = new ArrayList<>();
        this.authorName = authorName;
    }

    public void publishArticle(String articleName) {
        this.articleName = articleName;
        notifyObserver();
    }

    @Override
    public void registerObserver(MyObserver o) {
        myObservers.add(o);
    }

    @Override
    public void removeObserver(MyObserver o) {
        if (myObservers.contains(o)) {
            myObservers.remove(o);
        }
    }

    @Override
    public void notifyObserver() {
        myObservers.forEach(item -> {
            item.update(authorName, articleName);
        });
    }
}

observador específica

public class WeChatClient implements MyObserver {

    private String username;

    public WeChatClient(String username) {
        this.username = username;
    }

    @Override
    public void update(String authorName, String articleName) {
        System.out.println(username + ": " + authorName + " 发了一篇文章 " + articleName);
    }
}

Categoría de prueba

public class Main {

    public static void main(String[] args) {
        WeChatServer weChatServer = new WeChatServer("Java识堂");
        WeChatClient user1 = new WeChatClient("张三");
        WeChatClient user2 = new WeChatClient("李四");
        weChatServer.registerObserver(user1);
        weChatServer.registerObserver(user2);
        weChatServer.publishArticle("《五分钟学会观察者模式》");
    }
}

salida

张三: Java识堂 发了一篇文章 《五分钟学会观察者模式》
李四: Java识堂 发了一篇文章 《五分钟学会观察者模式》

patrón de observador Aplicación

JDK proporciona la interfaz de modo observador

Java tiene compatibilidad con el modo de observador en el paquete java.util, que define dos interfaces

Resumen de observador

public interface Observer {
    void update(Observable o, Object arg);
}

tema abstracto

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
        obs = new Vector<>();
    }

    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    public void notifyObservers() {
        notifyObservers(null);
    }

    public void notifyObservers(Object arg) {
	
        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    protected synchronized void setChanged() {
        changed = true;
    }

    protected synchronized void clearChanged() {
        changed = false;
    }

    public synchronized boolean hasChanged() {
        return changed;
    }

    public synchronized int countObservers() {
        return obs.size();
    }
}

Y estamos muy similar a la Kazajstán previamente definido, sino más bien un cambio del campo de conmutación, y para asegurar el hilo de seguridad

Vamos a reescribir el ejemplo anterior acerca de la definición del objeto de evento

@Data
@AllArgsConstructor
public class NewArticleEvent {

    private String authorName;
    private String articleName;
}
public class WeChatServer extends Observable {

    private String authorName;
    private String articleName;

    public WeChatServer(String authorName) {
        this.authorName = authorName;
    }

    public void publishArticle(String articleName) {
        setChanged();
        this.articleName = articleName;
        notifyObservers(new NewArticleEvent(authorName, articleName));
    }
}
public class WeChatClient implements Observer {

    private String username;

    public WeChatClient(String username) {
        this.username = username;
    }

    @Override
    public void update(Observable o, Object arg) {
        NewArticleEvent event = (NewArticleEvent) arg;
        System.out.println(username + ": " + event.getAuthorName() + " 发了一篇文章 " + event.getAuthorName());
    }
}
public class Main {

    public static void main(String[] args) {
        WeChatServer weChatServer = new WeChatServer("Java识堂");
        WeChatClient user1 = new WeChatClient("张三");
        WeChatClient user2 = new WeChatClient("李四");
        weChatServer.addObserver(user1);
        weChatServer.addObserver(user2);
        weChatServer.publishArticle("《五分钟学会观察者模式》");
    }
}

Salida Igual que el anterior

personalizada de eventos en la primavera

Primavera modo observador de lograr con el detector de eventos, el detector de eventos es relativamente simple de lograr en la primavera, o para transformar lo que el ejemplo anterior

Tipo de evento clases tienen que heredar ApplicationEvent

@Data
public class NewArticleEvent extends ApplicationEvent {

    private String authorName;
    private String articleName;

    public NewArticleEvent(Object source, String authorName, String articleName) {
        super(source);
        this.authorName = authorName;
        this.articleName = articleName;
    }

}

Nos puede realizarse mediante la implementación de detectores de eventos ApplicationListener interfaz o el uso @EventListener comentario

@Component
public class NewArticleEventListener implements ApplicationListener<NewArticleEvent> {

    @Override
    public void onApplicationEvent(NewArticleEvent event) {
        System.out.println(event.getAuthorName() + " 发了一篇文章 " + event.getArticleName());
    }
}
@Component
public class MyEventListener {

    @EventListener
    public void newArticleEventListener(NewArticleEvent event) {
        System.out.println(event.getAuthorName() + " 发了一篇文章 " + event.getArticleName());
    }
}

El ejemplo anterior se hizo a los espectadores de dos maneras, la siguiente redacción inicio de la clase de prueba. Las clases anteriores en el paquete Ha com.javashitang.part6

@Configuration
@ComponentScan("com.javashitang.part6")
public class AppConfig {
}
public class Main {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		context.publishEvent(new NewArticleEvent(context, "Jva识堂", "《五分钟学会观察者模式》"));
		context.close();
	}
}

En este punto se puede ver la salida de la consola

Jva识堂 发了一篇文章 《五分钟学会观察者模式》
Jva识堂 发了一篇文章 《五分钟学会观察者模式》

Pues bien, ahora tendrá un evento personalizado en la primavera. Lograr la primavera en el patrón de observador puede complicado, pero la idea básica se ha mencionado anteriormente.

  • El resorte es interfaz de eventos ApplicationEvent
  • La primavera es ApplicationListener interfaz de detector de eventos, todos los oyentes tienen que implementar la interfaz
  • La primavera es ApplicationEventPublisher evento de interfaz de la publicación, implementa esta interfaz applicationContext

primavera ofrece alguna clase de implementación ApplicationEvent para nosotros

  • ContextStartedEvent: recipiente ApplicationContext emitió durante la inicialización del tipo de evento
  • ContextClosedEvent: contenedor Application Context publicó en ir a apagar el tipo de evento
  • ContextRefreshedEvent: contenedor Application Context publicado en la inicialización o actualizar cuando el tipo de evento

Si quieres conocer una aplicación bien de eventos de primavera en la definición del proyecto. Se puede ver mi artículo anterior, nos fijamos en la forma de utilizar las anotaciones + eventos de primavera para implementar el patrón de estrategia

Proyecto si los demás también, cómo reconstruir?

evento definido en la primavera de nube-eureka en - User

Todos sabemos que Eureka es un registro, excepto el nombre del servicio -> ip relación de dirección específica, es
ConcurrentHashMap para guardar la relación de proyección. Ya que está sin duda relacionado con el centro de registro para registrar y cancelar los servicios, de Eureka en el registro (registro), cancel (cancelar), cuando se renueve (renovación) que pasa, publicará un evento, como se muestra en el siguiente código

InstanceRegistry.java

private void handleRegistration(InstanceInfo info, int leaseDuration,
		boolean isReplication) {
	log("register " + info.getAppName() + ", vip " + info.getVIPAddress()
			+ ", leaseDuration " + leaseDuration + ", isReplication "
			+ isReplication);
	publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration,
			isReplication));
}

Si usted está más interesado en los servicios de información, tales como datos de persistencia de la necesidad, se puede escuchar a estos eventos, la escalabilidad no es particularmente bueno?

el blog de referencia

[1] https://juejin.im/post/5bcf53f351882577e5120b99#heading-8
la primavera el proceso entero de arranque, hay una parte evento
[2] https://www.jianshu.com/p/83693d3d0a65
[3] HTTPS: // Blog .lqdev.cn / 11.06.2018 / springboot / capítulo treinta y dos /

Publicados 385 artículos originales · ganado elogios 1471 · Vistas de 900.000 +

Supongo que te gusta

Origin blog.csdn.net/zzti_erlie/article/details/104736416
Recomendado
Clasificación