Brinque com padrões de design (observador padrão)

Índice

Brinque com padrões de design (observador padrão)

Aplicação do Modo Observador em Cenários de Previsão do Tempo

Aplicação do Modo Observador em Cenários de Pagamento

Aplicação do padrão Observer no cenário de assinatura de dados

Resumir       


Brinque com padrões de design (observador padrão)

Para escrever um bom código, o padrão de design (Design Pattern) é uma habilidade básica essencial. O padrão de design é uma solução eficaz para os problemas recorrentes no design orientado a objetos (Design Orientado a Objetos). Início do modo (Padrão Observer). No modo observador, existem vários objetos observadores (observador) que dependem do mesmo objeto alvo (sujeito). Quando o objeto alvo dependente muda, todos os objetos observadores que dependem dele serão notificados e, em seguida, cada observador O objeto respondente responde de acordo com as suas próprias necessidades.

Suas principais vantagens são as seguintes:

  • Acoplamento reduzido entre o alvo e o observador

  • Um mecanismo de gatilho de mudança entre o alvo e o observador é estabelecido

Suas principais desvantagens são as seguintes:

  • A dependência entre o alvo e o observador não é completamente resolvida e pode haver referências circulares

  • Quando há muitos objetos observadores, a liberação da notificação demora muito, o que afeta a eficiência do programa

Mais abstrato e difícil de entender? Vamos nos referir a vários cenários comuns no design funcional diário.

Aplicação do Modo Observador em Cenários de Previsão do Tempo

Prestar atenção à previsão do tempo é um hábito importante em nosso dia a dia. Personagens diferentes têm reações diferentes às mudanças no clima. Por exemplo, vai chover forte amanhã. O departamento de meteorologia avaliará e emitirá orientações políticas razoáveis. O departamento de educação precisará avaliar se as aulas precisam ser suspensas. O departamento de emergência considerará como se preparar para o resgate de emergência com antecedência. Não é uma necessidade de pensar em como ir e voltar do trabalho, e também há algumas pessoas em áreas não afetadas por essa chuva forte que não precisam pensar em nada. Combinado com a introdução do modo observador acima, neste cenário, o clima pertence ao objeto alvo (Assunto) que é utilizado por cada função, os departamentos de meteorologia/educação/emergência/saneamento, trabalhadores e pessoas em outras áreas pertencem ao objeto observador (Observer ). Depois que o objeto alvo muda, cada objeto observador tomará medidas de resposta correspondentes após receber a mensagem. O diagrama simplificado de classe do modo observador com base nos cenários acima é o seguinte:

  • Objeto de destino (WeatherSubject): O objeto de destino a ser observado, ou seja, o clima neste exemplo, contém um atributo de estado do clima state e o método attach() do observador vinculado e o método notifyAllObservers() do observador. Quando o estado mudar, chame o método notifyAllObservers() para notificar todos os observadores.

  • Objeto observador abstrato (Observer): utilizado para definir as especificações de comportamento de cada observador, podendo também ser implementado na forma de uma interface

  • Objetos observadores reais: MeteorologicalDepartment, RescueDepartment, OfficeWorker, Other, etc., a função que realmente precisa prestar atenção ao objeto de destino e responder. Herdado do objeto observador abstrato e implementado o método de resposta update() com base em suas respectivas preocupações.

Experimente a demonstração do código da versão Java com base no exemplo acima:

