iOS设计模式
Design Pattern, Objective-C, iOS
Word Count: 1.6k(words)
单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #import <Foundation/Foundation.h> @interface SingletonPattern : NSObject - (instancetype) init NS_UNAVAILABLE; + (instancetype) alloc NS_UNAVAILABLE; + (instancetype) shareInstance; @end @implementation SingletonPattern + (instancetype) shareInstance { static dispatch_once_t onceToken; static SingletonPattern *instance; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } @end // 使用 SingletonPattern *singletonObject1 = [SingletonPattern shareInstance]; SingletonPattern *singletonObject2 = [SingletonPattern shareInstance]; NSLog(@"\n%@\n%@", singletonObject1, singletonObject2);
|
工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #import <Foundation/Foundation.h> @interface FactoryPattern : NSObject + (instancetype) createWithType: (NSString *) className; @end @implementation FactoryPattern + (instancetype)createWithType:(NSString *)className { Class class = NSClassFromString(className); return [[class alloc] init]; } @end // 使用 id factoryObject1 = [FactoryPattern createWithType:@"UITableView"]; id factoryObject2 = [FactoryPattern createWithType:@"UIView"]; NSLog(@"%@ %@", NSStringFromClass([factoryObject1 class]), NSStringFromClass([factoryObject2 class]));
|
这里的createWithType可以写成任意形式,参数也可以指定为任意的不同类的区分方式
抽象工厂模式
和工厂模式的区别在于多了一层抽象工厂和子工厂的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| @interface AbstractFactoryPattern : NSObject - (UIView *) createViewWithType: (NSInteger) type; - (UIColor *) createColorWithName: (NSString *) colorName; + (Class) getConcreteFactory: (NSString *) factoryType; @end @implementation AbstractFactoryPattern - (UIView *)createViewWithType:(NSInteger)type { return nil; } - (UIColor *)createColorWithName:(NSString *)colorName { return nil; } + (Class) getConcreteFactory: (NSString *) factoryType { if ([factoryType isEqualToString:@"View"]) { return [ConcreteFactory1 class]; } else{ return [ConcreteFactory2 class]; } } @end @interface ConcreteFactory1 : AbstractFactoryPattern @end @implementation ConcreteFactory1 - (UIView *) createViewWithType: (NSInteger) type { switch (type) { case 1: return [[UITableView alloc] init]; break; case 2: return [[UICollectionView alloc] init]; break; default: return [[UIView alloc] init]; break; } return nil; } @end @interface ConcreteFactory2 : AbstractFactoryPattern @end @implementation ConcreteFactory2 - (UIColor *) createColorWithName: (NSString *) colorName { if ([colorName isEqualToString:@"red"]) { return [UIColor redColor]; } else if ([colorName isEqualToString:@"blue"]) { return [UIColor blueColor]; } else{ return [UIColor blackColor]; } } @end // 使用 AbstractFactoryPattern *concreteFactory1 = [[[AbstractFactoryPattern getConcreteFactory:@"View"] alloc] init]; UIView *viewFromFactory1 = [concreteFactory1 createViewWithType:1]; AbstractFactoryPattern *concreteFactory2 = [[[AbstractFactoryPattern getConcreteFactory:@"Color"] alloc] init]; UIColor *colorFromFactory2 = [concreteFactory2 createColorWithName:@"red"]; NSLog(@"%@ %@", NSStringFromClass([viewFromFactory1 class]), NSStringFromClass([colorFromFactory2 class]));
|
原型模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @protocol PrototypeCopyProtocol <NSObject> @required - (id)clone; @end @interface PrototypePattern : NSObject <PrototypeCopyProtocol> @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *sex; @property (nonatomic, assign)NSInteger age; - (instancetype) initWithName: (NSString *) name andSex: (NSString *) sex andAge: (NSInteger) age; @end @implementation PrototypePattern - (instancetype) initWithName: (NSString *) name andSex: (NSString *) sex andAge: (NSInteger) age { if (self = [super init]) { _name = name; _sex = sex; _age = age; } return self; } - (id)clone { PrototypePattern *prototypeObject = [[PrototypePattern alloc] init]; prototypeObject.name = self.name; prototypeObject.sex = self.sex; prototypeObject.age = self.age; return prototypeObject; } - (NSString *)description { return [NSString stringWithFormat:@"Name: %@, Sex: %@, Age: %ld", _name, _sex, (long)_age]; } @end // 使用 PrototypePattern *prototypeObject1 = [[PrototypePattern alloc] initWithName:@"Peer" andSex:@"Male" andAge:22]; PrototypePattern *prototypeObject2 = [prototypeObject1 clone]; NSLog(@"%@\n%@", prototypeObject1, prototypeObject2);
|
生成器模式
生成器模式和抽象工厂模式的区别在于生成器模式采用的是分part的方式,一次需要一个director指导者对象来调用生成器对象生成对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| @interface BuilderPatternDirector : NSObject @property (nonatomic, strong) AbstractBuilderPattern *builder; - (instancetype) initWithBuilder:(AbstractBuilderPattern *) builder; - (BuilderPatternProduct *) construct; @end @implementation BuilderPatternDirector - (BuilderPatternProduct *)construct { [_builder buildPartA]; [_builder buildPartB]; [_builder buildPartC]; return [_builder getResult]; } - (instancetype)initWithBuilder:(AbstractBuilderPattern *)builder { if (self = [super init]) { _builder = builder; _builder.product = [[BuilderPatternProduct alloc] init]; } return self; } @end @interface BuilderPatternProduct : NSObject @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *sex; @property (nonatomic, assign)NSInteger age; @end @implementation BuilderPatternProduct - (NSString *)description { return [NSString stringWithFormat:@"Name: %@, Sex: %@, Age: %ld", _name, _sex, (long)_age]; } @end @interface AbstractBuilderPattern : NSObject - (void) buildPartA; - (void) buildPartB; - (void) buildPartC; - (BuilderPatternProduct *) getResult; @property (nonatomic, strong) BuilderPatternProduct *product; @end @implementation AbstractBuilderPattern - (void)buildPartA { return; } - (void)buildPartB { return; } - (void)buildPartC { return; } - (BuilderPatternProduct *)getResult { return nil; } @end @interface ConcreteBuilderPattern : AbstractBuilderPattern @end @implementation ConcreteBuilderPattern - (void)buildPartA { self.product.name = @"Peer"; } - (void)buildPartB { self.product.sex = @"Male"; } - (void)buildPartC { self.product.age = 23; } - (BuilderPatternProduct *)getResult { return self.product; } @end // 使用 ConcreteBuilderPattern *builder = [[ConcreteBuilderPattern alloc] init]; BuilderPatternDirector *director = [[BuilderPatternDirector alloc] initWithBuilder:builder]; BuilderPatternProduct *product = [director construct]; NSLog(@"%@", product);
|
代理模式
即对应OC中的protocol和delegate的使用wqdawd
适配器模式
用于对接不同类型的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @interface OriginalClassForAdapterPattern : NSObject - (void) printNSArray: (NSArray *) arr; @end @implementation OriginalClassForAdapterPattern - (void) printNSArray: (NSArray *) arr { NSLog(@"%@", arr); } @end @interface Adapter : NSObject @property (nonatomic, strong) OriginalClassForAdapterPattern *originalClass; - (void) printArr1: (NSArray *) arr1 andArr2: (NSArray *) arr2; @end @implementation Adapter - (instancetype)init { self = [super init]; if (self) { _originalClass = [[OriginalClassForAdapterPattern alloc] init]; } return self; } - (void)printArr1:(NSArray *)arr1 andArr2:(NSArray *)arr2 { NSArray *arr = [arr1 arrayByAddingObjectsFromArray:arr2]; [_originalClass printNSArray:arr]; } @end // 用法 NSArray *arr1 = @[@"eeeee"], *arr2 = @[@"wwwwww"]; Adapter *adapter = [[Adapter alloc] init]; [adapter printArr1:arr1 andArr2:arr2];
|
外观模式
外观模式就相当于对一系列的类做一个上层的封装
桥接模式
桥接模式类似适配器模式,通过将两个类各自抽象出一个抽象类,从而使得耦合都发生在抽象类之间,实现子类的完全解耦。
装饰器模式
即相当于category
观察者模式
即相当于OC中的observer系列使用,主要是双向绑定与耦合的作用,当observe的对象的属性变化时,则可以作出对应的操作。主要是通过实现如下方法:
1
| - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context;
|
注意点在于,有addObserver就一定要记得removeObserver
策略模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @interface AbstractStrategyPattern : NSObject - (void) testWithStrategy: (NSString *) str; @end @implementation AbstractStrategyPattern - (void)testWithStrategy:(NSString *)str { return; } @end @interface ConcreteStrategyPattern1 : AbstractStrategyPattern @end @implementation ConcreteStrategyPattern1 - (void)testWithStrategy:(NSString *)str { NSLog(@"Strategy1 - %@", str); } @end @interface ConcreteStrategyPattern2 : AbstractStrategyPattern @end @implementation ConcreteStrategyPattern2 - (void)testWithStrategy:(NSString *)str { NSLog(@"Strategy2 - %@", str); } @end // 使用 AbstractStrategyPattern *strategy1 = [[ConcreteStrategyPattern1 alloc] init]; AbstractStrategyPattern *strategy2 = [[ConcreteStrategyPattern2 alloc] init]; if ([strategy1 respondsToSelector:@selector(testWithStrategy:)]) { [strategy1 testWithStrategy:@"Strategy"]; } if ([strategy2 respondsToSelector:@selector(testWithStrategy:)]) { [strategy2 testWithStrategy:@"Strategy"]; }
|
责任链模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| @interface AbstractNodeInChain : NSObject @property (nonatomic, strong) AbstractNodeInChain *nextNode; - (void) transimitMsgInChain: (NSString *) msg; - (void) printMsg: (NSString *) msg; @end @implementation AbstractNodeInChain - (void)transimitMsgInChain:(NSString *)msg { AbstractNodeInChain *node = self; while (![node respondsToSelector:@selector(printMsg:)] && node != nil){ node = [node nextNode]; } if (node != nil) { [node printMsg:msg]; } else{ NSLog(@"No node in chain can response."); } } @end @interface ResponsibilityChainPattern : NSObject - (AbstractNodeInChain *)getNodeChain; - (void) logMsgByChain: (NSString *) msg; @end @interface NodeA : AbstractNodeInChain @end @implementation NodeA @end @interface NodeB : AbstractNodeInChain @end @implementation NodeB @end @interface NodeC : AbstractNodeInChain @end @implementation NodeC - (void)printMsg:(NSString *)msg { NSLog(@"%@ - by NodeC", msg); } @end @implementation ResponsibilityChainPattern - (AbstractNodeInChain *)getNodeChain { NodeA *nodeA = [[NodeA alloc] init]; NodeB *nodeB = [[NodeB alloc] init]; NodeC *nodeC = [[NodeC alloc] init]; nodeA.nextNode = nodeB; nodeB.nextNode = nodeC; return nodeA; } - (void)logMsgByChain:(NSString *)msg { AbstractNodeInChain *node = [self getNodeChain]; [node transimitMsgInChain:msg]; } @end // 使用 ResponsibilityChainPattern *responsibilityChainPattern = [[ResponsibilityChainPattern alloc] init]; [responsibilityChainPattern logMsgByChain:@"Here we go!"];
|
Target-Action模式
即常用的addTarget:action函数
中介者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| @protocol AbstractMediatorProtocol <NSObject> @optional - (void) showMsg: (NSString *)msg; @end @interface Mediator : NSObject <AbstractMediatorProtocol> @end @implementation Mediator - (void)showMsg:(NSString *)msg { NSLog(@"%@", [NSString stringWithFormat:@"Message is: %@", msg]); } @end @protocol AbstractColleagueProtocol <NSObject> @optional - (void) sendMsg: (NSString *) msg; @end @interface Colleague : NSObject <AbstractColleagueProtocol> @property (nonatomic, strong) Mediator *mediator; @property (nonatomic, strong) NSString *name; - (instancetype) initWithName: (NSString *)name; @end @implementation Colleague - (instancetype)initWithName:(NSString *)name { if (self = [super init]) { _name = name; _mediator = [[Mediator alloc] init]; } return self; } - (void)sendMsg:(NSString *)msg { [self.mediator showMsg:[NSString stringWithFormat:@"[%@]: %@", self.name, msg]]; } @end // 使用 Colleague *colleague1 = [[Colleague alloc] initWithName:@"Jack"]; Colleague *colleague2 = [[Colleague alloc] initWithName:@"John"]; [colleague1 sendMsg:@"Hi, John!"]; [colleague2 sendMsg:@"Hello, Jack"];
|