责任链模式与中间件原理

C++责任链模式实战:从原理到应用,彻底解耦复杂业务逻辑 在软件工程中,设计模式是解决特定问题的经典方案,其核心价值在于提升代码的可维护性、可扩展性和模块化程度。责任链模式作为一种行为型设计模式,其核心原理是将多个处理对象连接成一条链,请求沿着这条链传递,直到被某个对象处理为止,从而实现了发送者与接收者的解耦。这一模式的技术价值在于它完美遵循了开闭原则,新增处理器时无需修改现有代码,极大地增强了系统的灵活性。其典型的应用场景包括多级事件处理、日志过滤系统、中间件管道以及替代复杂的条件分支语句。在C++这类高性能系统开发中,责任链模式常与智能指针、标准库组件结合,用 阅读详情

责任链模式

责任链使用场景

image

责任链代码实现

/// <summary>
/// 请假请求
/// </summary>
class LeaveRequest
{
    /// <summary>
    /// 请假天数
    /// </summary>
    public int LeaveDays { set; get; }

    /// <summary>
    /// 姓名
    /// </summary>
    public string Name { set; get; }
}
/// <summary>
/// 抽象管理类
/// </summary>
abstract class AbstractManagerLeaveHandler
{
    public AbstractManagerLeaveHandler AbstractLeaveHandler { get; set; }
    public abstract void HandlerLeaveRequest(LeaveRequest request);
}
/// <summary>
/// 部门经理
/// </summary>
class BMManagerLeaveHandler : AbstractManagerLeaveHandler
{
    private readonly int allowedDays = 3; // 允许天数
    private string handlerName; // 领导名称
    public BMManagerLeaveHandler(string name)
    {
        this.handlerName = name;
    }
    public override void HandlerLeaveRequest(LeaveRequest request)
    {
        if (request.LeaveDays <= this.allowedDays)
        {
            Console.WriteLine("部门经理:" + this.handlerName + ",已批准请假;流程结束。");
            return;
        }
        AbstractLeaveHandler?.HandlerLeaveRequest(request);
    }
}
/// <summary>
/// 主管
/// </summary>
class ZGManagerLeaveHandler : AbstractManagerLeaveHandler
{
    private readonly int allowedDays = 7; // 允许天数
    private string handlerName; // 领导名称
    public ZGManagerLeaveHandler(string name)
    {
        this.handlerName = name;
    }
    public override void HandlerLeaveRequest(LeaveRequest request)
    {
        if (request.LeaveDays <= this.allowedDays)
        {
            Console.WriteLine("主管:" + this.handlerName + ",已批准请假;流程结束。");
            return;
        }
        AbstractLeaveHandler?.HandlerLeaveRequest(request);
    }
}
/// <summary>
/// 总经理
/// </summary>
class ZManagerLeaveHandler : AbstractManagerLeaveHandler
{
    private readonly int allowedDays = 20; // 允许天数
    private string handlerName; // 领导名称
    public ZManagerLeaveHandler(string name)
    {
        this.handlerName = name;
    }
    public override void HandlerLeaveRequest(LeaveRequest request)
    {

        if (request.LeaveDays <= this.allowedDays)
        {
            Console.WriteLine("总经理:" + this.handlerName + ",已批准请假;流程结束。");
            return;
        }
        AbstractLeaveHandler?.HandlerLeaveRequest(request);
    }
}
LeaveRequest lr = new();
lr.Name = "小明";
lr.LeaveDays = 8;

ZGManagerLeaveHandler zGManagerLeaveHandler = new ("张飞");
BMManagerLeaveHandler bMManagerLeaveHandler = new ("诸葛亮");
ZManagerLeaveHandler zManagerLeaveHandler = new("刘备");

bMManagerLeaveHandler.AbstractLeaveHandler = zManagerLeaveHandler;
zGManagerLeaveHandler.AbstractLeaveHandler = bMManagerLeaveHandler;

zGManagerLeaveHandler.HandlerLeaveRequest(lr);

Middleware实现原理

按责任链模式实现

创建请求类和中间件类。

/// <summary>
    /// http上下文类(用于获取HttpRequest和HttpResponse)
    /// </summary>
    class HttpContext
    {
        public HttpRequest httpRequest { set; get; } // 请求输入类
        public HttpResponse httpResponse { set; get; } // 请求响应输出
    }

    /// <summary>
    /// http请求类
    /// </summary>
    class HttpRequest
    {
        /// <summary>
        /// 请求url
        /// </summary>
        public string requestUrl;
    }
    /// <summary>
    /// http响应类
    /// </summary>
    class HttpResponse
    {
    }
