概念#
在函数式编程和软件架构中,中间件工厂是一种创建中间件的高阶函数模式。它是在函数工厂(能够生成其他函数的函数)概念基础上的扩展应用。
定义#
中间件工厂是一个函数,它接收配置参数并返回一个中间件函数。这种模式常见于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. 动态行为定制#
允许在运行时根据不同的配置生成具有不同行为的中间件实例。
典型场景#
- 认证中间件:根据不同策略(JWT、OAuth等)生成认证中间件
- 日志中间件:根据日志级别、输出目标等配置生成日志中间件
- 缓存中间件:根据缓存策略、过期时间等生成缓存处理中间件
- 错误处理中间件:根据不同环境(开发/生产)生成错误处理逻辑
高级模式#
组合式中间件工厂#
</>
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}设计考量#
- 单一职责:每个中间件工厂应专注于一个明确的功能
- 无状态设计:尽可能设计无状态的中间件,状态应通过配置传入
- 明确的接口:定义清晰的配置参数和返回的中间件接口
- 可测试性:确保中间件工厂和生成的中间件都易于单元测试
中间件工厂模式通过将创建逻辑与执行逻辑分离,为复杂应用提供了更灵活、更可维护的架构解决方案。
示例#
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 中实现中间件工厂模式,包括日志记录、认证等常见用例。中间件工厂模式使得中间件的创建更加灵活和可配置,同时保持了代码的整洁和可维护性。