iOS設(shè)計(jì)模式五(訪問者,裝飾,責(zé)任鏈)

承接上文iOS設(shè)計(jì)模式四(組合,迭代器)
本文為行為擴(kuò)展--獲取源碼

目錄
1 訪問者模式
2 裝飾模式
3 責(zé)任鏈模式


1 訪問者模式

訪問者模式是擴(kuò)展組合結(jié)構(gòu)功能的一種方式.
我們可以使用各種不同用途的訪問者,以同樣的方式訪問這個(gè)組合結(jié)構(gòu),然后用訪問者來處理增加的邏輯

當(dāng)然,也可以用類的Extension來增加邏輯,但是一個(gè)訪問者可以給多個(gè)類都增加邏輯,而用Extension則需要很多個(gè)了

一個(gè)給車升級(jí)的例子:
首先要有車OSZCars.h:

#import <Foundation/Foundation.h>
#import "OSZEngine.h"
#import "OSZWheel.h"
#import "OSZVisitor.h"
@interface OSZCars : NSObject

@property (nonatomic, strong) OSZEngine *engine;
@property (nonatomic, strong) NSMutableArray *wheels;
- (void)addWheels:(OSZWheel *)wheel atIndex:(NSUInteger)index;
//該方法是在加入訪問者后添加的
- (void)acceptVisitor:(id<OSZVisitor>)visitor;
@end

值得注意的是- (void)acceptVisitor:(id<OSZVisitor>)visitor這個(gè)方法是在加入訪問者后添加的
我們先把所有的模型建立完成再建立訪問者來擴(kuò)展

OSZCars.m:

#import "OSZCars.h"
@implementation OSZCars
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.wheels = [NSMutableArray array];
    }
    return self;
}

-(void)addWheels:(OSZWheel *)wheel atIndex:(NSUInteger)index
{
    [self.wheels insertObject:wheel atIndex:index];
}

- (void)acceptVisitor:(id<OSZVisitor>)visitor
{
    [self.engine acceptVisitor:visitor];
    for (OSZWheel *wheel in self.wheels)
    {
        [wheel acceptVisitor:visitor];
    }
}
@end

車有個(gè)引擎OSZEngine.h:

#import <Foundation/Foundation.h>
#import "OSZVisitor.h"
@interface OSZEngine : NSObject
@property (nonatomic, copy) NSString *name;
//接收訪問者修改
- (void)acceptVisitor:(id<OSZVisitor>)visitor;
@end

OSZEngine.m:

#import "OSZEngine.h"
@implementation OSZEngine
- (void)acceptVisitor:(id<OSZVisitor>)visitor
{
    [visitor visitEngine:self];
}
@end

車還有四個(gè)輪子OSZWheel.h:

#import <Foundation/Foundation.h>
#import "OSZVisitor.h"
@interface OSZWheel : NSObject
@property (nonatomic, assign) CGFloat size;
@property (nonatomic, copy) NSString *name;
//接收訪問者修改
- (void)acceptVisitor:(id<OSZVisitor>)visitor;
@end

OSZWheel.m:

#import "OSZWheel.h"
@implementation OSZWheel
- (void)acceptVisitor:(id<OSZVisitor>) visitor
{
    [visitor visitWheel:self];
}
@end

訪問者協(xié)議OSZVisitor.h:

#import <Foundation/Foundation.h>
@class OSZEngine,OSZWheel;
@protocol OSZVisitor <NSObject>
- (void)visitEngine:(OSZEngine *)engine;
- (void)visitWheel:(OSZWheel *)wheel;
@end

接下來在我們要擴(kuò)展功能的時(shí)候,創(chuàng)建一個(gè)訪問者,實(shí)體類修理工
OSZRepairman.h:

#import <Foundation/Foundation.h>
#import "OSZVisitor.h"
@interface OSZRepairman : NSObject<OSZVisitor>
@property (nonatomic, copy) NSString *name;

-(void)visitEngine:(OSZEngine *)engine;
-(void)visitWheel:(OSZWheel *)wheel;

@end

OSZRepairman.m:

#import "OSZRepairman.h"
#import "OSZEngine.h"
#import "OSZWheel.h"
@implementation OSZRepairman

-(void)visitEngine:(OSZEngine *)engine
{
    NSLog(@"修理工正在對(duì)%@升級(jí)",engine.name);
}
-(void)visitWheel:(OSZWheel *)wheel
{
    NSLog(@"修理工正在對(duì)%@升級(jí)",wheel.name);
}
@end