/// <summary>
    /// 中间件抽象类
    /// </summary>
    abstract class Middleware
    {
        // 下一个中间件
        public Middleware nextMiddleware { set; get; }

        /// <summary>
        /// 处理请求
        /// </summary>
        /// <param name="request"></param>
        public abstract void HandlerRequest(HttpContext httpContext);
    }
class Default404Middleware : Middleware
{
    /// <summary>
    /// 中间件是否终止条件
    /// </summary>
    private string token = "404";
    public override void HandlerRequest(HttpContext httpContext)
    {
        Console.WriteLine($"执行默认404中间件");
        // 判断请求url是否包含token,包含则终止
        if (httpContext.httpRequest.requestUrl.Contains(token))
        {
            Console.WriteLine($"默认40中间件终止了");
            return;
        }
        nextMiddleware?.HandlerRequest(httpContext);
    }
}
class Default500Middleware : Middleware
{
    /// <summary>
    /// 中间件是否终止条件
    /// </summary>
    private string token = "500";
    public override void HandlerRequest(HttpContext httpContext)
    {
        Console.WriteLine($"执行默认500中间件");
        // 判断请求url是否包含token,包含则终止
        if (httpContext.httpRequest.requestUrl.Contains(token))
        {
            Console.WriteLine($"默认500中间件终止了");
            return;
        }
        nextMiddleware?.HandlerRequest(httpContext);
    }
}
class HttpsMiddleware : Middleware
{
    /// <summary>
    /// 中间件是否终止条件
    /// </summary>
    private string token = "https";
    public override void HandlerRequest(HttpContext httpContext)
    {
        Console.WriteLine($"执行默认https中间件");
        // 判断请求url是否包含token,包含则终止
        if (httpContext.httpRequest.requestUrl.Contains(token))
        {
            Console.WriteLine($"默认https中间件终止了");
            return;
        }
        nextMiddleware?.HandlerRequest(httpContext);
    }
}

像责任链模式一样调用

HttpContext httpContext = new();
HttpRequest httpRequest = new()
{
    requestUrl = "500"
};
httpContext.httpRequest = httpRequest;

HttpsMiddleware httpsMiddleware = new();
Default404Middleware default404Middleware = new();
Default500Middleware default500Middleware = new();

httpsMiddleware.nextMiddleware = default404Middleware;
default404Middleware.nextMiddleware = default500Middleware;

httpsMiddleware.HandlerRequest(httpContext);

第一次改造

但是如果要想加入中间件,责任链这样的调用就会很麻烦,于是去改造代码,加入建造者模式。

/// <summary>
/// 封装中间件
/// </summary>
class Application
{
    /// <summary>
    /// 中间件链集合(中间件管道)
    /// </summary>
    private List<Middleware> middlewares = new List<Middleware>();

    public Application(){ }

    /// <summary>
    /// 外部添加中间件
    /// </summary>
    /// <param name="middleware"></param>
    public void AddMiddleware(Middleware middleware)
    {
        middlewares.Add(middleware);
    }


    /// <summary>
    /// 创建动态中间链(通用)
    /// 1、头部中间件
    /// 2、中间变量
    /// </summary>
    /// <returns></returns>
    public Middleware GetMiddleware()
    {
        // 1、头部节点
        Middleware headerMiddleware = null;

        // 2、中间变量
        Middleware middlewareMiddle = null;

        // 3、形成中间件链
        foreach (var middleware in middlewares)
        {
            if (headerMiddleware == null)
            {
                middlewareMiddle = middleware;

                headerMiddleware = middlewareMiddle;
            }
            else
            {
                middlewareMiddle.nextMiddleware = middleware;
                middlewareMiddle = middleware;
            }
        }
        return headerMiddleware;
    }
}
/// <summary>
/// 中间件集合建造者
/// </summary>
class ApplicationBuilder
{
    private Application application = new Application();
    public void AddMiddleware(Middleware middleware)
    {
        application.AddMiddleware(middleware);
    }
    public Application Build()
    {
        return application;
    }
}

