1.0 六大设计原则
问题1:你了解哪些设计原则?请谈谈你的理解。
单一职责原则:一个类只负责一件事
开闭原则:对修改关闭,对扩展开放
接口隔离原则:使用多个专门的协议,而不是一个庞大臃肿的协议,协议中的方法应该尽量少
依赖倒置原则:抽象不应该依赖于具体实现,具体实现可以依赖于抽象
里氏替换原则:父类可以被子类无缝替换,且原有功能不受任何影响
迪米特法则:一个对象应当对其他对象有尽可能少的了解,高内聚,低耦合
2.0 责任链设计模式相关面试问题
某一对象或者类它有一个成员变量,也是当前类的一个类型的成员变量就可以组成责任链模式
问题1:一个关于需求变更的问题-业务A-业务B-业务C 修改业务顺序 业务C-业务B-业务A
使用责任链模式来解决业务顺序调整的问题。
#import <Foundation/Foundation.h>
@class BusinessObject;
typedef void(^CompletionBlock)(BOOL handled);
typedef void(^ResultBlock)(BusinessObject *handler, BOOL handled);
@interface BusinessObject : NSObject
// 下一个响应者(响应链构成的关键)
@property (nonatomic, strong) BusinessObject *nextBusiness;
// 响应者的处理方法
- (void)handle:(ResultBlock)result;
// 各个业务在该方法当中做实际业务处理
- (void)handleBusiness:(CompletionBlock)completion;
@end
#import "BusinessObject.h"
@implementation BusinessObject
// 责任链入口方法
- (void)handle:(ResultBlock)result
{
CompletionBlock completion = ^(BOOL handled){
// 当前业务处理掉了,上抛结果
if (handled) {
result(self, handled);
}
else{
// 沿着责任链,指派给下一个业务处理
if (self.nextBusiness) {
[self.nextBusiness handle:result];
}
else{
// 没有业务处理, 上抛
result(nil, NO);
}
}
};
// 当前业务进行处理
[self handleBusiness:completion];
}
- (void)handleBusiness:(CompletionBlock)completion
{
/*
业务逻辑处理
如网络请求、本地照片查询等
*/
}
@end
3.0 桥接
问题1:一个关于桥接业务解耦的问题
A1 -> B1,B2,B3
A2 -> B1,B2,B3
A3 -> B1,B2,B3
#import <Foundation/Foundation.h>
#import "BaseObjectB.h"
@interface BaseObjectA : NSObject
// 桥接模式的核心实现
@property (nonatomic, strong) BaseObjectB *objB;
// 获取数据
- (void)handle;
@end
/*
根据实际业务判断使用那套具体数据
A1 --> B1、B2、B3 3种
A2 --> B1、B2、B3 3种
A3 --> B1、B2、B3 3种
*/
- (void)fetch
{
// 创建一个具体的ClassA
_objA = [[ObjectA1 alloc] init];
// 创建一个具体的ClassB
BaseObjectB *b1 = [[ObjectB1 alloc] init];
// 将一个具体的ClassB1 指定给抽象的ClassB
_objA.objB = b1;
// 获取数据
[_objA handle];
}
4.0 单例模式
问题1:手写一个单利模式
#import "Mooc.h"
@implementation Mooc
+ (id)sharedInstance
{
// 静态局部变量
static Mooc *instance = nil;
// 通过dispatch_once方式 确保instance在多线程环境下只被创建一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 创建实例
instance = [[super allocWithZone:NULL] init];
});
return instance;
}
// 重写方法【必不可少】
+ (id)allocWithZone:(struct _NSZone *)zone{
return [self sharedInstance];
}
// 重写方法【必不可少】
- (id)copyWithZone:(nullable NSZone *)zone{
return self;
}
@end
面试总结
问题1:描述一下单例模式
通过dispatch_once方式 确保instance在多线程环境下只被创建一次,重写allocaWithZone和copyWithZone方法,并且在dispatch_once当中创建当前实例需要使用[super allocWithZone]方法来创建,用来防止其他人直接使用alloc和init试图获得一个新实例的时候不产生一个新实例
问题2:你都知道哪些设计原则,请谈谈你的理解
单一职责原则:一个类只负责一件事
开闭原则:对修改关闭,对扩展开放
接口隔离原则:使用多个专门的协议,而不是一个庞大臃肿的协议,协议中的方法应该尽量少
依赖倒置原则:抽象不应该依赖于具体实现,具体实现可以依赖于抽象
里氏替换原则:父类可以被子类无缝替换,且原有功能不受任何影响
迪米特法则:一个对象应当对其他对象有尽可能少的了解,高内聚,低耦合
问题3:能否描述一下侨接模式的主体结构
定义一个抽象的父类A和抽象的父类B,把抽象父类B作为A的一个成员值,这样就可以衍生出A1到B1,以及A1到B2,A1到B3,等等的联系,两个父类其中持有一个它实际上就构成了桥接模式的桥梁关键作用。
问题4:UI事件传递机制是怎样实现的?你对其中运用到的设计模式是怎样理解的?
责任链模式,一个类它有一个成员变量也是当前类的类型,这就构成了责任链模式主体建构。