接下來我們?cè)诳刂破髦袆?chuàng)建車的實(shí)例,訪問者對(duì)車的功能擴(kuò)展
OSZTenVC.m

#import "OSZTenVC.h"
#import "OSZCars.h"
#import "OSZEngine.h"
#import "OSZWheel.h"
#import "OSZRepairman.h"

@interface OSZTenVC ()
@end

@implementation OSZTenVC
- (void)viewDidLoad {
    [super viewDidLoad];
    OSZEngine *engine1 = [[OSZEngine alloc]init];
    engine1.name = @"引擎1號(hào)";
    
    OSZWheel *wheel1 = [[OSZWheel alloc]init];
    wheel1.name = @"輪胎1";
    OSZWheel *wheel2 = [[OSZWheel alloc]init];
    wheel2.name = @"輪胎2";
    OSZWheel *wheel3 = [[OSZWheel alloc]init];
    wheel3.name = @"輪胎3";
    OSZWheel *wheel4 = [[OSZWheel alloc]init];
    wheel4.name = @"輪胎4";
    
    OSZCars *car = [[OSZCars alloc]init];
    car.engine = engine1;
    [car addWheels:wheel1 atIndex:0];
    [car addWheels:wheel2 atIndex:1];
    [car addWheels:wheel3 atIndex:2];
    [car addWheels:wheel4 atIndex:3];
    
    NSLog(@"%@",car.engine.name);
    //引擎1號(hào)
    [car.wheels enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        OSZWheel *wheel = obj;
        NSLog(@"%@",wheel.name);
    }];
    //輪胎1
    //輪胎2
    //輪胎3
    //輪胎4
    
    //訪問者
    OSZRepairman *man = [[OSZRepairman alloc]init];
    [car acceptVisitor:man];
    //修理工正在對(duì)引擎1號(hào)升級(jí)
    //修理工正在對(duì)輪胎1升級(jí)
    //修理工正在對(duì)輪胎2升級(jí)
    //修理工正在對(duì)輪胎3升級(jí)
    //修理工正在對(duì)輪胎4升級(jí)
}
@end

可以看出,一旦對(duì)組合結(jié)構(gòu)實(shí)現(xiàn)了訪問者模式,通常就不需要再修改各組合結(jié)構(gòu)的接口,
其實(shí)也是相當(dāng)于把各個(gè)組合結(jié)構(gòu)要擴(kuò)展的邏輯集中在了訪問者中,在沒有復(fù)用的情況下,代碼的總量是一定的

擴(kuò)展:iOS設(shè)計(jì)模式---訪問者模式


2 裝飾模式

我們向?qū)ο筇砑訓(xùn)|西,在用的時(shí)候可以裝飾上,不用的時(shí)候不破壞其原有的邏輯,
添加的東西都可以隨時(shí)添加或者刪除
有兩種方式可以實(shí)現(xiàn)這個(gè)模式:子類和分類

處理圖片的例子:獲取源碼
該協(xié)議定義了一種圖片數(shù)據(jù)結(jié)構(gòu)OSZPhotoProtocol.h

#import <Foundation/Foundation.h>

@protocol OSZPhotoProtocol <NSObject>
//漂亮等級(jí)
@property (nonatomic, assign) int beauty;
//寬高
@property (nonatomic, assign) int width;
@property (nonatomic, assign) int height;
//展示屬性
- (void)show;

@end

裝飾器根類OSZPhoto.h

#import <Foundation/Foundation.h>
#import "OSZPhotoProtocol.h"
@interface OSZPhoto : NSObject<OSZPhotoProtocol>
//保存圖片
@property (nonatomic, strong) id<OSZPhotoProtocol> photo;
//處理圖片的方法
- (id)initWithPhoto:(id<OSZPhotoProtocol>)photos;
@end

OSZPhoto.m

#import "OSZPhoto.h"
@implementation OSZPhoto
@synthesize beauty,width,height;

- (id)initWithPhoto:(id<OSZPhotoProtocol>)photos
{
    if (self = [super init])
    {
        self.photo  = photos;
    }
    return self;
}

- (void)show
{
    NSLog(@"漂亮等級(jí)%d,寬%d,高%d",self.photo.beauty,self.photo.width,self.photo.height);
}
@end
2.1先通過子類來實(shí)現(xiàn):

OSZPhotoMeiYan.h是空的

#import "OSZPhoto.h"
@interface OSZPhotoMeiYan : OSZPhoto
@end

OSZPhotoMeiYan.m

#import "OSZPhotoMeiYan.h"

