可能被忽略掉編程技巧 之 鏈式編程

可能被忽略掉編程技巧 之 鏈式編程


@author Jou Email Weibo or Github


可能被忽略掉編程技巧 之 鏈式編程

預熱 - 鏈式編程

哎呦叉抡,不錯哦。有點時間袁稽, 隨便寫篇文章,聊聊iOS中的鏈式編程溅呢。
鏈式編程披蕉? 如果你不是iOS開發(fā)者,相信你應該沒聽過鏈式編程伞访。對的掂骏, 鏈式編程,并不是一種編程范式厚掷。鏈式編程這種表述弟灼, 應該是在Objective-C獨有,因為Objective-C是一門繁瑣而奇怪的語言冒黑。
在Swift之前田绑,想成為iOS開發(fā)者,在入門前你就有了兩個門檻: 1. 你要有臺蘋果抡爹, 2. 你要肯于接受Objective-C的反人類掩驱,和繁瑣。
所以形式上冬竟,鏈式編程是"點方法"的調用欧穴,來彌補Objc的繁瑣。

Objective-C


NSString objc = @"Hello world";
[objc lowercaseString]; // 給objc 發(fā)送lowercaseString的消息

而相比之下swift 就更為簡潔

let str = "Hello, playground"
str.lowercaseString;

鏈式編程 - 點式調用 LinkBlock

為了實現(xiàn)Objc中的點式調用泵殴, Novo已經(jīng)有了一個基于block的好玩的實現(xiàn)LinkBlock涮帘。
LinkBlock 旨在幫助我們實現(xiàn)點方法調用的happy path。
如:


UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame= CGRectMake(20, 20, 150, 80);
UIColor *color = [UIColor colorWithRed:255/255.0 green:22/255.0 blue:150/255.0 alpha:1.0];
btn.backgroundColor = color;
[btn setTitle:@"click change color" forState:UIControlStateNormal];
[self.view addSubview:btn];


//如果使用鏈式編程的方式笑诅,大部分工作可以在思路連續(xù)的情況下進行
//now just using one line.Most work can be wrapped up in the idea of ??ongoing cases
btn.viewSetFrame(20,20,150,80).viewBGColor(@"0xff22cc".strToColorFromHexStr())
.viewAddToView(self.view).btnTitle(@"click change color", UIControlStateNormal);

是不是簡潔了許多调缨。

鏈式編程 - Masonry

自從iOS設備尺寸多樣化以后疮鲫,為了適配大小屏,我們用到了autolayout弦叶。
即便是我們使用了VFL俊犯,官方的autolayout寫法,在代碼實現(xiàn)上也過于繁瑣湾蔓。
所以很大程度上, 一部分人轉而重用storyboard界面布局砌梆,一部分轉而重度依賴mansory默责, 還有大多數(shù)在結合使用。
而Masonry的實現(xiàn)上咸包, 恰恰就是圍繞Maker對象的鏈式編程桃序。

之前autolayout的代碼是這樣的


UIView *superview = self;

UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
view1.backgroundColor = [UIColor greenColor];
[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[superview addConstraints:@[

    //view1 constraints
    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeTop
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeTop
                                multiplier:1.0
                                  constant:padding.top],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeLeft
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeLeft
                                multiplier:1.0
                                  constant:padding.left],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeBottom
                                multiplier:1.0
                                  constant:-padding.bottom],

    [NSLayoutConstraint constraintWithItem:view1
                                 attribute:NSLayoutAttributeRight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:superview
                                 attribute:NSLayoutAttributeRight
                                multiplier:1
                                  constant:-padding.right],

 ]];

Masonry實現(xiàn)、

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
    make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

顯而易見的烂瘫、真是簡潔到?jīng)]朋友媒熊。

ps: Masonry 在github上 已有1W+的star。


除了形式上的鏈式調用坟比, Objc中所談的鏈式調用芦鳍, 更是函數(shù)編程中一種常用的編程手段。

函數(shù)式編程 - Function Chaining

在swift中引入了函數(shù)式編程之后葛账,把函數(shù)編程推到了新的高度柠衅。
而在swift中, 偶爾會見到這樣的代碼籍琳。


let result = students |> filterOutFailed |> sortByGrade |> formatForPrint |> joinByComma


把 ‘|>’ 換成 ’.' 菲宴,便有了極大的相似并不是偶然, 鏈式編程趋急,只是函數(shù)編程思想的一種結合喝峦。

百分百的知識 - 實踐 鏈式編程

如果團隊有人在項目中,沒有討論的貿(mào)然加入了LinkBlock框架呜达, 我肯定還是會argue一下的谣蠢。
因過于依賴于LinkBlock,在代碼可讀性上增加了難度查近,并且增加了不可預期的崩潰漩怎。
LinkBlock中不能很好的處理,給nil進行鏈式調用嗦嗡,造成崩潰勋锤。

所以我認為,鏈式編程更好的實踐侥祭,應該是應用在復用性較好的組件中, 最好還可以像masonry一樣叁执,使用block包裹起來茄厘。

如, 語句塊在objc的使用方式之一:

self.tableView.tableFooterView = ({
  UIView *view = [[UIView alloc]initWithFrame:CGRectZero];
  view;
});

這不是純秀技巧, 在代碼可讀性上谈宛, 他的模塊次哈, 和邏輯更加清晰。

