Patrones de diseño ocho: el modo observador (observador)

En el mundo real, muchos objetos no son independientes, en el que el comportamiento de un objeto cambia puede resultar en una o más de la conducta de otros objetos también cambió. Por ejemplo, cuando el precio de un precios de los productos dará lugar a algunos negocios feliz, triste y consumidores; también, cuando estábamos conduciendo a la intersección, una luz roja se detendrá, la luz verde se encontrará con la línea. Hay muchos ejemplos de este tipo, tales como precios de las acciones y las previsiones meteorológicas con la audiencia, el ladrón y el policía y otros inversores, el número de micro-canales públicos y los usuarios de micro-canal, Oficina de Meteorología.

En el mundo del software de la misma manera, por ejemplo, la relación entre los datos en gráficos de Excel y de líneas, gráficos circulares, gráficos de barras; la relación entre el modelo y ver el modo MVC; origen del evento modelo de eventos y un controlador de eventos. Todos ellos, si el modo de observador a alcanzar es muy conveniente.

La definición y características del modelo

observadores definido (Observador) modo: se refiere a la presencia de muchas dependencias entre una pluralidad de objetos, cuando un estado de los cambios de objeto, todos los objetos que dependen de ella se han notificado y actualizado automáticamente. Este modo se denomina a veces publicar - suscribirse modelo del modelo, - el modo de vista, son los patrones de comportamiento de objetos.

patrón Observer es un patrón de comportamiento objeto, sus principales ventajas son las siguientes.

  1. Reducir el acoplamiento entre el objeto y el observador, el acoplamiento abstracto entre los dos.
  2. Hemos establecido un mecanismo de activación entre el objetivo y el observador.


Su principal inconveniente de la siguiente manera.

  1. Las dependencias entre la diana y el observador no se elimina por completo, pero puede ser una referencia circular.
  2. Cuando un objeto muchos observadores, la notificación de la conferencia pasan mucho tiempo, que afecta a la eficiencia del programa.

Arquitectura e Implementación Modelo

Debe prestar atención a la hora de implementar el patrón de observador no puede ser llamado directamente entre el público objetivo específico y los objetos específicos de observación se mantendrá el estrecho acoplamiento entre ellos, en violación de los principios de diseño orientado a objetos.

1. Estructura Modelo

El papel principal del modo de observación son los siguientes.

  1. temas abstractos (Asunto) Papel: también conocido como clases de objetos abstractos, que proporciona agregación y aumento de la clase para mantener un objeto visor, métodos de objeto de observación Eliminar, métodos abstractos y notificación de todos los observadores.
  2. Los temas específicos (hormigón Asunto) Papel: también conocidos como clase de objetivo específico que implementa el objetivo abstracto del método de notificación, cuando los cambios específicos temáticos estado interno, notificar a todos los observadores objeto registrado.
  3. Resumen de observador (Observador) papel: es una clase o interfaz abstracta, que incluye una versión actualizada de su método abstracto, al recibir el cambio el tema específico de notificación se llama.
  4. observador específica (observador) Hormigón papeles: los métodos abstractos definidos en el observador abstracto implementado con el fin de actualizar su estado en la obtención de los objetivos de notificación de cambio.


configuración de patrón de observador figura como se muestra en la figura.
 

                            estructura patrón de observador figura
 

2. Modo de realización

códigos de patrones observador son los siguientes:

package observer;
import java.util.*;
public class ObserverPattern
{
    public static void main(String[] args)
    {
        Subject subject=new ConcreteSubject();
        Observer obs1=new ConcreteObserver1();
        Observer obs2=new ConcreteObserver2();
        subject.add(obs1);
        subject.add(obs2);
        subject.notifyObserver();
    }
}
//抽象目标
abstract class Subject
{
    protected List<Observer> observers=new ArrayList<Observer>();   
    //增加观察者方法
    public void add(Observer observer)
    {
        observers.add(observer);
    }    
    //删除观察者方法
    public void remove(Observer observer)
    {
        observers.remove(observer);
    }   
    public abstract void notifyObserver(); //通知观察者方法
}
//具体目标
class ConcreteSubject extends Subject
{
    public void notifyObserver()
    {
        System.out.println("具体目标发生改变...");
        System.out.println("--------------");       
       
        for(Object obs:observers)
        {
            ((Observer)obs).response();
        }
       
    }          
}
//抽象观察者
interface Observer
{
    void response(); //反应
}
//具体观察者1
class ConcreteObserver1 implements Observer
{
    public void response()
    {
        System.out.println("具体观察者1作出反应!");
    }
}
//具体观察者1
class ConcreteObserver2 implements Observer
{
    public void response()
    {
        System.out.println("具体观察者2作出反应!");
    }
}

