用DeepSeek学源码-SDWebImage 中用到了哪些设计模式?

58 阅读2分钟

SDWebImage 中常用的设计模式

设计模式应用场景SDWebImage中的示例
单例模式全局共享的缓存/下载管理SDImageCache, SDWebImageManager
工厂模式编解码器动态注册与选择SDImageCodersManager + SDImageCoder协议
观察者模式图片加载进度/结果通知Block回调(如SDInternalCompletionBlock
外观模式简化复杂API的统一入口UIImageView+WebCache分类方法
策略模式自定义缓存/下载行为SDWebImageOptions参数配置
代理模式定制网络请求行为(如认证)SDWebImageDownloaderDelegate(早期版本)
组合模式缓存层级管理(内存+磁盘)SDImageCache内部的内存与磁盘缓存组合

Objective-C 实现示例

1. 单例模式:SDImageCache

核心代码

// SDImageCache.h
@interface SDImageCache : NSObject
+ (instancetype)sharedImageCache;
@end

// SDImageCache.m
@implementation SDImageCache
static SDImageCache *_sharedInstance;

+ (instancetype)sharedImageCache {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}
@end

2. 工厂模式:图片编解码器

抽象协议 (SDImageCoder)

@protocol SDImageCoder <NSObject>
+ (BOOL)canDecodeFromData:(NSData *)data;
- (UIImage *)decodedImageWithData:(NSData *)data options:(NSDictionary *)options;
@end

具体工厂 (SDImageWebPCoder)

@interface SDImageWebPCoder : NSObject <SDImageCoder>
@end

@implementation SDImageWebPCoder
+ (BOOL)canDecodeFromData:(NSData *)data {
    // 检查是否为 WebP 数据
    return [SDImageWebPCoder isWebPFormatForData:data];
}

- (UIImage *)decodedImageWithData:(NSData *)data options:(NSDictionary *)options {
    // 调用 WebP 解码库
    return [UIImage sd_imageWithWebPData:data];
}
@end

// 工厂管理类
@interface SDImageCodersManager : NSObject
+ (instancetype)sharedManager;
- (void)addCoder:(id<SDImageCoder>)coder;
@end

3. 观察者模式:进度与完成回调

使用 Block 实现观察逻辑

// 用户调用示例
[imageView sd_setImageWithURL:url 
             placeholderImage:nil 
                      options:0 
                     progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL *targetURL) {
    // 进度更新通知(类似观察者)
    CGFloat progress = (CGFloat)receivedSize / expectedSize;
} 
                    completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
    // 完成结果通知
}];

4. 外观模式:统一接口封装

UIImageView 分类简化调用

// UIImageView+WebCache.h
@interface UIImageView (WebCache)
- (void)sd_setImageWithURL:(NSURL *)url;
@end

// UIImageView+WebCache.m
@implementation UIImageView (WebCache)
- (void)sd_setImageWithURL:(NSURL *)url {
    // 内部组合下载器、缓存管理器、解码器
    [[SDWebImageManager sharedManager] loadImageWithURL:url 
                                               options:0 
                                              progress:nil 
                                             completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
        self.image = image;
    }];
}
@end

5. 策略模式:缓存选项控制

通过枚举配置策略

typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
    SDWebImageRetryFailed = 1 << 0,          // 失败后重试
    SDWebImageLowPriority = 1 << 1,          // 低优先级下载
    SDWebImageCacheMemoryOnly = 1 << 2,      // 仅使用内存缓存
};

// 使用示例(选择仅内存缓存策略)
[imageView sd_setImageWithURL:url 
             placeholderImage:nil 
                      options:SDWebImageCacheMemoryOnly];

设计模式优势总结

  • 单例模式:全局资源统一管理,避免重复实例化。
  • 工厂模式:解耦编解码逻辑,灵活支持扩展新格式。
  • 观察者模式:异步事件通知,提升响应式交互体验。
  • 外观模式:简化API调用复杂度,降低使用门槛。
  • 策略模式:动态切换算法,适应多样化需求场景。

通过组合这些设计模式,SDWebImage构建了一个高度模块化、可扩展的图片加载框架。

(ps: 以上大部分内容使用 DeepSeek R 生成,作者有部分内容调整,如有任何不正确之处欢迎指正)