設(shè)計(jì)模式之構(gòu)建者模式

  • 注意?。。?! 如果你是技術(shù)大牛、技術(shù)大咖,請(qǐng)略過這篇文章避免耽擱您的時(shí)間,這篇文章屬于入門級(jí)別。??

什么是構(gòu)建者模式?

  • 構(gòu)建者模式是創(chuàng)建型設(shè)計(jì)模式(單利模式、工廠模式、構(gòu)建者模式、原型模式)之一。
  • 將一個(gè)復(fù)雜的對(duì)象的創(chuàng)建和表示進(jìn)行分離,同時(shí)你創(chuàng)建的順序不一樣,表示也不一樣。(表示:我們看到的外觀,也就是程序中UI顯示
    創(chuàng)建:制造的過程封裝,在使用的時(shí)候不需要使用者關(guān)心)
  • 使用場(chǎng)景? 1、相同的方法,調(diào)用的順序不一樣,產(chǎn)生的結(jié)果不一樣 2、多個(gè)部件都可以組裝到一個(gè)對(duì)象上,但是產(chǎn)生的結(jié)果不一樣 3、當(dāng)一個(gè)類非常復(fù)雜的時(shí)候,并且需要初始化默認(rèn)初始化參數(shù)(如:網(wǎng)絡(luò)請(qǐng)求)
下面看一個(gè)基礎(chǔ)原理程序案例(以電腦為例):??
//----------------------先來定義兩個(gè)抽象協(xié)議-------------------
//電腦的抽象協(xié)議
@protocol IComputer <NSObject>
//處理器
- (void)cpu:(NSString *)cpu;
//顯卡
- (void)display:(NSString *)display;
//主板
- (void)mainboard:(NSString *)mainboard;
//系統(tǒng)
- (void)os;
@end

//構(gòu)建者抽象協(xié)議
@protocol IComputerBuilder <NSObject>
//構(gòu)建CPU
- (id<IComputerBuilder>)buildCPU:(NSString *)cpu;
//構(gòu)建顯卡
- (id<IComputerBuilder>)buildDisplay:(NSString *)display;
//構(gòu)建主板
- (id<IComputerBuilder>)buildMainboard:(NSString *)mainboard;
//構(gòu)建系統(tǒng)
- (id<IComputerBuilder>)buildOS:(NSString *)os;
//構(gòu)建
- (id<IComputer>)build;
@end

//----------------構(gòu)建具體的類并實(shí)現(xiàn)協(xié)議------------------
@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);
}
//系統(tǒng)
- (void)os {
    NSLog(@"windows");
}
@end

//具體的構(gòu)建者實(shí)現(xiàn)構(gòu)建者抽象協(xié)議
@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;
}
//構(gòu)建CPU
- (id<IComputerBuilder>)buildCPU:(NSString *)cpu {
    [_computer cpu:cpu];
    return self;
}
//構(gòu)建顯卡
- (id<IComputerBuilder>)buildDisplay:(NSString *)display {
    [_computer display:display];
    return self;
}
//構(gòu)建主板
- (id<IComputerBuilder>)buildMainboard:(NSString *)mainboard {
    [_computer mainboard:mainboard];
    return self;
}
//構(gòu)建系統(tǒng)
- (id<IComputerBuilder>)buildOS:(NSString *)os {
    [_computer os];
    return self;
}
//構(gòu)建
- (id<IComputer>)build {
    NSLog(@"構(gòu)建了一臺(tái)Leveno??");
    //正式的項(xiàng)目中其實(shí)這里有很多的邏輯
    return _computer;
}

//----------在客戶端(ViewController)里面使用一下
id<IComputerBuilder> builder2 = [[LevenoComputerBuilder alloc] init];
    //鏈?zhǔn)骄幊?[[[[[builder2 buildCPU:@"inter i5"] buildDisplay:@"獨(dú)立顯卡2G"] buildMainboard:@"三星主板"] buildOS:@""] build];
理解了上邊的原理案例后 我們來看一個(gè)項(xiàng)目中實(shí)際運(yùn)用的例子(我們平常用的UIAlertViewController)使用構(gòu)建者模式來封裝一下,進(jìn)行項(xiàng)目的解耦和。如下??:
import UIKit
//使用Builder設(shè)計(jì)模式自定義一個(gè)alert SLAlertController不能再外部實(shí)例化對(duì)象,只能在內(nèi)部使用(否則沒有意義)
class SLAlertController: NSObject {
    //不允許外部進(jìn)行初始化
    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) {
        }
    }

    //參數(shù)和構(gòu)建的分離
    class BuilderParams: NSObject {
        //上下文,用AlertController
        var context:UIViewController?
        //alert 的提示標(biāo)題
        var title:String?
        //alert 的提示信息
        var message:String?
        //確定按鈕
        var confirmTitle:String?
        //取消按鈕
        var cancelTitle:String?
        //確定回調(diào)
        var confirmHandle:((UIAlertAction) -> Swift.Void)?
        //取消回調(diào)
        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
        }
        //最后構(gòu)建
        func build() -> SLAlertController {
            return SLAlertController(params: self.param!)
        }
    }
}

//============對(duì)構(gòu)建者的alert我們測(cè)試一下============
//構(gòu)建者設(shè)計(jì)的alert使用寫方法
let alert = SLAlertController.Builder(context: self)
 alert.setTitle("提示").setMessage("你確定要?jiǎng)h除這張圖片嗎?").setCancelTitle("取消").setCancelHandle { (UIAlertAction) in
       print("取消")
 }.setConfirmTitle("確定").setConfirmHandle { (UIAlertAction) in
       print("確定")
}.build().showAlert()

  • 這樣來寫的話,避免了在一個(gè)程序中多次使用 UIAlertController后,如果需求改了,你需要去程序中一個(gè)一個(gè)的改,改的你到時(shí)候懷疑人生(改的想死)。
如有錯(cuò)誤的地方,留言區(qū) -> 請(qǐng)多多指教!???? ??
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,725評(píng)論 25 709
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,073評(píng)論 1 15
  • 突然想起來我的初中時(shí)代,那時(shí)的我們天真無邪,兩小無猜。雖然不怎么富裕,但是我覺得一切都是那么的好。有一起的兄弟...
    msl十年閱讀 265評(píng)論 0 2
  • 很著急,反而更拖延。這就是我現(xiàn)在的狀態(tài)。感覺事情很多但是工作卻沒有著手開始,越堆越多感覺總是干不完呢。 最近看到了...
    我叫李徐杰閱讀 255評(píng)論 0 0
  • 第01章:妖刀 凌晨一點(diǎn),東街城隍廟,都帶家伙。 這是我接到的信息,發(fā)件人是虎哥。 收到信息的時(shí)候,我正躺在床上睡...
    蘭十三閱讀 469評(píng)論 1 1

友情鏈接更多精彩內(nèi)容