上面代码中把中间件都添加到集合 middlewares 中,再通过 GetMiddleware 方法动态创建出中间件链。

以下在客户端调用。

HttpContext httpContext = new();
HttpRequest httpRequest = new()
{
    requestUrl = "500"
};
httpContext.httpRequest = httpRequest;

ApplicationBuilder applicationBuilder = new ApplicationBuilder();
applicationBuilder.AddMiddleware(new HttpsMiddleware());
applicationBuilder.AddMiddleware(new Default404Middleware());
applicationBuilder.AddMiddleware(new Default500Middleware());
Application application = applicationBuilder.Build();

var middleware = application.GetMiddleware();

middleware.HandlerRequest(httpContext);

第二次改造

虽然责任链调用已经完成了封装,遵循了开闭原则,但是添加中间件 AddMiddleware 方法依然会随着中间件增加而增多,客户端代码不稳定。

于是我们使用了扩展方法,并引入 Startup 类。

static class HttpsMiddlewareExtension
{
    public static ApplicationBuilder AddHttpsMiddleware(this ApplicationBuilder applicationBuilder)
    {
        applicationBuilder.AddMiddleware(new HttpsMiddleware());
        return applicationBuilder;
    }
}
static class Default404MiddlewareExtension
{
    public static ApplicationBuilder AddDefault404Middleware(this ApplicationBuilder applicationBuilder)
    {
        applicationBuilder.AddMiddleware(new Default404Middleware());
        return applicationBuilder;
    }
}
static class Default500MiddlewareExtension
{
    public static ApplicationBuilder AddDefault500Middleware(this ApplicationBuilder applicationBuilder)
    {
        applicationBuilder.AddMiddleware(new Default500Middleware());
        return applicationBuilder;
    }
}
/// <summary>
/// 启动类
/// </summary>
class Startup
{
    public void Configure(ApplicationBuilder builder)
    {
        builder.AddHttpsMiddleware();
        builder.AddDefault404Middleware();
        builder.AddDefault500Middleware();       
    }
}

这样客户端代码就稳定了。

HttpContext httpContext = new();
HttpRequest httpRequest = new()
{
    requestUrl = "500"
};
httpContext.httpRequest = httpRequest;

ApplicationBuilder applicationBuilder = new ApplicationBuilder();
Startup startup = new();
startup.Configure(applicationBuilder);

Application application = applicationBuilder.Build();

var middleware = application.GetMiddleware();

middleware.HandlerRequest(httpContext);

以后每次想添加中间件,只需要添加中间件类和扩展类,再往 Startup 类中加入就可以了,客户端调用代码完全不用动。

image

瑞萨RZN2L工业以太网开发避坑指南:EtherCAT从入门到通信调试全流程 本文详细解析了瑞萨RZN2L MPU在工业以太网开发中的EtherCAT从站配置与通信优化全流程。通过硬件设计关键点、协议栈选型、PDO映射策略及DC同步精度优化等实战技巧,帮助开发者快速搭建高效通信框架并解决调试中的常见问题,特别适合工业自动化领域的实时通信需求。 阅读详情

相关推荐

华为防火墙USG6600全流量日志配置指南:从流量监控到NAT日志的完整方案

本文详细介绍了华为USG6600防火墙全流量日志配置方案,涵盖流量监控、NAT日志及安全事件溯源等核心功能。通过精细化配置和性能优化技巧,帮助企业构建高效、合规的日志体系,提升网络安全运维效率。文章特别强调了日志采样与字段过滤的实用方法,适用于高流量环境下的资源优化。

gin88的博客 347

责任链模式(Chain of Responsibility):HTTP 中间件管道(Pipeline)如何形成责任链?`$next($request)` 的作用是什么?

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。Handler(处理器):定义处理接口;ConcreteHandler(具体处理器):处理请求或传递给下一个;关键:每个处理器决定是否处理请求,以及是否传递。通常只有一个处理器处理请求(如审批流:经理 → 总监 → CEO);处理即终止,不再传递。Laravel 的中间件管道是责任链模式在 Web 开发中的创造性演进。

长风破浪会有时的博客 1146

Type-C快充移动电源芯片避坑指南:IP5356配置全流程(支持PD3.0)