Los resultados del programa son los siguientes: 

具体目标发生改变...
--------------
具体观察者1作出反应!
具体观察者2作出反应!

Modo de ejemplos de aplicación

[Ejemplo 1] utilizando el patrón de observador diseñar un programa para analizar el efecto "tipo de cambio" margen de apreciación o depreciación de los costos de los productos importados empresa de importación o exportación de la empresa productos de exportación y ganancias de la compañía.

Análisis: Cuando el "tipo de cambio" aprecio, empresas de importación reducir el costo de los productos importados y mejora de los márgenes, productos de exportación de la empresa de exportación de los ingresos y los márgenes de beneficios reducidos; cuando los productos "tipo de cambio" devaluación, empresa de importación importado y el costo de la actualización márgenes de beneficio más bajos, las empresas de exportación exportar productos para mejorar los ingresos y la mejora de los márgenes.

Aquí está el tipo de cambio (Rate) clase de destino es una clase abstracta que contiene el observador salvado (la empresa) la lista y añadir / métodos de observador eliminar, y el cambio método abstracto relacionado con los cambios de tipo de cambio (número int); y la tasa de cambio del RMB (RMBrate ) objetivos específicos de clase, que implementa el cambio de la clase padre (número int) método, es decir, cuando la tasa de cambio se cambia por la compañía pertinente; (compañía) es un observador clase abstracta, que define un extracto reacciones de intercambio relacionadas con el método respuesta (número int); empresa de importación clase (ImportCompany) y un Corporation (ExportCompany) clase espectador de salida es una clase concreta que implementan la respuesta de los padres (número int) método, es decir, cuando reciben una notificación de un cambio en la tasa de cambio en consecuencia. La Figura 2 es una vista estructural.
 

                        AAE aººae ° ± caaecaºcc »aea¾


Código es el siguiente:

package observer;
import java.util.*;
public class RMBrateTest
{
    public static void main(String[] args)
    {
        Rate rate=new RMBrate();         
        Company watcher1=new ImportCompany(); 
        Company watcher2=new ExportCompany();           
        rate.add(watcher1); 
        rate.add(watcher2);           
        rate.change(10);
        rate.change(-9);
    }
}
//抽象目标:汇率
abstract class Rate
{
    protected List<Company> companys=new ArrayList<Company>();   
    //增加观察者方法
    public void add(Company company)
    {
        companys.add(company);
    }    
    //删除观察者方法
    public void remove(Company company)
    {
        companys.remove(company);
    }   
    public abstract void change(int number);
}
//具体目标:人民币汇率
class RMBrate extends Rate 
{
    public void change(int number)
    {       
        for(Company obs:companys)
        {
            ((Company)obs).response(number);
        }       
    }
}
//抽象观察者:公司
interface Company
{
    void response(int number);
}
//具体观察者1:进口公司 
class ImportCompany implements Company 
{
    public void response(int number) 
    {
        if(number>0)
        {
            System.out.println("人民币汇率升值"+number+"个基点,降低了进口产品成本,提升了进口公司利润率。"); 
        }
        else if(number<0)
        {
              System.out.println("人民币汇率贬值"+(-number)+"个基点,提升了进口产品成本,降低了进口公司利润率。"); 
        }
    } 
} 
//具体观察者2:出口公司
class ExportCompany implements Company 
{
    public void response(int number) 
    {
        if(number>0)
        {
            System.out.println("人民币汇率升值"+number+"个基点,降低了出口产品收入,降低了出口公司的销售利润率。"); 
        }
        else if(number<0)
        {
              System.out.println("人民币汇率贬值"+(-number)+"个基点,提升了出口产品收入,提升了出口公司的销售利润率。"); 
        }
    } 
}

Los resultados del programa son los siguientes: 

人民币汇率升值10个基点,降低了进口产品成本,提升了进口公司利润率。
人民币汇率升值10个基点,降低了出口产品收入,降低了出口公司的销售利润率。
人民币汇率贬值9个基点,提升了进口产品成本,降低了进口公司利润率。
人民币汇率贬值9个基点,提升了出口产品收入,提升了出口公司的销售利润率。

 patrón Observer en concurrencia software y la forma de uso más frecuente del diseño del programa de procesamiento de eventos, todos los componentes de la forma son "origen de evento", que es el objeto de destino, y el objeto es una observación específica clase controlador de eventos los que se oponen. Por debajo de un controlador de eventos campana de la escuela como un ejemplo, en las obras de manejo de caso modelo "de Windows.

[Ejemplo 2] controlador de eventos usando el diseño patrón de observador de una campana de la escuela.