package com;import java.util.ArrayList;import java.util.List;// 基于天气预报场景的观察者模式实现Demopublic class ObserverPatternDemo {
   
       // 天气对象    static class WeatherSubject {
   
           private int state;        List<Observer> observers = new ArrayList<>();        void attach(Observer observer) {
   
               observers.add(observer);        }        // 通知观察者        void notifyAllObservers() {
   
               for (Observer o : observers            ) {
   
                   o.update(getState());            }        }        public int getState() {
   
               return state;        }        // 状态变更        public void setState(int state) {
   
               this.state = state;            if (state == 1) {
   
                   System.out.println("=====明天要下大暴雨=====");            } else {
   
                   System.out.println("=====明天天气很好呀=====");            }            // 变更后通知观察者            notifyAllObservers();        }    }    // 抽象观察者对象    static abstract class Observer {
   
           abstract void update(int state);    }    // 政府气象部门    static class MeteorologicalDepartment extends Observer {
   
           @Override        void update(int state) {
   
               if (state == 1) {
   
                   System.out.println("【气象部门】发出预警");            }        }    }    // 政府应急救援部门    static class ResumeDepartment extends Observer {
   
           @Override        void update(int state) {
   
               if (state == 1) {
   
                   System.out.println("【救援部门】准备应急预案");            }        }    }    // 打工人    static class OfficeWorker extends Observer {
   
           @Override        void update(int state) {
   
               if (state == 1) {
   
                   System.out.println("【打工人】思考明天怎么上下班通勤");            } else {
   
                   System.out.println("【打工人】努力搬砖");            }        }    }    // 其他无影响的人    static class Other extends Observer {
   
           @Override        void update(int state) {
   
               if (state == 1) {
   
                   System.out.println("【其他人】下雨啊,对我影响不大");            } else {
   
                   System.out.println("【其他人】明天天气不错,出去玩玩");            }        }    }    public static void main(String[] args) {
   
           // 初始化目标对象        WeatherSubject subject = new WeatherSubject();        // 初始化观察者对象,并关注目标对象        Observer ob1 = new MeteorologicalDepartment();        Observer ob2 = new ResumeDepartment();        Observer ob3 = new OfficeWorker();        Observer ob4 = new Other();        subject.attach(ob1);        subject.attach(ob2);        subject.attach(ob3);        subject.attach(ob4);        // 状态变化: 大暴雨        subject.setState(1);        // 状态变化: 好天气        subject.setState(2);                //执行结果如下        =====明天要下大暴雨=====        【气象部门】发出预警        【救援部门】准备应急预案        【打工人】思考明天怎么上下班通勤        【其他人】下雨啊,对我影响不大        =====明天天气很好呀=====        【打工人】努力搬砖        【其他人】明天天气不错,出去玩玩    }}

Aplicação do Modo Observador em Cenários de Pagamento

No cenário de pagamento de negócios, quando o usuário compra um produto, as três partes ligam de volta depois que o pagamento é bem-sucedido. Nesse momento, o sistema pode ter muita lógica a ser executada (como: atualizar o pedido status, enviar notificações por SMS, avisar o sistema de logística para começar a estocar, dar presentes…).

Normalmente, o método de processamento mais intuitivo é criar as classes das quais o sistema de pagamento correspondente precisa depender (Order, SMS, Express...) e a classe de pagamento Pay, instanciar cada classe dependente na lógica de pagamento principal e chamá-las de uma por um após o pagamento do usuário ser bem-sucedido.Cada classe de dependência manipula a lógica. Mas desta forma, a classe de pagamento precisa saber quais classes precisam ser notificadas, e a lógica principal de pagamento é inchada e acoplada, o que não é fácil de expandir e manter.

O modo observador pode lidar melhor com esse cenário de pagamento. Não há forte acoplamento entre as lógicas de classe das quais esses sistemas de pagamento dependem, portanto, é adequado usar o modo observador para realizar essas funções, e a classe de pagamento não se importa com a necessidade para notificação Quais classes só precisam fornecer uma lista de notificação.Quando houver mais operações, você só precisa adicionar novos observadores à lista de notificação, e o pagamento bem-sucedido do usuário notificará todos os observadores registrados. O princípio de abertura e fechamento, que é fechado para modificação e aberto para extensão, foi realizado.

A implementação específica geralmente inclui as seguintes partes:

  • Abstraia a classe observável Observable e abstraia as propriedades e métodos comuns;

  • Crie uma classe específica de Observer Pay, desde que o usuário pague com sucesso, ela notificará todos os observadores cadastrados;

  • Abstract a interface do observador Observer, que contém um método abstrato update para atualizar a si mesmo, que é chamado ao receber uma notificação de alteração do tema específico Pay;

  • Crie classes específicas de observadores, como pedidos, SMS e logística, eles precisam observar o status do pagamento e atualizar seu próprio status quando são notificados sobre alterações no pagamento;

// 抽象主题(Subject)角色public abstract class Observable {
   
    // 观察者列表 private List<Observer> observers = new ArrayList<>(); // 添加观察者 public void add(Observer observer){
   
     observers.add(observer); } // 移除观察者 public void remove(Observer observer){
   
     observers.remove(observer); } // 通知观察者 protected void notifyObservers(){
   
     for (Observer observer : observers) {
   
      observer.update();  } }}// 具体主题(Concrete Subject)角色public class Pay extends Observable{
   
    public void pay(){
   
     System.out.println("支付完成.");  // 通知观察者  super.notifyObservers(); }}// 抽象观察者(Observer)角色public interface Observer {
   
    // 通知 void update();}// 具体观察者(Concrete Observer)角色// 订单:修改订单状态public class Order implements Observer{
   
    @Override public void update() {
   
     System.out.println("修改订单状态..."); }}// 短信:发送扣款短信到用户public class SMS implements Observer{
   
    @Override public void update() {
   
     System.out.println("账户扣款短信通知..."); }}//物流:通知物流系统开始备货public class Express implements Observer{
   
    @Override public void update() {
   
     System.out.println("物流开始备货..."); }}// 客户端调用public class Client {
   
    public static void main(String[] args) {
   
     Pay pay = new Pay();  pay.add(new Order());  pay.add(new SMS());  pay.add(new Express());  pay.pay(); }}