本文详细解析了英集芯IP5356芯片在Type-C快充移动电源中的应用,提供了从芯片选型、原理图设计、PCB布局到PD协议调试的全流程实战指南。文章重点剖析了如何避免散热、EMI及协议握手等常见设计陷阱,并分享了量产前的关键测试验证方法,旨在帮助硬件开发者高效打造稳定可靠的快充产品。

weixin_29235525的博客 845

中间件实现原理

ThinkPHP5.1x的中间件,其核心还是闭包函数的应用,来实现“责任链”模式: 模拟代码: <?php //模拟的控制器 class Controller { public function index($request) { echo '控制器方法体',$request,'<br>'; } } //...

weixin_34380296的博客 115

别再死记硬背了!用MaxDEA软件实操SBM、DDF、NDDF模型,手把手教你测算绿色全要素生产率

本文深度解析如何使用MaxDEA软件实操SBM、DDF、NDDF模型,手把手教你测算绿色全要素生产率(GTFP)。通过详细的模型选择对比、数据准备策略和MaxDEA操作流程,帮助研究者科学构建指标体系并准确解读结果,提升环境管理研究的实证分析能力。

weixin_28731231的博客 312

brpc组件bvar源码解析(一)简介、使用和类的关系

bvar是brpc中的一个重要组件,brpc内部有很多builtin监控都是bvar实现的。 brpc文档介绍bvar“几乎不会给程序增加性能开销,也快于竞争频繁的原子操作”。它的原理是:多线程累加一个计数器时,每个线程只累加私有的变量而不参与全局竞争,因此写时没有锁的竞争;在读取时累加所有线程的私有变量。虽然读比之前慢多了,但写就快多了,因此它使用写多读少的场景,例如统计、监控场景。 1.使用 // bvar::Adder<T>用于累加,下面定义了一个统计read error总数的Adder。

华秋实的专栏 1851

揭秘PHP中间件设计原理:如何构建可复用的请求处理管道

掌握PHP中间件开发技巧,构建高效可复用的请求处理管道。详解中间件设计原理与实现方法,适用于Web应用、API服务等场景,提升代码解耦与维护性。揭秘核心机制,值得收藏。

PixelGlow的博客 981

从圆形到椭圆:CenterNet中高斯热图半径的自适应优化策略

本文深入探讨了CenterNet目标检测模型中高斯热图生成策略的优化,针对传统圆形高斯核在处理长宽比差异大目标时的局限性,提出了自适应椭圆高斯核的解决方案。通过数学推导和代码实战,详细阐述了如何根据目标边界框尺寸动态计算椭圆长短轴半径,生成更贴合目标几何形状的热图监督信号,从而有效提升模型,尤其是对无人机、车辆等不规则目标的定位精度。

alice7model的博客 985

ThinkPHP5.1x 中间件实现原理

ThinkPHP5.1x的中间件,其核心还是闭包函数的应用,来实现“责任链”模式: 模拟代码: <?php //模拟的控制器 class Controller { public function index($request) { echo '控制器方法体',$request,'<br>'; } } ...

dizhuanqi5927的博客 292

AI上推荐 之 AutoInt模型(Transformer开始玩特征交互)

1. 写在前面 这段时间做优化模型的事情,正好和特征交互有关系,这个也是推荐系统里面一直探索的一个方向,从浅层模型的FM, FFM, HOFM, FwFM到深层模型的DNN, PNN, NFM, AFM, DeepFM, DCN, xDeepFM, FiBiNet等,而这次正好借着这次机会, 多看一些有关于特征交叉方向的模型paper, 把一些新的模型或者较为前沿的思想融入进来。 上一篇的FiBinet模型就是在特征交互上一个非常有意思的探索, 通过SENET动态选择有用的交互特征, 然后再用一个双线性交互

Miracle8070 5724

环保 HJ212协议解析

由于是做环保相关的,有时需要对212协议进行拆包和解包。HJ212协议是一种字符串协议,数据传输通讯包主要由包头、数据段长度、数据段、CRC校验、包尾组成,其中“数据段”内容包括请求编码、系统编码、命令编码、密码、设备唯一标识、总包数、包号、指令参数。请求编码为请求的时间戳,系统编码ST统一规定为22,命令编码CN为该数据包的时间类型,访问密码、设备唯一标识在对接时由平台提供,指令参数为数据内容。通讯协议的数据结构如图4所示。 图4 通讯协议的数据结构 6.1.1通讯包结构组成 名称 类型 长度

ccf19881030的专栏 2万+

