跳过正文
  1. Teches/
  2. 通用编程思想/
  3. 编程概念/

中间件工厂

·582 字·3 分钟
目录

概念
#

在函数式编程和软件架构中,中间件工厂是一种创建中间件的高阶函数模式。它是在函数工厂(能够生成其他函数的函数)概念基础上的扩展应用。

定义
#

中间件工厂是一个函数,它接收配置参数并返回一个中间件函数。这种模式常见于Web框架(如Express、Koa)和数据处理流程中。

</> javascript
 1// 中间件工厂示例
 2function createMiddleware(config) {
 3  return function middleware(req, res, next) {
 4    // 使用config和实现中间件逻辑
 5    if (config.condition) {
 6      // 做一些事情
 7    }
 8    next();
 9  };
10}
11
12// 使用
13const myMiddleware = createMiddleware({ condition: true });
14app.use(myMiddleware);

核心意义
#

1. 配置与复用性
#

中间件工厂通过参数化配置,使得单个中间件实现可以适应多种使用场景,大大提高了代码的复用性。

2. 封装与隔离
#

将中间件的创建逻辑封装在工厂函数中,实现了:

  • 内部实现的隐藏
  • 依赖管理的集中化
  • 副作用隔离

3. 动态行为定制
#

允许在运行时根据不同的配置生成具有不同行为的中间件实例。

典型场景
#

  1. 认证中间件:根据不同策略(JWT、OAuth等)生成认证中间件
  2. 日志中间件:根据日志级别、输出目标等配置生成日志中间件
  3. 缓存中间件:根据缓存策略、过期时间等生成缓存处理中间件
  4. 错误处理中间件:根据不同环境(开发/生产)生成错误处理逻辑

高级模式
#

组合式中间件工厂
#

</> javascript
1function composeMiddlewares(...middlewareFactories) {
2  return (config) => {
3    const middlewares = middlewareFactories.map(factory => factory(config));
4    return (req, res, next) => {
5      // 组合中间件的执行逻辑
6    };
7  };
8}

条件式中间件工厂
#

</> javascript
1function conditionalMiddleware(condition, trueMiddleware, falseMiddleware) {
2  return (req, res, next) => {
3    const middleware = condition(req) ? trueMiddleware : falseMiddleware;
4    return middleware(req, res, next);
5  };
6}

设计考量
#

  1. 单一职责:每个中间件工厂应专注于一个明确的功能
  2. 无状态设计:尽可能设计无状态的中间件,状态应通过配置传入
  3. 明确的接口:定义清晰的配置参数和返回的中间件接口
  4. 可测试性:确保中间件工厂和生成的中间件都易于单元测试

中间件工厂模式通过将创建逻辑与执行逻辑分离,为复杂应用提供了更灵活、更可维护的架构解决方案。

示例
#

Python 示例
#

1. Flask 中间件工厂
#

</> python
 1from flask import Flask, request
 2
 3app = Flask(__name__)
 4
 5def create_logging_middleware(log_level='INFO'):
 6    def logging_middleware(next_middleware):
 7        def wrapper(*args, **kwargs):
 8            if log_level == 'DEBUG':
 9                print(f"Request: {request.method} {request.path}")
10            response = next_middleware(*args, **kwargs)
11            if log_level == 'DEBUG':
12                print(f"Response: {response.status_code}")
13            return response
14        return wrapper
15    return logging_middleware
16
17# 使用中间件工厂
18debug_logging = create_logging_middleware(log_level='DEBUG')
19app.before_request(debug_logging)
20
21@app.route('/')
22def home():
23    return "Hello, World!"
24
25if __name__ == '__main__':
26    app.run()

2. 通用 Python 中间件工厂
#

</> python
 1def create_auth_middleware(required_role):
 2    def auth_middleware(request_handler):
 3        def wrapper(request):
 4            if request.get('user_role') != required_role:
 5                return {'error': 'Unauthorized'}, 403
 6            return request_handler(request)
 7        return wrapper
 8    return auth_middleware
 9
10# 使用
11admin_auth = create_auth_middleware(required_role='admin')
12
13@admin_auth
14def handle_admin_request(request):
15    return {'data': 'Admin resource'}
16
17# 测试
18print(handle_admin_request({'user_role': 'admin'}))  # 正常
19print(handle_admin_request({'user_role': 'user'}))   # 返回403错误

Go 示例
#

1. HTTP 中间件工厂
#

</> go
 1package main
 2
 3import (
 4	"fmt"
 5	"net/http"
 6)
 7
 8// 中间件工厂:创建日志中间件
 9func loggingMiddlewareFactory(logLevel string) func(http.Handler) http.Handler {
10	return func(next http.Handler) http.Handler {
11		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
12			if logLevel == "DEBUG" {
13				fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
14			}
15			next.ServeHTTP(w, r)
16		})
17	}
18}
19
20func mainHandler(w http.ResponseWriter, r *http.Request) {
21	w.Write([]byte("Hello, World!"))
22}
23
24func main() {
25	// 使用中间件工厂
26	debugLogging := loggingMiddlewareFactory("DEBUG")
27	
28	mux := http.NewServeMux()
29	mux.Handle("/", debugLogging(http.HandlerFunc(mainHandler)))
30	
31	http.ListenAndServe(":8080", mux)
32}

2. 认证中间件工厂
#

</> go
 1package main
 2
 3import (
 4	"net/http"
 5)
 6
 7// 中间件工厂:创建认证中间件
 8func authMiddlewareFactory(requiredRole string) func(http.Handler) http.Handler {
 9	return func(next http.Handler) http.Handler {
10		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11			userRole := r.Header.Get("X-User-Role")
12			if userRole != requiredRole {
13				w.WriteHeader(http.StatusForbidden)
14				w.Write([]byte("Forbidden"))
15				return
16			}
17			next.ServeHTTP(w, r)
18		})
19	}
20}
21
22func adminHandler(w http.ResponseWriter, r *http.Request) {
23	w.Write([]byte("Admin Area"))
24}
25
26func main() {
27	adminAuth := authMiddlewareFactory("admin")
28	
29	mux := http.NewServeMux()
30	mux.Handle("/admin", adminAuth(http.HandlerFunc(adminHandler)))
31	
32	http.ListenAndServe(":8080", mux)
33}

3. Go 中间件链工厂
#

</> go
 1package main
 2
 3import (
 4	"net/http"
 5)
 6
 7// 中间件链工厂
 8func middlewareChainFactory(middlewares ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
 9	return func(final http.Handler) http.Handler {
10		for i := len(middlewares) - 1; i >= 0; i-- {
11			final = middlewares[i](final)
12		}
13		return final
14	}
15}
16
17func main() {
18	logging := loggingMiddlewareFactory("INFO")
19	auth := authMiddlewareFactory("user")
20	
21	// 创建中间件链
22	chain := middlewareChainFactory(logging, auth)
23	
24	mux := http.NewServeMux()
25	mux.Handle("/", chain(http.HandlerFunc(mainHandler)))
26	
27	http.ListenAndServe(":8080", mux)
28}

这些示例展示了如何在 Python 和 Go 中实现中间件工厂模式,包括日志记录、认证等常见用例。中间件工厂模式使得中间件的创建更加灵活和可配置,同时保持了代码的整洁和可维护性。