当前位置:网站首页>Vous ne connaissez pas encore les scénarios d'utilisation du modèle de chaîne de responsabilité?

Vous ne connaissez pas encore les scénarios d'utilisation du modèle de chaîne de responsabilité?

2022-04-23 14:39:00 Châtaignier frit avec sucre

Généralités

Dans le Code, nous avons souventif…else…Jugement,Si une condition n'est pas remplie, faites le jugement suivant,Cela ressemble à un modèle de chaîne de responsabilité,Mais le modèle de chaîne de responsabilité est filtré par des objets.

Scénario

Dans l'industrie de l'Internet des objets,Un appareil pousse les données vers le serveur à une certaine fréquence,Faciliter l'acquisition de données et la surveillance de la machine par le serveur,Les types de données sont variés.Par exemple, une machine à poupée:Il y aura des données sur l'état de l'appareil、Données de positionnement de l'équipement、Les données de l'alarme de l'appareil et toutes sortes de données.Chaque type de données se compose de plusieurs champs,Par exemple, les données d'état de l'appareil contiennent:Heure actuelle、Numéro de la machine、État de la machine(En ligne.、Hors ligne、Hors ligne),Il est généralement transmis sous forme binaire,Pour plus de commodité, supposons que l'équipement soitJSONLe format du rapport,J'ai reçu les données et je les ai traitées en conséquence.

image-20220421214953234

Mise en œuvre normale du Code

La première chose à penser est d'utiliserif…else…,S'il s'agit de données d'alarme de l'appareil, j'utilise le processeur d'alarme de l'appareil pour traiter,C'est très simple.,Commencez le codage~

1、Classe d'entité

DeviceAlarmCatégorie

package com.ylc.model;

import lombok.Data;

/**
 *  Classe d'entité d'état de l'appareil 
 * @author yanglingcong
 * @date 2022/4/20 21:08
 */
@Data
public class DeviceStatus {


    /**
     * Mise à jour
     */
    private  long updateTime;

    /**
     * Statut
     * 0 Non préparé
     * 1 Préparez - vous.
     * 2 Fonctionnement normal
     * 3 Anomalie
     */
    private Integer state;

    /**
     * Type de données
     */
    private String type;

}

DeviceGpsCatégorie

/**
 * MatérielGPSClasse d'entité
 *
 * @author yanglingcong
 * @date 2022/4/20 21:08
 */
@Data
public class DeviceGps {

    /**
     * Longitude
     */
    private Float longitude;

    /**
     * Latitude
     */
    private Float latitude;


    /**
     *  Facteur de précision de la composante horizontale :
     */
    private Float hdop;

}

DeviceAlarmCatégorie

package com.ylc.model;

import lombok.Data;

/**
 *  Classe d'entité d'alarme de l'équipement 
 *
 * @author yanglingcong
 * @date 2022/4/20 21:08
 */
@Data
public class DeviceAlarm {

    /**
     * Message d'alarme
     */
    private String alarmMsg;

    /**
     * État de l'alarme
     */
    private Integer alarmStatus;
}

2、 Type d'énumération du message

package com.ylc.model;

import lombok.Getter;

/**
 *  Type d'énumération des messages du périphérique 
 * @author yanglingcong
 * @date 2022/4/20 21:08
 */
@Getter
public enum eventEnum {

    STATUS("10001"),

    ALARM("10002"),

    GPS("10003");

    private String code;

    eventEnum(String code){
        this.code=code;
    }
}

3、Interfaces d'événements

/**
 * Interface processeur
 * @author yanglingcong
 * @date 2022/4/19 22:59
 */
public interface AbstractHandler {

    String getEventType();

    void handle(JSONObject jsonObject);

}

3、Gestion des événements

DeviceAlarmEvent

/**
 *  Événement d'alarme de l'appareil 
 * @author yanglingcong
 * @date 2022/4/19 22:59
 */
