设计模式

240 阅读2分钟

1、设计原则
  • 单一职责原则 一个类只负责一件事 (UIView/CALayer)
  • 开闭原则 对修改关闭、对扩展开放
  • 接口隔离原则 使用多个专门的协议 (UITableViewDataSource/UITableViewDelegate)
  • 依赖倒置原则 抽象不应依赖于具体实现,具体实现可以依赖与抽象(数据访问)
  • 里氏替换原则 父类可以被子类无缝替换,且原有功能不受任何影响(KVO)
  • 迪米特法则 一个对象应当对其他对象有尽可能少的了解,高内聚、低耦合

2、设计模式

  • 责任链模式
@class Object;
typedef void(^CompletionBlock)(Bool handled);
typedef void(^ResultBlock)(Object *handler, BOOL handled);

@interface Object: NSObject

@property (nonatomic, strong) Object *nextObject;

- (void)handle:(ResultBlock)result;
- (void)handleBusiness:(CompletionBlock)completion;

@end

@implementation Object

- (void)handle:(ResultBlock)result {
    CompletionBlcok completion = ^(BOOL handled) {
        if (handled) {
            return (self, handled);
        } else {
            if (self.nextObject) {
                [self.nextObject handle:result];
            } else {
                result(nil, NO);
            }
        }
    }
    
    [self handBusiness:completion];
}

- (void)handleBusiness:(CompletionBlock)completion 
{
    // 业务处理    
}

@end

  • 桥接模式

A1 --> B1, B2, B3

A2 --> B1, B2, B3

A3 --> B1, B2, B3

@interface BaseObjectB: NSObject

- (void)fetchData;

@end


@implementation BaseObjectB

- (void)fetchData
{
    
}

@end
#importt "BaseObjectB.h"

@interface BaseObjectA: NSObject

@property(nonatomic, strong) BaseObjectB *objB;

- (void)handle;

@end

@implementation BaseObjectB

- (void)handle 
{
    [self.objB fetchData];
}

@end

  • 适配器模式

一个类如何适应变化

#import "AdaptedObject.h"

@interface FitObject: NSObject
@property (nonatomic, strong) AdaptedObject *adapted;
@end

@implementation FitObject

- (void)request 
{
    // 适配逻辑
    [self.adapted request];
    // 适配逻辑
}

@end
  • 单例模式
@implementation SingObject

+ (id)shareInstace 
{
    static SingleObject *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:NULL] init];
    })
    
    return instance;
}

+ (id)allocWithZone:(struct _NSZone *)zone
{
    return [self shareInstance];
}

- (id)copyWithZone:(nullable NSZone *)zone 
{
    return self;
}

@end
  • 命令模式

行为参数化 降低代码重合度

@class Command;
typedef void(^CommandCompletionCallBack)(Command *cmd)

@interface Command: NSObject
@property (nonatomic, copy) CommandCompletionCallBack completion;

- (void)execute;
- (void)cancel;
- (void)done;
@end

@implementation Command

- (void)execute 
{
    // 逻辑处理
    [self done];
}

- (void)cancel 
{
    self.completion = nil;
}

- (void)done
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (_completion) {
            _completion(self)
        }
        
        self.completion = nil;
        
        [[CommandManager shareInstance].arrayCommands removeObject: self];
    })
}
@end

// 命令管理者
#import "Command.h"
@interface CommandManager: NSObject

@property (nonatomic, strong) NSMutableArray<Command *> *commandArr;

+ (instanceType)sharedInstance;

+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion;

+ (void)cancelCommand:(Command *)cmd;
@end

@implementation CommandManager

+ (id)shareInstace 
{
    static CommandManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[super allocWithZone:NULL] init];
    })
    
    return manager;
}

+ (id)allocWithZone:(struct _NSZone *)zone
{
    return [self shareInstance];
}

- (id)copyWithZone:(nullable NSZone *)zone 
{
    return self;
}

+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion
{
    if (cmd) {
        if (![self _isExecutingCommand:cmd]) {
            [[self sharedInstance] arrayCommands addObject:cmd];
            cmd.completion = completion;
            [cmd execute];
        }
    }
}

+ (void)cancelCommand:(Command *)cmd 
{
    if (cmd) {
        [[[self shareInstance] arrayCommands] removeObject:cmd];
        [cmd cancel];
    }
}

+ (BOOL)_isExecutingCommand:(Command *)cmd
{
    if (cmd) {
        NSArray *cmds = [[self shareInstance] arrayCommands];
        for (Command *aCmd in cmds) {
            if (aCmd = cmd) {
                return yes;
            } 
        }
    }
    
    rturn NO;
}
@end