【Laravel系列3.4】中间件在路由与控制器中的应用

中间件在路由与控制器中的应用中间件是什么?在传统框架的年代,很少会有中间件这个概念。我最早接触这个概念其实是在学习 MySQL 的时候,了解过 MyCat 这类的组件也被称为中间件。既然是...

硬核项目经理 3112

微信小程序逆向实战:从HTTPS抓包到API接口全解构

方案原理优点缺点方案一:使用低版本微信+系统代理微信7.0以下版本未强制不走代理操作简单容易被封号,无法使用新版小程序方案二:Hook SSL层(Xposed/Frida)动态Hook Java的TrustManager或系统的SSLContext,绕过证书校验灵活可控需要Root/越狱,技术门槛高方案三:VPN转发抓包(PacketCapture)利用Android VPNService将所有流量转发到本地代理无需Root,兼容性好部分机型存在性能问题。

2201_76125261的博客 265

go资深之路笔记(四)中间件(Middleware)设计模式

本文介绍了Go语言中Web框架中间件的实现原理,通过装饰器模式和责任链模式将多个中间件串联执行。核心是通过Middleware函数类型和ApplyMiddleware方法构建处理链,其中每个中间件都能在调用前后添加逻辑。文中提供了日志记录和认证两个中间件示例,日志中间件会记录请求耗时和状态码,认证中间件会检查请求头中的token。最后通过ApplyMiddleware将中间件应用到业务处理器上,形成"日志→认证→业务"的执行顺序。这种设计模式使得中间件可以灵活组合,便于扩展和维护。

h799710的博客 567

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Gin框架学习day04

上面看源码得知,Gin的中间件其实就是一个个HandlerFunc,我们要想自定义中间件,只需要自己实现一个HandlerFunc。start := time.Now() //获取当前时间c.Next() //执行请求cost := time.Since(start) //计算耗时// 1. 创建路由引擎}))adminGroup.Use(exeTime()) //在adminGroup中添加中间件中间件可以做的事情还有很多,如日志记录、授权校验、过滤。

Hello_world2020的博客 1136

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Rust Web:Rocket过滤器链(FromRequest)的源码实现与责任链模式应用

本文深入剖析Rocket框架中FromRequest过滤器链的源码实现,揭示其背后基于责任链模式的设计哲学。通过分析Rocket的中间件架构、请求处理流程和类型安全机制,我们将理解如何利用FromRequest trait构建可扩展的请求验证系统。文章包含源码级解析、设计模式应用和性能优化策略,为Rust Web开发者提供构建企业级应用的中间件设计参考。Rocket框架中的FromRequest trait定义在模块中,它是整个过滤器链架构的基石。///关联类型Error。

摘星编程的博客 6526

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

FastAPI 中间件开发与高级应用

FastAPI中间件作为请求处理管道的核心组件,为开发者提供了强大的扩展能力和灵活性。通过深入理解中间件的设计原理和掌握高级开发技巧,我们可以构建出更加健壮、高性能的Web服务。想必你已系统性地了解了FastAPI中间件的核心概念、实现方法和理解了最佳实践,认证授权、性能优化、错误处理等关键场景。在实际项目开发中,建议你根据具体需求合理设计中间件组合,注意执行顺序和性能影响,同时充分利用现有的成熟中间件解决方案。随着技术的不断发展,中间件在云原生、微服务等现代架构中的重要性将进一步提升。

haolove527的专栏 471

Go中间件开发进阶之路(从入门到生产级落地)

掌握Go中间件开发核心方法,提升Web服务扩展性与性能。涵盖HTTP中间件设计模式、责任链实现、认证日志等场景应用,解析生产级最佳实践。从入门到落地全程详解,值得收藏。

CodeVibe的博客 685

Gearbox中间件完全指南:从日志记录到JWT认证的完整实现

Gearbox是一个用Go编写的高性能Web框架,其轻量级架构和灵活的中间件系统使其成为构建现代Web应用的理想选择。本文将详细介绍如何在Gearbox框架中实现从基础日志记录到高级JWT认证的各类中间件,帮助开发者快速掌握中间件开发的核心技巧。 ## 为什么选择Gearbox中间件? Gearbox框架以性能为核心设计目标,其独特的中间件链机制允许开发者在请求处理流程中插入自定义逻辑,而不会

gitblog_00239的博客 606

