1. Design principles
- Single responsibility principle A class is only responsible for one thing (UIView/CALayer)
- The open closed principle is closed for modification and open for extension
- Interface segregation principle Using multiple special agreement (UITableViewDataSource/UITableViewDelegate)
- Dependency Inversion principle Abstraction should not depend on concrete implementation, concrete implementation can depend on abstraction (data access)
- Richter’s substitution Principle The parent class can be seamlessly replaced by the child class without affecting the original function (KVO)
- Demeter’s Law An object should know as little as possible about other objects, be highly cohesive and coupling less
2. Design patterns
- Chain of Responsibility model
@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
{
// Business processing
}
@end
Copy the code
- The bridge model
A1 –> B1, B2, B3
A2 –> B1, B2, B3
A3 –> B1, B2, B3
@interface BaseObjectB: NSObject
- (void)fetchData;
@end
@implementation BaseObjectB
- (void)fetchData
{
}
@end
Copy the code
#importt "BaseObjectB.h"
@interface BaseObjectA: NSObject
@property(nonatomic.strong) BaseObjectB *objB;
- (void)handle;
@end
@implementation BaseObjectB
- (void)handle
{
[self.objB fetchData];
}
@end
Copy the code
- Adapter mode
How does a class adapt to change
#import "AdaptedObject.h"
@interface FitObject: NSObject
@property (nonatomic.strong) AdaptedObject *adapted;
@end
@implementation FitObject
- (void)request
{
// adapt logic
[self.adapted request];
// adapt logic
}
@end
Copy the code
- The singleton pattern
@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
Copy the code
- Command mode
Behavior parameterization reduces code coincidence
@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
{
// Logical processing
[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
// Command manager
#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]) {
[[selfsharedInstance] arrayCommands addObject:cmd]; cmd.completion = completion; [cmd execute]; }}} + (void)cancelCommand:(Command *)cmd
{
if (cmd) {
[[[selfshareInstance] 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
Copy the code