11 padrão de design _ padrão de cadeia de responsabilidade _ implementação da linguagem C

Modelo de Cadeia de Responsabilidade

1 cena de simulação

Suponha que desejamos desenvolver um software de firewall simples. O software de firewall permite aos usuários personalizar regras de segurança e bloquear pacotes de rede de acordo com as regras de segurança definidas pelo usuário.

Vamos pensar sobre possíveis esquemas de implementação:

opção um

Insira a descrição da imagem aqui

O solicitante inicia uma solicitação de processamento para cada regra de segurança separadamente.

Os detalhes das regras de segurança (quantas regras de segurança, qual regra descartou a mensagem, qual regra não descartou a mensagem) são expostos ao solicitante.

Opção II

Insira a descrição da imagem aqui

Encapsule uma interface de manipulador unificada para o processamento de todas as regras de segurança. O solicitante só precisa iniciar uma solicitação de processamento para esta interface. Ele não se importa com quantas regras de segurança existem ou a regra de segurança específica que descarta o pacote.

Obviamente, a segunda opção desacopla o solicitante e o processador, e a segunda opção é melhor do que a primeira opção.

A segunda opção aqui é a ideia do modelo da cadeia de responsabilidade.

2 Introdução ao Modelo de Cadeia de Responsabilidade

O padrão da cadeia de responsabilidade é usado para resolver o problema de acoplamento entre o solicitante e o processador. Quando o processador pode ser um de vários objetos, o padrão da cadeia de responsabilidade pode desacoplar o solicitante e o processador.

O solicitante não precisa se preocupar com qual objeto está processando a solicitação, basta enviar a solicitação para a "cadeia" correspondente. Vários processadores são organizados na "cadeia" de acordo com uma determinada ordem (por exemplo, prioridade, prioridade) e julgam se podem processar a solicitação por sua vez, se podem processá-la, se não, passar a solicitação para o próximo na "cadeia" Processador.

3 Implementar software de firewall usando o modelo de cadeia de responsabilidade

Participante

  1. Handle: RuleHandle

Definir a interface de processamento de regras de segurança e implementar a estrutura da cadeia de regras de segurança

  1. ConcreteHandle: Rule1Handle, Rule2Handle

Implementar uma regra de processamento específica

  1. Cliente

Prepare a mensagem a ser processada pela regra de segurança e envie a solicitação de processamento para a cadeia de regras de segurança

UML

Insira a descrição da imagem aqui

Código de amostra RuleHandle

rule_handle.h

#ifndef RULE_HANDLE_H
#define RULE_HANDLE_H

#define MAX_HANDLE_NUM 10

struct RuleHandle {
    struct RuleHandle *successor;
    void (*SetSuccessor)(struct RuleHandle *this, struct RuleHandle *newHandle);
    // return 0:被本规则拦截,丢弃报文, return 1:未被本规则拦截,继续
    int (*HandleRequest)(struct RuleHandle *this, int pktType); 
};

// 构造函数
void RuleHandle(struct RuleHandle *this);
// 析构函数
void _RuleHandle(struct RuleHandle *this);

#endif

rule_handle.c

#include "rule_handle.h"
#include <stddef.h>

static void SetSuccessor(struct RuleHandle *this, struct RuleHandle *newHandle)
{
    this->successor = newHandle;
}

// 构造函数
void RuleHandle(struct RuleHandle *this)
{    
    this->successor = NULL;
    this->HandleRequest = NULL;
    this->SetSuccessor = SetSuccessor;
}

// 析构函数
void _RuleHandle(struct RuleHandle *this)
{
    this->successor = NULL;
    this->HandleRequest = NULL;
    this->SetSuccessor = NULL;
}

Código de amostra do Rule1Handle

rule1_handle.h

#include "rule_handle.h"

// 构造函数
void Rule1Handle(struct RuleHandle *this);

// 析构函数
void _Rule1Handle(struct RuleHandle *this);

rule1_handle.c

#include "rule1_handle.h"
#include <stddef.h>

static int HandleRequest(struct RuleHandle *this, int pktType)
{
    if (pktType == 3) {
        return 0;
    }
    
    if (this->successor != NULL) {
        return this->successor->HandleRequest(this->successor, pktType);
    }

    return 1;
}

// 构造函数
void Rule1Handle(struct RuleHandle *this)
{    
    RuleHandle(this);
    this->HandleRequest = HandleRequest;
}

// 析构函数
void _Rule1Handle(struct RuleHandle *this)
{
    RuleHandle(this);
}

Código de amostra do Rule2Handle

rule2_handle.h

#include "rule_handle.h"

// 构造函数
void Rule2Handle(struct RuleHandle *this);

// 析构函数
void _Rule2Handle(struct RuleHandle *this);

rule2_handle.c

#include "rule_handle.h"
#include <stddef.h>

static int HandleRequest(struct RuleHandle *this, int pktType)
{
    if (pktType == 5) {
        return 0;
    }
    
    if (this->successor != NULL) {
        return this->successor->HandleRequest(this->successor, pktType);
    }

    return 1;
}

// 构造函数
void Rule2Handle(struct RuleHandle *this)
{    
    RuleHandle(this);
    this->HandleRequest = HandleRequest;
}

// 析构函数
void _Rule2Handle(struct RuleHandle *this)
{
    RuleHandle(this);
}

Exemplo de código de cliente

#include "rule_handle.h"
#include "rule1_handle.h"
#include "rule2_handle.h"
#include <stdio.h> 

void main()
{
    //待防火墙处理的网络报文类型
    int pktStream[] = {1, 2, 3, 4, 5, 5, 1, 2, 3};

    struct RuleHandle rule1; // 丢弃类型为3的网络报文
    Rule1Handle(&rule1);

    struct RuleHandle rule2; // 丢弃类型为5的网络报文
    Rule2Handle(&rule2);
    rule1.SetSuccessor(&rule1, &rule2);

    int i;
    for (i = 0; i < (sizeof(pktStream) / sizeof(int)); i++) {
        printf("网络报文类型 %d : ", pktStream[i]);
        if (rule1.HandleRequest(&rule1, pktStream[i]) == 0) {
            printf("丢弃\n");
        } else {
            printf("不丢弃\n");
        }
    }
}

Exemplo de exibição do cliente

-bash-4.2# ./test
网络报文类型 1 : 不丢弃
网络报文类型 2 : 不丢弃
网络报文类型 3 : 丢弃
网络报文类型 4 : 不丢弃
网络报文类型 5 : 丢弃
网络报文类型 5 : 丢弃
网络报文类型 1 : 不丢弃
网络报文类型 2 : 不丢弃
网络报文类型 3 : 丢弃

Acho que você gosta

Origin blog.csdn.net/weixin_46826913/article/details/107443335
Recomendado
Clasificación