11設計パターン_責任の連鎖パターン_ C言語の実装

責任の連鎖モデル

1シミュレーションシーン

簡単なファイアウォールソフトウェアを開発したいとします。ファイアウォールソフトウェアを使用すると、ユーザーはセキュリティルールをカスタマイズし、ユーザー定義のセキュリティルールに従ってネットワークパケットをブロックできます。

可能な実装スキームについて考えてみましょう:

オプション1

ここに画像の説明を挿入

要求者は、各セキュリティルールへの処理要求を個別に開始します。

セキュリティルールの詳細(メッセージを破棄したルール、メッセージを破棄しなかったルールの数)は、要求者に公開されます。

オプションII

ここに画像の説明を挿入

すべてのセキュリティルールを処理するための統合ハンドラーインターフェースをカプセル化します。リクエスターはインターフェースへの処理リクエストを開始するだけでよく、セキュリティルールの数や、パケットを破棄する特定のセキュリティルールは関係ありません。

明らかに、2番目のオプションはリクエスターとプロセッサーを分離し、2番目のオプションは最初のオプションよりも優れています。

ここでの2番目のオプションは、責任の連鎖モデルのアイデアです。

2責任連鎖モデルの概要

責任連鎖パターンは、リクエスターとプロセッサーの間の結合問題を解決するために使用されます。プロセッサが複数のオブジェクトの1つである場合、責任パターンのチェーンは、要求者とプロセッサを切り離すことができます。

リクエスタは、どのオブジェクトがリクエストを処理しているかを気にする必要はありません。対応する「チェーン」にリクエストを送信するだけです。複数のプロセッサが特定の順序(たとえば、優先度、優先度)に従って「チェーン」に配置され、要求を順番に処理できるかどうかを判断し、処理できる場合は、「チェーン」上の次のリクエストに渡します。プロセッサー。

3責任の連鎖モデルを使用してファイアウォールソフトウェアを実装する

参加者

  1. ハンドル:RuleHandle

セキュリティルール処理インターフェイスを定義し、セキュリティルールのチェーン構造を実装する

  1. ConcreteHandle:Rule1Handle、Rule2Handle

特定の処理ルールを実装する

  1. クライアント

セキュリティルールで処理するメッセージを準備し、処理リクエストをセキュリティルールチェーンに送信する

UML

ここに画像の説明を挿入

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;
}

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);
}

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);
}

クライアントコードの例

#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");
        }
    }
}

クライアントの表示例

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

おすすめ

転載: blog.csdn.net/weixin_46826913/article/details/107443335
おすすめ