Aplicação do padrão Observer no cenário de assinatura de dados

Em aplicações práticas, o modo observador é frequentemente usado em cenários de envio de dados. Tomando novos recursos como exemplo, após a conclusão da produção de novos capítulos, muitas empresas precisam desses dados, como pesquisa, disco online, barra de postagem, Xiaodu, etc., e cada parte recebe os dados de maneiras diferentes.

Para cada assinante, será implementado um método de assinatura completamente diferente, que pode ser interface push http, fila kafka, sistema de arquivos afs, etc. Esses métodos de assinatura podem ser implementados separadamente e registrados e, quando uma mensagem é publicada, o método de assinante é acionado por sua vez.

Segue a demonstração de implementação da linguagem PHP:​​​​​​​​

interface Observer {
   
       public function push($data);}class Publish {
   
       private $observers = array();        public function register(Observer $observer) {
   
           $this->observers[] = $observer;    }        public function delete(Observer $observer) {
   
           $index = array_search($observer, $this->observers);        if ($index !== FALSE && array_key_exists($index, $this->observers)) {
   
               unset($this->_observers[$index]);        }    }        public function push($data) {
   
           foreach ($this->observers as $observer) {
   
               $observer->push($data);        }    }}class Search implements Observer {
   
       public function push($data) {
   
           //推送afs    }}class Cloud implements Observer {
   
       public function push($data) {
   
           //推送kafaka    }}$publish = new Publish();$publish->register(new Search());$publish->register(new Cloud());$publish->push($data);

Resumir       

Através da explicação dos três casos reais acima e da leitura da implementação do código específico, você deve ter uma compreensão mais profunda dos cenários de aplicação e dos planos de implementação específicos do modo observador. Combinando a análise dos três casos anteriores, os cenários adequados para o modo observador apresentam as seguintes características típicas:

  • Há uma dependência de muitos para um: ou seja, vários observadores dependem do mesmo objeto de destino

  • Existe um mecanismo de gatilho de mudança de alvo: depois que o alvo é mudado, uma série de outras tarefas precisam ser acionadas

A realização dos cenários acima por meio do mecanismo do observador pode realizar o desacoplamento da classe de destino e da classe do observador, ou seja, o objeto de destino não precisa saber quais observadores precisam ser notificados, o que é conveniente para expansão e manutenção subsequentes.

Foi exclusivamente autorizado, respeite o original!

Leitura recomendada:

Kafka de alto rendimento, tecnologia central de alto desempenho e melhor aplicação...

Controle de fluxo inteligente em serviços de alta simultaneidade...

Fraudes de otimização de banco de dados Mysql...

Extensibilidade do banco de dados sub-banco de dados e sub-tabela e problemas de distorção/correção de dados...

A evolução do Java chegou ao fim...

Acho que você gosta

Origin blog.csdn.net/qq_34417408/article/details/126265673
Recomendado
Clasificación