@Slf4j
@Component
public class DeviceAlarmEvent   implements  AbstractHandler{

    @Override
    public String getEventType() {
        return eventEnum.ALARM.getCode();
    }

    @Override
    public void handle(JSONObject jsonObject) {
        DeviceAlarm deviceAlarm = jsonObject.toJavaObject(DeviceAlarm.class);
        log.info(" Les événements d'alarme de l'équipement sont traités ");
        //Traitement des affaires.....
    }
}

DeviceGpsEvent

/**
 *  Événement de localisation de l'appareil 
 * @author yanglingcong
 * @date 2022/4/19 22:59
 */
@Component
@Slf4j
public class DeviceGpsEvent implements AbstractHandler{

    @Override
    public String getEventType() {
        return eventEnum.GPS.getCode();
    }

    @Override
    public void handle(JSONObject jsonObject) {
        DeviceGps deviceGps = jsonObject.toJavaObject(DeviceGps.class);
        //Traitement des affaires.....
        log.info(" L'événement de localisation de l'appareil est traité ");
    }
}

DeviceStatusEvent

/**
 *  Événement d'état de l'appareil 
 * @author yanglingcong
 * @date 2022/4/19 22:59
 */
@Slf4j
@Component
public class DeviceStatusEvent implements  AbstractHandler{

    @Override
    public String getEventType() {
        return eventEnum.STATUS.getCode();
    }

    @Override
    public   void  handle(JSONObject jsonObject){
        DeviceStatus deviceStatus = jsonObject.toJavaObject(DeviceStatus.class);
        //Traitement des affaires.....
        log.info(" L'événement d'état de l'appareil est traité ");
    }
}

4、 Centre de distribution de messages

package com.ylc.handle;

import com.alibaba.fastjson.JSONObject;
import com.ylc.model.eventEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 *  Classe de traitement des événements de données 
 * @author yanglingcong
 */
@Slf4j
@Component
public class PushEvent {

    /**
     *  Les données sont distribuées au traitement d'événements correspondant 
     */
    public void dispatch(JSONObject jsonObject){
        String code = (String) jsonObject.get("type");
        // S'il s'agit de données sur l'état de l'appareil 
        if(code.equals(eventEnum.STATUS.getCode())){
            log.info(" Début du traitement des données d'état de l'appareil ");
            DeviceStatusEvent statusEvent=new DeviceStatusEvent();
            statusEvent.handle(jsonObject);
        }
        // S'il s'agit de données de localisation de l'appareil 
        else if(code.equals(eventEnum.GPS.getCode())){
            log.info(" Début du traitement des données de localisation de l'appareil ");
            DeviceGpsEvent deviceGpsEvent=new DeviceGpsEvent();
            deviceGpsEvent.handle(jsonObject);
        }
        // Dans le cas des données d'alarme de l'équipement 
        else if(code.equals(eventEnum.ALARM.getCode())){
            log.info(" Début du traitement des données de localisation de l'appareil ");
            DeviceStatusEvent statusEvent=new DeviceStatusEvent();
            statusEvent.handle(jsonObject);
        }
    }

}

6、Tests

@Slf4j
public class MessageHandleTest {

    @Test
    public void  testDeviceStatus(){
        DeviceStatus deviceStatus=new DeviceStatus();
        deviceStatus.setType(eventEnum.STATUS.getCode());
        deviceStatus.setUpdateTime(1653532367);
        deviceStatus.setState(1);
        JSONObject jsonObject= JSON.parseObject(JSONObject.toJSONString(deviceStatus));
        PushEvent pushEvent=new PushEvent();
        log.info("Début de la distribution des messages:{}",deviceStatus.toString());
        pushEvent.dispatch(jsonObject);
    }

}

Résultats des opérations

image-20220421221949165