@implementation OSZPhotoMeiYan
- (id)initWithPhoto:(id<OSZPhotoProtocol>)photos
{
//    另一種實(shí)現(xiàn)方式,把自己當(dāng)做圖片處理,而不是持有一個(gè)圖片加工
//    self = photos;
//    self.beauty += 100;
//    return self;
    if (self = [super initWithPhoto:photos])
    {
        self.photo = photos;
    }
    return self;
}
- (void)show
{
    self.photo.beauty += 100;
    NSLog(@"漂亮等級(jí)%d,寬%d,高%d",self.photo.beauty,self.photo.width,self.photo.height);
}
@end

OSZPhotoEdit.h也是空的

#import "OSZPhoto.h"
@interface OSZPhotoEdit : OSZPhoto
@end

OSZPhotoEdit.m

#import "OSZPhotoEdit.h"
@implementation OSZPhotoEdit
- (id)initWithPhoto:(id<OSZPhotoProtocol>)photos
{
//    self = photos;
//    self.width += 100;
//    self.height += 100;
//    return self;
    if (self = [super initWithPhoto:photos])
    {
        self.photo = photos;
    }
    return self;
}

- (void)show
{
    self.photo.width += 100;
    self.photo.height += 100;
    NSLog(@"漂亮等級(jí)%d,寬%d,高%d",self.photo.beauty,self.photo.width,self.photo.height);
}
@end
2.2 通過分類來實(shí)現(xiàn)

OSZPhoto+MeiYan.h

#import "OSZPhoto.h"
@interface OSZPhoto (MeiYan)

- (instancetype)showWithMeiYan;

@end

OSZPhoto+MeiYan.m

#import "OSZPhoto+MeiYan.h"
@implementation OSZPhoto (MeiYan)
- (instancetype)showWithMeiYan
{
    self.beauty += 100;
    NSLog(@"漂亮等級(jí)%d,寬%d,高%d",self.beauty,self.width,self.height);
    return self;
}
@end

OSZPhoto+Edit.h

#import "OSZPhoto.h"
@interface OSZPhoto (Edit)

- (instancetype)showWithEdit;

@end

OSZPhoto+Edit.m

#import "OSZPhoto+Edit.h"
@implementation OSZPhoto (Edit)
- (instancetype)showWithEdit
{
    self.width += 100;
    self.height += 100;
    NSLog(@"漂亮等級(jí)%d,寬%d,高%d",self.beauty,self.width,self.height);
    return self;
}
@end

控制器OSZElevenVC.m

#import "OSZElevenVC.h"
#import "OSZPhoto.h"
#import "OSZPhotoMeiYan.h"
#import "OSZPhotoEdit.h"
#import "OSZPhoto+MeiYan.h"
#import "OSZPhoto+Edit.h"

@interface OSZElevenVC ()
@end

@implementation OSZElevenVC
- (void)viewDidLoad
 {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor];
    
    //正常使用
    OSZPhoto *p1 = [[OSZPhoto alloc]init];
    p1.beauty = 100;
    p1.width = 100;
    p1.height = 100;
    p1.photo = p1;
    [p1 show];              //漂亮等級(jí)100,寬100,高100
    
    //1.通過真正的子類實(shí)現(xiàn)裝飾模式
    //裝飾1 美顏
    OSZPhotoMeiYan *p2 = [[OSZPhotoMeiYan alloc]initWithPhoto:p1];
    [p2 show];              //漂亮等級(jí)200,寬100,高100
    //裝飾2 修改大小
    OSZPhotoEdit *p3 = [[OSZPhotoEdit alloc]initWithPhoto:p2.photo];
    [p3 show];              //漂亮等級(jí)200,寬200,高200
    
    //2.通過分類實(shí)現(xiàn)裝飾模式
    //裝飾1 美顏
    OSZPhoto *p4 = [p1 showWithMeiYan];    //漂亮等級(jí)300,寬200,高200
    //裝飾2 修改大小
    OSZPhoto *p5 = [p4 showWithEdit];      //漂亮等級(jí)300,寬300,高300
}
@end

可以看出子類與分類的使用區(qū)別:
在子類中,圖片是一個(gè)抽象類型,被子類持有加工,比較結(jié)構(gòu)化,是原始風(fēng)格
在分類中,圖片是本身直接被加工,比較簡(jiǎn)單輕便,適用于少量裝飾
當(dāng)然,二者都可以實(shí)現(xiàn)另一種方式,這個(gè)例子僅僅是一個(gè)簡(jiǎn)單的演示,可能并不能看出來優(yōu)點(diǎn)與好處,也可能并不貼切,僅僅是我個(gè)人的理解吧
具體如何在項(xiàng)目中使用,可能已經(jīng)在不知不覺中就使用了,比如分類,延展,等等方式