Análisis: En este caso, la escuela "campana" es el origen del evento y el objetivo, "maestro" y "estudiante" es un detector de eventos específicos y observador, "campana" es la clase de evento. Los estudiantes y profesores llegaron a la escuela del área de enseñanza, se presta atención a la campana de la escuela, llamado el acontecimiento de unión, cuando las horas de clase o después de las horas de clase que activarán el sonido de la campana, a continuación, genera una serie de eventos "campana", los estudiantes y profesores oyó la campana van a empezar la escuela o clase, llamada manejo de eventos. Ejemplos de esto son muy adecuadas para el patrón de uso observador, la Figura 3 muestra los tonos de la escuela modelo de eventos.
 

                                   campana de la escuela diagrama de modelo de eventos


Ahora, con el "modo de observador" para lograr el modelo de gestión de eventos. En primer lugar, definir un evento de llamada (RingEvent) clase, que registra el tipo (clase de anillo / anillo de la clase) tono; redefinición de una campana de la escuela (BellEventSource) clase, que es el origen del evento, la clase observador objetivo, el cual contiene un oyente escucha contenedor, puede enlazar oyente (estudiante o profesor), y hay maneras de generar eventos tonos e informar a los oyentes de todo; a continuación, definir el detector de eventos de sonido de clase (BellEventListener), que es un observador abstracto, tonos contiene manejador de eventos heardBell (RingEvent e) y, por último, la definición del profesor de la clase (TeachEventListener) y las categorías de los estudiantes (StuEventListener), que es un detector de eventos, es un observador específico, oyó la campana sería ir a clase o después de clase. La Figura 4 muestra la estructura del controlador de eventos campana de la escuela.
 

                      diagrama de bloques Alarma de escuela de un controlador de eventos


Código es el siguiente:

package observer;
import java.util.*;
public class BellEventTest
{
    public static void main(String[] args)
    {
        BellEventSource bell=new BellEventSource();    //铃(事件源)    
        bell.addPersonListener(new TeachEventListener()); //注册监听器(老师)
        bell.addPersonListener(new StuEventListener());    //注册监听器(学生)
        bell.ring(true);   //打上课铃声
        System.out.println("------------");   
        bell.ring(false);  //打下课铃声
    }
}
//铃声事件类:用于封装事件源及一些与事件相关的参数
class RingEvent extends EventObject
{   
    private static final long serialVersionUID=1L;
    private boolean sound;    //true表示上课铃声,false表示下课铃声
    public RingEvent(Object source,boolean sound)
    {
        super(source);
        this.sound=sound;
    }   
    public void setSound(boolean sound)
    {
        this.sound=sound;
    }
    public boolean getSound()
    {
        return this.sound;
    }
}
//目标类:事件源,铃
class BellEventSource
{    
    private List<BellEventListener> listener; //监听器容器
    public BellEventSource()
    { 
        listener=new ArrayList<BellEventListener>();        
    }
    //给事件源绑定监听器 
    public void addPersonListener(BellEventListener ren)
    { 
        listener.add(ren); 
    }
    //事件触发器:敲钟,当铃声sound的值发生变化时,触发事件。
    public void ring(boolean sound)
    {
        String type=sound?"上课铃":"下课铃";
        System.out.println(type+"响!");
        RingEvent event=new RingEvent(this, sound);     
        notifies(event);    //通知注册在该事件源上的所有监听器                
    }   
    //当事件发生时,通知绑定在该事件源上的所有监听器做出反应(调用事件处理方法)
    protected void notifies(RingEvent e)
    { 
        BellEventListener ren=null; 
        Iterator<BellEventListener> iterator=listener.iterator(); 
        while(iterator.hasNext())
        { 
            ren=iterator.next(); 
            ren.heardBell(e); 
        } 
    }
}
//抽象观察者类:铃声事件监听器
interface  BellEventListener extends EventListener
{
    //事件处理方法,听到铃声
    public void heardBell(RingEvent e);
}
//具体观察者类:老师事件监听器
class TeachEventListener implements BellEventListener
{
    public void heardBell(RingEvent e)
    {        
        if(e.getSound())
        {
            System.out.println("老师上课了...");           
        }
        else
        {
            System.out.println("老师下课了...");   
        }          
    }
}
//具体观察者类:学生事件监听器
class StuEventListener implements BellEventListener
{
    public void heardBell(RingEvent e)
    {        
        if(e.getSound())
        {
            System.out.println("同学们,上课了...");           
        }
        else
        {
            System.out.println("同学们,下课了...");   
        }          
    }
}

Los resultados del programa son los siguientes: 

上课铃响!
老师上课了...
同学们,上课了...
------------
下课铃响!
老师下课了...
同学们,下课了...

 