Sidekiq中间件测试终极指南:拦截器功能与扩展性实战技巧

Sidekiq作为Ruby生态中最受欢迎的后台任务处理框架,其强大的中间件系统为开发者提供了灵活的任务拦截与处理能力。本文将系统讲解Sidekiq中间件的核心原理、测试方法以及扩展技巧,帮助你轻松掌握这一高级特性。 ## 什么是Sidekiq中间件? Sidekiq中间件是一种特殊的拦截器,能够在任务执行的不同阶段介入处理流程。无论是在任务入队前修改参数,还是在执行过程中记录日志、处理异常,中

gitblog_00456的博客 381

Python责任链模式详解:从原理到实战应用

责任链模式是一种行为型设计模式,通过构建处理者链条实现请求的传递与处理。其核心原理是将请求发送者与接收者解耦,每个处理节点只需关注自身职责范围。该模式在Python中广泛应用于多级审批系统、异常处理机制和中间件管道等场景。结合日志处理等实际案例,责任链模式能有效提升代码的可扩展性和维护性。本文通过UML结构解析和Pythonic实现示例,深入讲解如何构建动态可配置的处理链条,并分享与组合模式、装饰器模式等设计模式的结合实践。

weixin_30402231的博客 24

Python HTTP中间件设计:请求/响应拦截器实现原理

在Python HTTP服务开发中,中间件(Middleware)通过拦截请求与响应流,为应用提供了统一的横切点处理能力,其核心实现依赖于责任链模式与装饰器模式的结合。例如,认证中间件将用户信息存入上下文,后续中间件可直接读取。)或框架钩子捕获响应对象。装饰器可将函数注册为请求预处理中间件,在路由处理前执行认证、日志记录等操作。此时,中间件可修改请求头、参数校验或触发限流逻辑,若拦截失败则直接返回错误响应,终止请求链。当客户端发起HTTP请求时,中间件首先通过装饰器或框架提供的钩子函数(如WSGI的。

weixin_73725158的博客 336

责任链模式从原理到实战:告别if-else审批逻辑

在业务系统开发中,随着规则复杂度的提升,if-else层层嵌套往往导致代码难以维护,尤其在审批流程、内容审核等场景中,每次需求变更都牵一发而动全身。设计模式中的责任链模式通过将请求沿一条处理链顺序传递,让每个节点只关注自身职责,从而实现解耦、复用与开闭原则。本文从责任链的核心结构讲起,结合Java完整示例展示如何重构采购审批与请假系统,并深入对比纯职责链与不纯职责链的差异。同时探讨了责任链在日志框架、Web中间件中的典型应用,以及真实项目中容易踩的链断、死循环等坑。最后通过支付风控案例说明如何用责任链优雅管

weixin_42116058的博客 254

从零构建高性能压缩中间件,Go开发者必备技能

掌握Go压缩解压核心技术,构建高性能中间件。适用于微服务通信与文件处理场景,基于Go语言高效实现GZIP、Zlib等算法,提升系统IO性能30%以上。代码简洁易集成,值得收藏。

LogicPlex的博客 750

JavaScript责任链模式:优化深层if嵌套的解决方案

责任链模式是一种行为设计模式,通过将请求沿处理链传递实现逻辑解耦。其核心原理是构建多个独立处理单元,每个单元只处理特定条件,无法处理则传递给下一单元。这种模式能有效解决代码中常见的深层if嵌套问题,提升可读性、可维护性和可测试性。在JavaScript开发中,责任链模式特别适用于Express/Koa中间件、表单验证链等场景。通过将复杂的条件判断拆分为独立的处理单元,开发者可以实现更清晰的代码结构,同时提高组件的复用性。现代前端框架如React/Node.js中,责任链模式常与中间件机制结合,为复杂业务逻辑

weixin_29011993的博客 269

深入理解ASP.NET Core Middleware:构建高效Web应用的关键组件

在ASP.NET Core开发中,Middleware是处理HTTP请求和响应的核心组件。它能够对请求进行预处理,对响应进行后处理,在Web开发中起着至关重要的作用。深入理解其原理和用法,有助于开发者构建高效、灵活且健壮的Web应用。

dotnethello的博客 3047
上一篇: 容器化-Docker volume数据卷
下一篇: 适配器模式
似水明俊德
博客等级 码龄8年 247粉丝 276原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值