擴(kuò)展:iOS 設(shè)計(jì)模式之裝飾模式(Decorator)


一個(gè)很有意思的報(bào)錯(cuò):


在非init或init開頭方法中使用[super init]

錯(cuò)誤信息如下:
error:Cannot assign to 'self' outside of a method in the init family
原因:
只能在init方法中給self賦值碉渡,Xcode判斷是否為init方法規(guī)則:方法返回id,并且名字以init+大寫字母開頭+其他為準(zhǔn)則


3 責(zé)任鏈模式

這種模式允許我們對(duì)整體結(jié)構(gòu)功能的升級(jí)或者擴(kuò)展,而不必修改已有單元的功能,只要添加鏈就行了
看起來跟裝飾模式有點(diǎn)像,但實(shí)現(xiàn)不同的目的,實(shí)現(xiàn)方式也不同

主要方式為:
當(dāng)前對(duì)象持有同父類下另一對(duì)象,另一對(duì)象可以繼續(xù)持有其他對(duì)象,每個(gè)對(duì)象都重載相同的方法,當(dāng)前對(duì)象處理不了,就返回給父類,父類再傳給另一子類對(duì)象處理

模仿盾牌防御攻擊的例子:獲取源碼
首先創(chuàng)建一個(gè)攻擊父類OSZAttack方便使用,再創(chuàng)建幾個(gè)子攻擊類
火攻擊:OSZFireAttack 冰攻擊:OSZIceAttack 電攻擊:OSZLightingAttack
這幾個(gè)類都是空的,僅僅使用個(gè)類名,就不做繁瑣的邏輯了

再創(chuàng)建一個(gè)防御父類
OSZAttackHandler.h

#import <Foundation/Foundation.h>
#import "OSZAttack.h"
@interface OSZAttackHandler : NSObject

//攻擊處理者
@property (nonatomic, strong) OSZAttackHandler *nextAttackHandler;
//傳遞攻擊
- (void)transmitAttack:(OSZAttack *)attack;
@end

OSZAttackHandler.m

#import "OSZAttackHandler.h"
@implementation OSZAttackHandler

- (void)transmitAttack:(OSZAttack *)attack
{
    [self.nextAttackHandler transmitAttack:attack];
}
@end

火攻擊防御者OSZFireHandler.h

#import "OSZAttackHandler.h"
@interface OSZFireHandler : OSZAttackHandler
//在子類的頭文件中再次聲明重寫的方法不是必需的,但是這樣做更加清楚
@end

OSZFireHandler.m

#import "OSZFireHandler.h"
#import "OSZFireAttack.h"
@implementation OSZFireHandler

- (void)transmitAttack:(OSZAttack *)attack
{
    //如果是火攻擊就攔截下來
    if ([attack isKindOfClass:[OSZFireAttack class]])
    {
        NSLog(@"我攔截住了火攻擊");
    }
    //如果不是就返回給父類,再去給別的人處理
    else
    {
        NSLog(@"我擋不住這個(gè)攻擊");
        [super transmitAttack:attack];
    }
}
@end

為了簡(jiǎn)化代碼,冰防御者OSZIceHandler.h同樣沒有重寫聲明,什么也沒有

OSZIceHandler.m

#import "OSZIceHandler.h"
#import "OSZIceAttack.h"
@implementation OSZIceHandler

- (void)transmitAttack:(OSZAttack *)attack
{
    //如果是冰攻擊就攔截下來
    if ([attack isKindOfClass:[OSZIceAttack class]])
    {
        NSLog(@"我攔截住了冰攻擊");
    }
    //如果不是就返回給父類,再去給別的人處理
    else
    {
        NSLog(@"我擋不住這個(gè)攻擊");
        [super transmitAttack:attack];
    }
}
@end

最后一個(gè)子類,作為化身,不做防御,處理最后的結(jié)果
OSZAvatar.h中什么也沒有

OSZAvatar.m

#import "OSZAvatar.h"
@implementation OSZAvatar

- (void)transmitAttack:(OSZAttack *)attack
{
    NSLog(@"我被打到了????");
}
@end

控制器OSZTwelveVC