Mais ça va poser beaucoup de problèmes , S'il y a d'autres types de données, ajoutez le jugement , L'ordre dans lequel cette condition est déterminée est également écrit mort ,Très inflexible, Ensuite, optimisé avec le modèle de chaîne de responsabilité

Réalisation de la chaîne de responsabilité

1、Classe d'entité Non.

2、Gestion des événements Non.

3、 Centre de distribution de messages

package com.ylc.handle;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 *  Classe de traitement des événements de données 
 * @author yanglingcong
 */
@Slf4j
@Component
public class PushEvent implements ApplicationContextAware {

     /**
     *  Mise en œuvre de la collection de classes 
     * */
    private Map<String, List<AbstractHandler>> routerMap;

    @Autowired
    ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.routerMap =applicationContext.getBeansOfType(AbstractHandler.class).values()
                .stream().collect(Collectors.groupingBy(AbstractHandler::getEventType));
    }

    /**
     *  Les données sont distribuées au traitement d'événements correspondant 
     */
    public void dispatch(JSONObject jsonObject){
        String code = (String) jsonObject.get("type");
        List<AbstractHandler> pushEventHandlers= this.routerMap.get(code);
        for (AbstractHandler pushEventHandler : pushEventHandlers) {
            log.info("Début du traitement{}Événements",pushEventHandler.getEventType());
            pushEventHandler.handle(jsonObject);
        }
    }
}

4、Tests

package com.ylc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ylc.handle.AbstractHandler;
import com.ylc.handle.PushEvent;
import com.ylc.model.DeviceStatus;
import com.ylc.model.eventEnum;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class MessageHandleTest {

    @Autowired
    PushEvent pushEvent;

    @Test
    public void  testDeviceStatus(){
        DeviceStatus deviceStatus=new DeviceStatus();
        deviceStatus.setType(eventEnum.STATUS.getCode());
        deviceStatus.setUpdateTime(1653532367);
        deviceStatus.setState(1);
        JSONObject jsonObject= JSON.parseObject(JSONObject.toJSONString(deviceStatus));
        log.info("Début de la distribution des messages:{}",deviceStatus.toString());
        pushEvent.dispatch(jsonObject);
    }

}

image-20220423140135494

  • S'il y a un nouveau type de message de périphérique , Il suffit d'ajouter une nouvelle classe de gestion d'événements , Les autres codes ne changent pas , Cela est conforme au principe de l'ouverture et de la fermeture et au principe unique , La flexibilité des procédures a également été accrue .
  • Nous n'avons pas besoin de nous - mêmes pour utiliser exactement quel type , Pour le traitement de l'exécution du programme
  • UtiliserMapLa façon de se réunir, Trouver le processeur correspondant directement à partir de la collection en fonction des caractéristiques , Comme pour d'autres paramètres de blog, utilisez le prochain processeur pour juger , Si la chaîne est plus longue, il n'est pas approprié d'utiliser la prochaine méthode de traitement , Il faut traverser de la tête à la queue .
  • Vous pouvez également contrôler l'ordre des demandes , Les mots de collection sont ajoutés en ajoutant un champ de tri

Résumé

Le modèle de chaîne de responsabilité est en fait flexible if..else..Déclarations, Relier plusieurs processeurs en une seule chaîne . Après réception de la demande, Il le fera. “Demandes de renseignements” Est - ce que chaque transformateur est capable de le traiter . De cette façon, tous les processeurs ont la possibilité de traiter la demande

Utiliser le scénario

  • Lorsque plusieurs processeurs doivent être exécutés séquentiellement ,Ce mode peut être utilisé
  • Si le processeur requis et son ordre doivent être modifiés au moment de l'exécution , Le mode chaîne de responsabilité peut être utilisé
  • Lorsque le programme doit traiter différents types de demandes de différentes façons,Et lorsque le type et l'ordre de la demande sont inconnus à l'avance,Le mode chaîne de responsabilité peut être utilisé

版权声明
本文为[Châtaignier frit avec sucre]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231439160668.html