Aplicación de modos de escena

Para las siguientes situaciones vistos por el análisis del patrón de observador y la aplicación de los anteriores.

  1. Muchos relación entre los objetos, los cambios de estado de un objeto afectará a otros objetos.
  2. Cuando un modelo abstracto tiene dos aspectos, un aspecto del cual es dependiente de la otra parte, los dos de éstos pueden encapsularse en un objeto separado de manera que puedan ser variadas y la reutilización de forma independiente.

el modo extendido

En Java, la clase y define la interfaz java.util.Observable java.util.Observer el patrón de observador, siempre y cuando alcanzan las subclases pueden escribir la instancia patrón de observador.

1. clase observable

clase observable es un objetivo abstracto clase, tiene un vector de vectores se utiliza para mantener todos los observadores se oponen a ser notificado, vamos a presentar su mayoría de tres métodos importantes.

  1. addObserver void (Observador o) Métodos: un visor para añadir un nuevo objeto al vector.
  2. notifyObservers void (arg) Objeto método: Actualización de llamadas todos los observadores objeto vectorial. El método de informarles que los cambios en los datos. Por lo general, la adición posterior del primer vector del observador para ser notificado.
  3. void setChange () método: se utiliza para establecer un indicador interno booleano, indicando los cambios objeto de destino. Cuando es verdadera, notifyObservers () se notifiquen al espectador.

2. Interfaz Observador

interfaz de observador es un visor abstracto, que supervisa los cambios en el objeto de destino cuando se cambia el objeto de destino, el espectador se le notifica, y llama a la actualización vacío (observable o, arg Objeto ) método, el trabajo correspondiente.

[Ejemplo 3] El uso de clases de interfaz Observador observable y los futuros del petróleo crudo ejemplo patrón de observador.

Análisis: Cuando los precios del petróleo crudo, el lado corto triste, y más Fangju Xing, cuando los precios del petróleo caen, vacío Fangju Xing, múltiples triste. objetivo abstracto en el presente ejemplo (observable) clase definida en Java, una subclase se puede definir directamente, el método es decir, en bruto (OilFutures) clase, que es una clase de objetivo concreto, una clase se define SetPriCe (precio float), cuando clase padre llamada de datos en bruto cambia notifyObservers (arg Object) para notificar a todos los observadores; en el presente ejemplo la interfaz abstracta para el observador (observador) se han definido en Java, siempre y cuando se define la subclase, es decir, la observación específica por categoría (incluyendo a base multipartidista-Bull y oso basado en el espacio), e implementar la actualización (observable o, objeto arg) método puede ser. Figura 5 muestra la estructura de la Fig.
 

                    observador crudo ejemplo de configuración patrón de la fig.


Código es el siguiente:

 

package observer;
import java.util.Observer;
import java.util.Observable;
public class CrudeOilFutures
{
    public static void main(String[] args)
    {
        OilFutures oil=new OilFutures();
        Observer bull=new Bull(); //多方
        Observer bear=new Bear(); //空方
        oil.addObserver(bull);
        oil.addObserver(bear);
        oil.setPrice(10);
        oil.setPrice(-8);
    }
}
//具体目标类:原油期货
class OilFutures extends Observable
{
    private float price;   
    public float getPrice()
    {
        return this.price; 
    }
    public void setPrice(float price)
    {
        super.setChanged() ;  //设置内部标志位,注明数据发生变化 
        super.notifyObservers(price);    //通知观察者价格改变了 
        this.price=price ; 
    }
}
//具体观察者类:多方
class Bull implements Observer
{   
    public void update(Observable o,Object arg)
    {
        Float price=((Float)arg).floatValue();
        if(price>0)
        {
            System.out.println("油价上涨"+price+"元,多方高兴了!");
        }
        else
        {
            System.out.println("油价下跌"+(-price)+"元,多方伤心了!");
        }
    }
}
//具体观察者类:空方
class Bear implements Observer
{   
    public void update(Observable o,Object arg)
    {
        Float price=((Float)arg).floatValue();
        if(price>0)
        {
            System.out.println("油价上涨"+price+"元,空方伤心了!");
        }
        else
        {
            System.out.println("油价下跌"+(-price)+"元,空方高兴了!");
        }
    }
}

 Los resultados del programa son los siguientes:

油价上涨10.0元,空方伤心了!
油价上涨10.0元,多方高兴了!
油价下跌8.0元,空方高兴了!
油价下跌8.0元,多方伤心了!

 

Publicados 136 artículos originales · ganado elogios 6 · vistas 1542

Supongo que te gusta

Origin blog.csdn.net/weixin_42073629/article/details/104437861
Recomendado
Clasificación