热门角色不仅是灵感来源,更是你的效率助手。通过精挑细选的角色提示词,你可以快速生成高质量内容、提升创作灵感,并找到最契合你需求的解决方案。让创作更轻松,让价值更直接!
我们根据不同用户需求,持续更新角色库,让你总能找到合适的灵感入口。
为指定的设计模式提供详细解析,覆盖结构、关键角色、使用场景与优缺点,并结合具体编程语言附上清晰代码示例,帮助开发者快速理解并应用设计模式。
以下从软件设计角度和 Go 语言的实现习惯,系统讲解策略模式(Strategy Pattern),并给出一个中等复杂度的示例。
一、作用
二、结构(关键组件与角色)
三、常见使用场景
四、优缺点
五、Go 语言实现示例(重试与回退策略) 说明:
代码:
package main
import (
	"context"
	"fmt"
	"math"
	"math/rand"
	"time"
)
// Strategy:回退策略接口
type BackoffStrategy interface {
	NextDelay(attempt int, err error) time.Duration
}
// ConcreteStrategy:固定间隔回退
type ConstantBackoff struct {
	Interval time.Duration
}
func (c ConstantBackoff) NextDelay(attempt int, err error) time.Duration {
	return c.Interval
}
// ConcreteStrategy:指数回退(带最大值与抖动)
type ExponentialBackoff struct {
	Base   time.Duration // 初始基准延迟
	Factor float64       // 每次递增的倍率
	Max    time.Duration // 最大延迟
	Jitter float64       // 抖动比例,范围 [0,1] 较为合理,表示±百分比
}
func (e ExponentialBackoff) NextDelay(attempt int, err error) time.Duration {
	if attempt < 1 {
		attempt = 1
	}
	delay := float64(e.Base) * math.Pow(e.Factor, float64(attempt-1))
	if e.Max > 0 && time.Duration(delay) > e.Max {
		delay = float64(e.Max)
	}
	// 应用抖动:在 [1-Jitter, 1+Jitter] 区间随机缩放
	if e.Jitter > 0 {
		min := 1 - e.Jitter
		max := 1 + e.Jitter
		noise := min + rand.Float64()*(max-min)
		delay *= noise
	}
	if delay < 0 {
		delay = 0
	}
	return time.Duration(delay)
}
// 可选:用于判断是否应该重试的谓词策略
type RetryPredicate func(error) bool
// 一个用于示例的临时错误接口
type TemporaryError interface {
	error
	Temporary() bool
}
type transientError struct{ msg string }
func (e transientError) Error() string   { return e.msg }
func (e transientError) Temporary() bool { return true }
// Context:重试器,封装重试流程并使用 BackoffStrategy
type Retrier struct {
	MaxAttempts int
	Backoff     BackoffStrategy
	ShouldRetry RetryPredicate // 可选,不设置则全部重试
}
func NewRetrier(max int, backoff BackoffStrategy, pred RetryPredicate) *Retrier {
	return &Retrier{
		MaxAttempts: max,
		Backoff:     backoff,
		ShouldRetry: pred,
	}
}
func (r *Retrier) Do(ctx context.Context, op func(context.Context) error) error {
	if r.MaxAttempts < 1 {
		return fmt.Errorf("MaxAttempts must be >= 1")
	}
	var lastErr error
	for attempt := 1; attempt <= r.MaxAttempts; attempt++ {
		err := op(ctx)
		if err == nil {
			return nil
		}
		lastErr = err
		if r.ShouldRetry != nil && !r.ShouldRetry(err) {
			return err
		}
		if attempt == r.MaxAttempts {
			break
		}
		delay := r.Backoff.NextDelay(attempt, err)
		fmt.Printf("attempt=%d failed: %v; backing off for %v\n", attempt, err, delay)
		// 尊重上下文取消或超时
		select {
		case <-time.After(delay):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
	return lastErr
}
// 一个不稳定的服务,用于演示
type flakyService struct {
	failUntil int // 前 failUntil 次调用都会失败
	calls     int
}
func (s *flakyService) call(ctx context.Context) error {
	s.calls++
	fmt.Printf("calling service (attempt %d)\n", s.calls)
	if s.calls <= s.failUntil {
		return transientError{msg: "network glitch"}
	}
	// 模拟成功
	fmt.Println("service succeeded")
	return nil
}
func main() {
	rand.Seed(time.Now().UnixNano())
	// 上下文设置 5 秒超时
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	svc := &flakyService{failUntil: 3}
	// 使用指数回退策略(带抖动)
	exp := ExponentialBackoff{
		Base:   100 * time.Millisecond,
		Factor: 2.0,
		Max:    1 * time.Second,
		Jitter: 0.3, // ±30% 抖动
	}
	shouldRetry := func(err error) bool {
		// 只重试临时错误
		if te, ok := err.(TemporaryError); ok && te.Temporary() {
			return true
		}
		return false
	}
	retrier := NewRetrier(5, exp, shouldRetry)
	fmt.Println("== Run with ExponentialBackoff ==")
	if err := retrier.Do(ctx, svc.call); err != nil {
		fmt.Printf("final error: %v\n", err)
	}
	// 运行时切换策略:改为固定间隔策略
	fmt.Println("\n== Switch to ConstantBackoff ==")
	retrier.Backoff = ConstantBackoff{Interval: 200 * time.Millisecond}
	svc.failUntil = 5
	svc.calls = 0
	if err := retrier.Do(ctx, svc.call); err != nil {
		fmt.Printf("final error: %v\n", err)
	}
}
要点解析(结合示例)
实践建议(Go 习惯)
通过上述结构与示例,你可以把任何可替换的算法封装为策略接口或函数类型,做到在 Go 项目中既优雅又高效地管理行为变体。
以下内容围绕观察者模式在 TypeScript 中的作用、结构、常见使用场景、优缺点,并附上一个简单清晰的代码示例。
作用
结构(关键组件与角色)
两种通知模式(重要变体)
常见使用场景
优点
缺点
TypeScript 简单示例(Push 模式,强类型)
// 定义观察者接口(泛型,强类型)
interface Observer<T> {
  update(data: T): void;
}
// 定义主题接口
interface Subject<T> {
  attach(observer: Observer<T>): () => void; // 返回取消订阅函数,便于使用
  detach(observer: Observer<T>): void;
  notify(data: T): void;
}
// 一个具体主题:温度传感器(推送最新温度)
class TemperatureSensor implements Subject<number> {
  private observers = new Set<Observer<number>>();
  private temperature = 20;
  attach(observer: Observer<number>): () => void {
    this.observers.add(observer);
    // 返回取消订阅函数,避免遗忘 detach
    return () => this.detach(observer);
  }
  detach(observer: Observer<number>): void {
    this.observers.delete(observer);
  }
  setTemperature(value: number): void {
    this.temperature = value;
    this.notify(this.temperature);
  }
  notify(data: number): void {
    // 复制迭代,避免通知过程中集合被修改影响遍历
    for (const obs of [...this.observers]) {
      try {
        obs.update(data);
      } catch (err) {
        console.error('Observer failed:', err);
      }
    }
  }
}
// 具体观察者:仪表盘显示
class DashboardDisplay implements Observer<number> {
  update(temp: number): void {
    console.log(`Dashboard: current temperature is ${temp}°C`);
  }
}
// 具体观察者:风扇控制器
class FanController implements Observer<number> {
  update(temp: number): void {
    const on = temp >= 28;
    console.log(on ? 'FanController: Fan ON' : 'FanController: Fan OFF');
  }
}
// 使用
const sensor = new TemperatureSensor();
const dashboard = new DashboardDisplay();
const fan = new FanController();
const unsubscribeFan = sensor.attach(fan);
sensor.attach(dashboard);
sensor.setTemperature(26); // 通知:风扇关、仪表盘显示
sensor.setTemperature(31); // 通知:风扇开、仪表盘显示
unsubscribeFan();          // 取消订阅风扇
sensor.setTemperature(25); // 仅仪表盘接收通知
实践建议
下面从架构视角系统讲解装饰器模式在 Python 中的作用、结构、使用场景与优缺点,并附上一个较为复杂但清晰的示例代码。
一、作用
二、结构(关键组件与角色)
三、常见使用场景
四、优缺点
五、代码示例(复杂示例:在数据获取组件上叠加缓存、重试、熔断、度量) 说明:
代码:
import time
import random
from abc import ABC, abstractmethod
from collections import OrderedDict
from typing import Dict, Optional, Tuple, Any
# =========================
# 领域与错误类型
# =========================
class TransientError(Exception):
    """可重试的瞬时错误(例如网络抖动、服务暂不可用)。"""
    pass
class NotFoundError(Exception):
    """不可重试的错误(例如资源不存在)。"""
    pass
class CircuitOpenError(Exception):
    """熔断器打开,拒绝调用。"""
    pass
# =========================
# 组件接口与具体实现
# =========================
class Fetcher(ABC):
    """Component:数据获取接口"""
    @abstractmethod
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        pass
class UnstableFetcher(Fetcher):
    """
    ConcreteComponent:不稳定的数据源,模拟真实服务的随机失败与延迟。
    - failure_rate: 随机失败概率(TransientError)
    - latency_range: 延迟范围(秒)
    - data: 简单的URL->字符串数据映射
    """
    def __init__(self, data: Dict[str, str], failure_rate: float = 0.3, latency_range: Tuple[float, float] = (0.05, 0.2)):
        self.data = data
        self.failure_rate = failure_rate
        self.latency_range = latency_range
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        # 模拟随机延迟
        time.sleep(random.uniform(*self.latency_range))
        # 模拟不可重试错误:不存在
        if url not in self.data:
            raise NotFoundError(f"URL not found: {url}")
        # 模拟可重试错误:瞬时失败
        if random.random() < self.failure_rate:
            raise TransientError("Random transient failure.")
        return self.data[url]
# =========================
# 抽象装饰器
# =========================
class FetcherDecorator(Fetcher):
    """Decorator:持有被装饰对象,并实现同样的接口"""
    def __init__(self, inner: Fetcher):
        self._inner = inner
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        return self._inner.fetch(url, headers=headers)
# =========================
# Metrics 度量中心(供多个装饰器共享)
# =========================
class MetricsRegistry:
    def __init__(self):
        self.counters: Dict[str, int] = {}
        self.timers: Dict[str, float] = {}
    def inc(self, key: str, n: int = 1):
        self.counters[key] = self.counters.get(key, 0) + n
    def add_time(self, key: str, ms: float):
        self.timers[key] = self.timers.get(key, 0.0) + ms
    def snapshot(self) -> Dict[str, Any]:
        return {
            "counters": dict(self.counters),
            "timers_ms": dict(self.timers),
        }
# =========================
# ConcreteDecorator:熔断器
# =========================
class CircuitBreakerFetcher(FetcherDecorator):
    """
    熔断器状态机:
      - closed: 正常。累积失败达到阈值 -> open
      - open: 拒绝请求,等待恢复时间 -> half_open
      - half_open: 允许一次试探请求;成功 -> closed;失败 -> open
    """
    def __init__(self, inner: Fetcher, failure_threshold: int = 3, recovery_time: float = 3.0, metrics: Optional[MetricsRegistry] = None):
        super().__init__(inner)
        self.failure_threshold = failure_threshold
        self.recovery_time = recovery_time
        self.metrics = metrics
        self._state = "closed"
        self._consecutive_failures = 0
        self._opened_at = 0.0
        self._half_open_trial_in_progress = False
    def _to_open(self):
        self._state = "open"
        self._opened_at = time.time()
        self._half_open_trial_in_progress = False
    def _maybe_to_half_open(self):
        if self._state == "open" and (time.time() - self._opened_at) >= self.recovery_time:
            self._state = "half_open"
            self._half_open_trial_in_progress = False
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        # open -> half_open if冷却结束
        self._maybe_to_half_open()
        if self._state == "open":
            if self.metrics:
                self.metrics.inc("circuit_open_skips")
            raise CircuitOpenError("Circuit breaker is OPEN")
        if self._state == "half_open":
            # 允许一次试探请求
            if self._half_open_trial_in_progress:
                # 有另一个试探中,拒绝(简单处理并发;单线程可忽略)
                raise CircuitOpenError("Half-open trial in progress")
            self._half_open_trial_in_progress = True
        try:
            result = self._inner.fetch(url, headers=headers)
            # 成功:重置并转为closed(若half_open)
            self._consecutive_failures = 0
            if self._state == "half_open":
                self._state = "closed"
                self._half_open_trial_in_progress = False
            return result
        except Exception as e:
            # 失败:计数并根据阈值转open
            self._consecutive_failures += 1
            if self._state == "half_open":
                # half-open失败立即转open
                self._to_open()
            elif self._consecutive_failures >= self.failure_threshold:
                self._to_open()
            raise
# =========================
# ConcreteDecorator:重试(指数退避+抖动)
# =========================
class RetryFetcher(FetcherDecorator):
    """
    对指定异常进行重试,支持指数退避与随机抖动。
    - retry_exceptions: 需要重试的异常类型集合
    - giveup_exceptions: 直接放弃的异常,不重试(如 CircuitOpenError、NotFoundError)
    """
    def __init__(self, inner: Fetcher, retries: int = 3, backoff_base: float = 0.1,
                 retry_exceptions: Tuple[type, ...] = (TransientError,),
                 giveup_exceptions: Tuple[type, ...] = (CircuitOpenError, NotFoundError),
                 metrics: Optional[MetricsRegistry] = None):
        super().__init__(inner)
        self.retries = retries
        self.backoff_base = backoff_base
        self.retry_exceptions = retry_exceptions
        self.giveup_exceptions = giveup_exceptions
        self.metrics = metrics
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        attempt = 0
        while True:
            try:
                return self._inner.fetch(url, headers=headers)
            except self.giveup_exceptions:
                # 直接放弃,不做重试
                raise
            except self.retry_exceptions as e:
                attempt += 1
                if self.metrics:
                    self.metrics.inc("retries_attempted")
                if attempt > self.retries:
                    raise
                # 指数退避 + 随机抖动
                delay = self.backoff_base * (2 ** (attempt - 1)) * random.uniform(0.8, 1.2)
                time.sleep(delay)
# =========================
# ConcreteDecorator:TTL + LRU 缓存
# =========================
class TTLCache:
    """简单的TTL+LRU缓存实现,用于示例,不考虑并发。"""
    def __init__(self, capacity: int = 128, ttl_seconds: float = 5.0):
        self.capacity = capacity
        self.ttl = ttl_seconds
        self.store: OrderedDict[Any, Tuple[float, Any]] = OrderedDict()
    def _evict_if_needed(self):
        while len(self.store) > self.capacity:
            self.store.popitem(last=False)
    def _purge_expired(self):
        now = time.time()
        expired_keys = [k for k, (exp, _) in self.store.items() if exp < now]
        for k in expired_keys:
            del self.store[k]
    def get(self, key: Any) -> Optional[Any]:
        self._purge_expired()
        if key in self.store:
            exp, val = self.store.pop(key)  # 触发LRU移动
            self.store[key] = (exp, val)
            return val
        return None
    def put(self, key: Any, value: Any):
        exp = time.time() + self.ttl
        if key in self.store:
            del self.store[key]
        self.store[key] = (exp, value)
        self._evict_if_needed()
class CacheFetcher(FetcherDecorator):
    def __init__(self, inner: Fetcher, cache: TTLCache, metrics: Optional[MetricsRegistry] = None):
        super().__init__(inner)
        self.cache = cache
        self.metrics = metrics
    def _key(self, url: str, headers: Optional[Dict[str, str]]) -> Tuple[str, Tuple[Tuple[str, str], ...]]:
        headers_tuple = tuple(sorted((headers or {}).items()))
        return (url, headers_tuple)
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        key = self._key(url, headers)
        val = self.cache.get(key)
        if val is not None:
            if self.metrics:
                self.metrics.inc("cache_hits")
            return val
        if self.metrics:
            self.metrics.inc("cache_misses")
        val = self._inner.fetch(url, headers=headers)
        self.cache.put(key, val)
        return val
# =========================
# ConcreteDecorator:度量
# =========================
class MetricsFetcher(FetcherDecorator):
    def __init__(self, inner: Fetcher, metrics: MetricsRegistry):
        super().__init__(inner)
        self.metrics = metrics
    def fetch(self, url: str, headers: Optional[Dict[str, str]] = None) -> str:
        self.metrics.inc("fetch_calls")
        start = time.time()
        try:
            result = self._inner.fetch(url, headers=headers)
            self.metrics.inc("fetch_success")
            return result
        except Exception:
            self.metrics.inc("fetch_failure")
            raise
        finally:
            elapsed_ms = (time.time() - start) * 1000.0
            self.metrics.add_time("fetch_latency_ms_total", elapsed_ms)
# =========================
# 演示:构建装饰器调用链并运行
# =========================
if __name__ == "__main__":
    # 准备示例数据与度量中心
    data = {
        "item/42": "The answer is 42.",
        "item/7": "Lucky number is 7.",
    }
    metrics = MetricsRegistry()
    # ConcreteComponent
    base = UnstableFetcher(data=data, failure_rate=0.5, latency_range=(0.05, 0.15))
    # 构建调用链(顺序很重要):
    # Cache -> Retry -> CircuitBreaker -> base,最外层再加 Metrics
    cache = TTLCache(capacity=64, ttl_seconds=2.0)
    chain = MetricsFetcher(
        inner=CacheFetcher(
            inner=RetryFetcher(
                inner=CircuitBreakerFetcher(
                    inner=base,
                    failure_threshold=3,   # 连续3次失败打开熔断
                    recovery_time=3.0,     # 3秒后进入half-open
                    metrics=metrics
                ),
                retries=4,               # 最多4次补偿重试
                backoff_base=0.08,       # 初始退避
                retry_exceptions=(TransientError,),
                giveup_exceptions=(CircuitOpenError, NotFoundError),
                metrics=metrics
            ),
            cache=cache,
            metrics=metrics
        ),
        metrics=metrics
    )
    # 连续请求以观察:缓存、重试、熔断与恢复的行为
    url = "item/42"
    for i in range(1, 12):
        try:
            val = chain.fetch(url)
            print(f"[{i:02d}] OK: {val}")
        except CircuitOpenError as e:
            print(f"[{i:02d}] CIRCUIT OPEN: {e}")
        except NotFoundError as e:
            print(f"[{i:02d}] NOT FOUND: {e}")
        except TransientError as e:
            print(f"[{i:02d}] TRANSIENT FAILURE (no more retries): {e}")
        except Exception as e:
            print(f"[{i:02d}] OTHER ERROR: {e}")
        time.sleep(0.7)  # 控制节奏,观察TTL与熔断恢复
    print("\nMetrics snapshot:")
    print(metrics.snapshot())
要点与实践建议:
帮助用户深入理解并掌握指定设计模式的用途、结构及实现方法,通过清晰的讲解和实例代码提升技术技能,从而解决实际开发中的架构问题,并在项目实施中充分运用到设计模式的核心思想。
从事系统开发的程序员,使用提示词快速掌握设计模式理论,学习代码实现,并将其用于项目开发。
想提升团队架构能力的技术领袖,利用本提示词快速生成教学材料并推广设计模式知识,使团队开发更高效。
从事技术教程、博客、书籍撰写的内容创作者,通过提示词快速建立高质量架构文章模板,提高创作效率。
将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。
把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。
在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。
免费获取高级提示词-优惠即将到期