#import "OSZTwelveVC.h"
#import "OSZFireAttack.h"
#import "OSZIceAttack.h"
#import "OSZLightingAttack.h"
#import "OSZFireHandler.h"
#import "OSZIceHandler.h"
#import "OSZAvatar.h"

@interface OSZTwelveVC ()
@end

@implementation OSZTwelveVC

- (void)viewDidLoad {
    [super viewDidLoad];  
    //創(chuàng)建一個(gè)人物,分配責(zé)任鏈
    OSZAvatar *handler1 = [[OSZAvatar alloc]init];
    //加火防御
    OSZFireHandler *handler2 = [[OSZFireHandler alloc]init];
    handler2.nextAttackHandler = handler1;
    //加冰防御
    OSZIceHandler *handler3 = [[OSZIceHandler alloc]init];
    handler3.nextAttackHandler = handler2;
    
    //開始攻擊測(cè)試,選擇最后一個(gè)責(zé)任鏈人物 先走冰防御,再走火防御
    //先用火
    OSZFireAttack *fire = [[OSZFireAttack alloc]init];
    [handler3 transmitAttack:fire];
    //我擋不住這個(gè)攻擊
    //我攔截住了火攻擊
    
    //再用冰
    OSZIceAttack *ice = [[OSZIceAttack alloc]init];
    [handler3 transmitAttack:ice];
    //我攔截住了冰攻擊
    
    //再用電
    OSZLightingAttack *lighting = [[OSZLightingAttack alloc]init];
    [handler3 transmitAttack:lighting];
    //我擋不住這個(gè)攻擊
    //我擋不住這個(gè)攻擊
    //我被打到了????
}
@end

實(shí)際上我們完全可以把所有的邏輯都塞在一個(gè)類中達(dá)到目的,但如果邏輯很龐大的話,就會(huì)很亂,
而這三種模式,都是在擴(kuò)展類邏輯的同時(shí),進(jìn)行最少的修改甚至不修改

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谣殊,一起剝皮案震驚了整個(gè)濱河市犀忱,隨后出現(xiàn)的幾起案子盈匾,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件九串,死亡現(xiàn)場(chǎng)離奇詭異踢步,居然都是意外死亡癣亚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門获印,熙熙樓的掌柜王于貴愁眉苦臉地迎上來述雾,“玉大人,你說我怎么就攤上這事蓬豁〈卵剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵地粪,是天一觀的道長(zhǎng)取募。 經(jīng)常有香客問我,道長(zhǎng)蟆技,這世上最難降的妖魔是什么玩敏? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮质礼,結(jié)果婚禮上师脂,老公的妹妹穿的比我還像新娘。我一直安慰自己踩晶,他們只是感情好蛛淋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著造挽,像睡著了一般碱璃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饭入,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天嵌器,我揣著相機(jī)與錄音,去河邊找鬼谐丢。 笑死爽航,一個(gè)胖子當(dāng)著我的面吹牛蚓让,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讥珍,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼历极,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了串述?” 一聲冷哼從身側(cè)響起执解,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纲酗,沒想到半個(gè)月后衰腌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡觅赊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年右蕊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吮螺。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饶囚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鸠补,到底是詐尸還是另有隱情萝风,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布紫岩,位于F島的核電站规惰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泉蝌。R本人自食惡果不足惜歇万,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勋陪。 院中可真熱鬧贪磺,春花似錦、人聲如沸诅愚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽违孝。三九已至刹前,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間等浊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工摹蘑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留筹燕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撒踪,于是被迫代替她去往敵國(guó)和親过咬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP)制妄,是說軟件實(shí)體(類掸绞、模塊、函數(shù)等等)應(yīng)該可以拓展耕捞,但是不可修改衔掸。開-閉原...
    西山薄涼閱讀 3,798評(píng)論 3 14
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用俺抽、多...
    MinoyJet閱讀 3,948評(píng)論 1 15
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,181評(píng)論 25 707
  • 我叫 簡(jiǎn)凝敞映,聽起來……這個(gè)名字很瓊瑤,在不少小說里都出現(xiàn)過磷斧。 但是振愿,我真的是人海中最不起眼的一部分。 但青春 初中...
    桃夭乀閱讀 258評(píng)論 1 0
  • 寫篇網(wǎng)貸測(cè)評(píng),今天的主角就是可圈可點(diǎn)侣颂、妖風(fēng)陣陣的暴風(fēng)金融档桃,且看它有何妖氣。 平臺(tái)背景是第一妖横蜒。讓我們扒一扒妖風(fēng)金融...
    玲瓏財(cái)?shù)?/span>閱讀 297評(píng)論 0 1