- 注意!!!! 如果你是技术大牛、技术大咖,请略过这篇文章避免耽搁您的时间,这篇文章属于入门级别。😀
什么是构建者模式?
- 构建者模式是创建型设计模式(单利模式、工厂模式、构建者模式、原型模式)之一。
- 将一个复杂的对象的创建和表示进行分离,同时你创建的顺序不一样,表示也不一样。(表示:我们看到的外观,也就是程序中UI显示
创建:制造的过程封装,在使用的时候不需要使用者关心) - 使用场景? 1、相同的方法,调用的顺序不一样,产生的结果不一样 2、多个部件都可以组装到一个对象上,但是产生的结果不一样 3、当一个类非常复杂的时候,并且需要初始化默认初始化参数(如:网络请求)
下面看一个基础原理程序案例(以电脑为例):👇
//----------------------先来定义两个抽象协议-------------------
//电脑的抽象协议
@protocol IComputer <NSObject>
//处理器
- (void)cpu:(NSString *)cpu;
//显卡
- (void)display:(NSString *)display;
//主板
- (void)mainboard:(NSString *)mainboard;
//系统
- (void)os;
@end
//构建者抽象协议
@protocol IComputerBuilder <NSObject>
//构建CPU
- (id<IComputerBuilder>)buildCPU:(NSString *)cpu;
//构建显卡
- (id<IComputerBuilder>)buildDisplay:(NSString *)display;
//构建主板
- (id<IComputerBuilder>)buildMainboard:(NSString *)mainboard;
//构建系统
- (id<IComputerBuilder>)buildOS:(NSString *)os;
//构建
- (id<IComputer>)build;
@end
//----------------构建具体的类并实现协议------------------
@interface LevenoComputer ()<IComputer>
@end
@implementation LevenoComputer
//处理器
- (void)cpu:(NSString *)cpu {
NSLog(@"Leveno处理器CPU:%@", cpu);
}
//显卡
- (void)display:(NSString *)display {
NSLog(@"Leveno显卡:%@", display);
}
//主板
- (void)mainboard:(NSString *)mainboard {
NSLog(@"Leveno主板:%@", mainboard);
}
//系统
- (void)os {
NSLog(@"windows");
}
@end
//具体的构建者实现构建者抽象协议
@interface LevenoComputerBuilder ()<IComputerBuilder>
@property (nonatomic, strong) id<IComputer> computer;
@end
@implementation LevenoComputerBuilder
- (instancetype)init{
self = [super init];
if (self) {
_computer = [[LevenoComputer alloc] init];
}
return self;
}
//构建CPU
- (id<IComputerBuilder>)buildCPU:(NSString *)cpu {
[_computer cpu:cpu];
return self;
}
//构建显卡
- (id<IComputerBuilder>)buildDisplay:(NSString *)display {
[_computer display:display];
return self;
}
//构建主板
- (id<IComputerBuilder>)buildMainboard:(NSString *)mainboard {
[_computer mainboard:mainboard];
return self;
}
//构建系统
- (id<IComputerBuilder>)buildOS:(NSString *)os {
[_computer os];
return self;
}
//构建
- (id<IComputer>)build {
NSLog(@"构建了一台Leveno💻");
//正式的项目中其实这里有很多的逻辑
return _computer;
}
//----------在客户端(ViewController)里面使用一下
id<IComputerBuilder> builder2 = [[LevenoComputerBuilder alloc] init];
//链式编程
[[[[[builder2 buildCPU:@"inter i5"] buildDisplay:@"独立显卡2G"] buildMainboard:@"三星主板"] buildOS:@""] build];
理解了上边的原理案例后 我们来看一个项目中实际运用的例子(我们平常用的UIAlertViewController)使用构建者模式来封装一下,进行项目的解耦和。如下👇:
import UIKit
//使用Builder设计模式自定义一个alert SLAlertController不能再外部实例化对象,只能在内部使用(否则没有意义)
class SLAlertController: NSObject {
//不允许外部进行初始化
private var params:BuilderParams?
private init(params:BuilderParams) {
super.init()
self.params = params
}
//显示controller
func showAlert() {
let alert = UIAlertController(title: self.params?.title, message: self.params?.message, preferredStyle: UIAlertControllerStyle.alert)
if self.params?.confirmTitle != nil {
alert.addAction(UIAlertAction(title: self.params?.confirmTitle, style: UIAlertActionStyle.destructive, handler: self.params?.confirmHandle))
}
if self.params?.cancelTitle != nil {
alert.addAction(UIAlertAction(title: self.params?.cancelTitle, style: UIAlertActionStyle.cancel, handler: self.params?.cancelHandle))
}
self.params?.context?.present(alert, animated: true) {
}
}
//参数和构建的分离
class BuilderParams: NSObject {
//上下文,用AlertController
var context:UIViewController?
//alert 的提示标题
var title:String?
//alert 的提示信息
var message:String?
//确定按钮
var confirmTitle:String?
//取消按钮
var cancelTitle:String?
//确定回调
var confirmHandle:((UIAlertAction) -> Swift.Void)?
//取消回调
var cancelHandle:((UIAlertAction) -> Swift.Void)?
init(context:UIViewController) {
super.init()
self.context = context
}
}
class Builder: NSObject {
private var param:BuilderParams?
init(context:UIViewController) {
super.init()
self.param = BuilderParams(context: context)
}
func setTitle(_ title:String) -> Builder {
self.param?.title = title
return self
}
func setMessage(_ message:String) -> Builder {
self.param?.message = message
return self
}
func setConfirmTitle(_ confirmTitle:String) -> Builder {
self.param?.confirmTitle = confirmTitle
return self
}
func setCancelTitle(_ cancelTitle:String) -> Builder {
self.param?.cancelTitle = cancelTitle
return self
}
func setConfirmHandle(_ confirmHandle: ((UIAlertAction) -> Swift.Void)? = nil) -> Builder {
self.param?.confirmHandle = confirmHandle
return self
}
func setCancelHandle (_ cancelHandle :((UIAlertAction) -> Swift.Void)? = nil) -> Builder {
self.param?.cancelHandle = cancelHandle
return self
}
//最后构建
func build() -> SLAlertController {
return SLAlertController(params: self.param!)
}
}
}
//============对构建者的alert我们测试一下============
//构建者设计的alert使用写方法
let alert = SLAlertController.Builder(context: self)
alert.setTitle("提示").setMessage("你确定要删除这张图片吗?").setCancelTitle("取消").setCancelHandle { (UIAlertAction) in
print("取消")
}.setConfirmTitle("确定").setConfirmHandle { (UIAlertAction) in
print("确定")
}.build().showAlert()
- 这样来写的话,避免了在一个程序中多次使用
UIAlertController
后,如果需求改了,你需要去程序中一个一个的改,改的你到时候怀疑人生(改的想死)。
网友评论