所以我最近在考慮吆录,將鏈式編程的思想加入我自己的 開源項目Router窑滞, 或 Dispatcher 中。 而形式上恢筝,則更類似Masonry的maker哀卫。

場景是 : 假如,我買了一架灰機撬槽, 我要駕駛它此改。

使用Block的特性,Trick實現(xiàn)鏈式調用

那么侄柔,我的飛機共啃,一定可以起飛,降落暂题, 上下左右移剪,依照block的特性。我可以這么實現(xiàn)它


- (MAFlight *(^)(CGFloat distence))takeOff
{
  return ^MAFlight *(CGFloat distence)
  {
    //Do move distence
    return self;
  };
}

- (MAFlight *(^)(CGFloat distence))landDown
{
  return ^MAFlight *(CGFloat distence)
  {
    //Do move distence
    return self;
  };
}

- (MAFlight *(^)(CGFloat distence))forward
{
  return ^MAFlight *(CGFloat distence)
  {
    //Do move distence
    return self;
  };
}

- (MAFlight *(^)(CGFloat distence))back
{
  return ^MAFlight *(CGFloat distence)
  {
    //Do move distence
    return self;
  };
}

- (MAFlight *(^)(CGFloat distence))left
{
  return ^MAFlight *(CGFloat distence)
  {
    //Do move distence
    return self;
  };
}

- (MAFlight *(^)(CGFloat distence))right
{
  return ^MAFlight *(CGFloat distence)
  {
    //Do move distence
    return self;
  };
}

所以我們就可以這么調用


MAFlight *flight = [[MAFlight alloc]init];//我買了飛機
flight.takeOff(10.f).forward(100000.f).left(10.f).right(1.f).back(1.f).back(1.f).landDown(10.f);

好了那么我們已經(jīng)實現(xiàn)了鏈式調用薪者,但挂滓,還沒滿足于此,因為邏輯還沒有更加清晰啸胧。 為了叫買飛機的流程赶站,和開飛機的流程更加清晰。實現(xiàn)了maker纺念、

實現(xiàn)Maker

為了叫買飛機贝椿,我給NSObject實現(xiàn)了分類+Extra.h


+ (CGFloat)makeFlight:(void (^)(MAFlight *))block {

  //購買飛機
  MAFlight *maker = [[MAFlight alloc]init];
  //操作飛機
  block(maker);

  return maker.distence;
}

再為飛機加一點語法糖

- (MAFlight *)and
{
  return self;
}

所以, 就可以這么玩飛機了

[objc makeFlight:^(MAFlight *flight){
  flight.takeOff(10.f).and.forward(100000.f);
  flight.left(10.f).and.right(1.f);
  flight.back(1.f).and.back(1.f).landDown(10.f)
  }];

OK, That's all.

下一篇 - iOS Nightmare系列之 - 客戶端應用的Daily Build 與 持續(xù)化集成(Continuous Integration)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末陷谱,一起剝皮案震驚了整個濱河市烙博,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌烟逊,老刑警劉巖渣窜,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宪躯,居然都是意外死亡乔宿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門访雪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來详瑞,“玉大人掂林,你說我怎么就攤上這事“酉穑” “怎么了泻帮?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長计寇。 經(jīng)常有香客問我锣杂,道長,這世上最難降的妖魔是什么番宁? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任元莫,我火速辦了婚禮,結果婚禮上贝淤,老公的妹妹穿的比我還像新娘柒竞。我一直安慰自己政供,他們只是感情好播聪,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著布隔,像睡著了一般离陶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衅檀,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天招刨,我揣著相機與錄音,去河邊找鬼哀军。 笑死沉眶,一個胖子當著我的面吹牛,可吹牛的內容都是我干的杉适。 我是一名探鬼主播谎倔,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼猿推!你這毒婦竟也來了片习?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤蹬叭,失蹤者是張志新(化名)和其女友劉穎藕咏,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秽五,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡孽查,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了坦喘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卦碾。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡铺坞,死狀恐怖,靈堂內的尸體忽然破棺而出洲胖,到底是詐尸還是另有隱情济榨,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布绿映,位于F島的核電站擒滑,受9級特大地震影響,放射性物質發(fā)生泄漏叉弦。R本人自食惡果不足惜丐一,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淹冰。 院中可真熱鬧库车,春花似錦、人聲如沸樱拴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晶乔。三九已至珍坊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間正罢,已是汗流浹背阵漏。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留翻具,地道東北人履怯。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像裆泳,于是被迫代替她去往敵國和親叹洲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫晾虑、插件疹味、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,066評論 4 62
  • 有很多想法 ,腦子里也有許多構思 帜篇。為什么不能寫下來糙捺?書荒,可以寫自己的小說笙隙。從現(xiàn)在開始
    文白__閱讀 202評論 0 0
  • 文|雜家大兵 我不知道大家是否和我一樣是一個瘋狂收集信息的人掏呼,當想要了解一個領域或者一個行業(yè)的時候,通常會利用互聯(lián)...
    雜家大兵閱讀 962評論 0 3
  • 山下有蕓蕓眾生铅檩,萬千燈火山上有飄渺仙人憎夷,遺世獨立2013-5-1 想象你站在山腳的一個小山坡上,正好可以被風吹到昧旨,...
    酒笑生閱讀 149評論 0 1