亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

實例講解iOS應用的設計模式開發中的Visitor訪問者模式

2020-07-26 03:25:20
字體:
來源:轉載
供稿:網友

為了方便向大家展示,先給出簡短的定義:

訪問者模式(Visitor),表示一個作用于某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。

緊接著,給出其類結構圖。

201632293447218.jpg (500×385)
訪問者模式適用于數據結構相對穩定的系統,它把數據結構和作用于結構上的操作之間的耦合解脫開,使得操作結合可以相對自由地演化。

訪問者模式的目的是要把處理從數據結構分離出來。很多系統可以按照算法和數據結構分開,如果這樣的系統有比較穩定的數據結構,又有易于變化的算法的話,使用訪問者模式就是比較合適的,因為訪問者模式使得算法操作的增加變得容易。

訪問者模式的優點就是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。訪問者模式將有關的行為集中到一個訪問者對象中。

那其實,訪問者模式的缺點也就是使增加新的數據結構變得苦難了。所以,GoF四人中的一個作者增經說過,‘大多時候你并不需要訪問者模式,但當一旦你需要訪問者模式的時候,那就是真的需要它了'。

那么下面還是老慣例,給大家展示一下簡單的實現。
一個簡單的Car模型,含有1臺Engine、4個Wheel,使用訪問者模式添加對Car的升級與維修操作。

定義Engine類:

復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoComponentVisitor.h"
 
@interface NimoEngine : NSObject
 
@property (nonatomic, copy) NSString *modelName;
- (id)initWithModelName:(NSString *)modelName;
 
@end

復制代碼 代碼如下:

#import "NimoEngine.h"
 
@implementation NimoEngine
 
- (id)initWithModelName:(NSString *)modelName
{
    self = [super init];
    if (self) {
        _modelName = [modelName copy];
    }
    return self;
}
 
- (id) init
{
    return [self initWithModelName:@"Slant 6"];
}
 
- (NSString *)description
{
    return [NSString stringWithFormat:@"Engine: %@", _modelName];
}
 
@end

定義Wheel類:
復制代碼 代碼如下:

#import <Foundation/Foundation.h>
 
@interface NimoWheel : NSObject
 
@property (nonatomic, assign) float diameter; //車輪直徑
 
@end

復制代碼 代碼如下:

#import "NimoWheel.h"
 
@implementation NimoWheel
 
- (id)init
{
    self = [super init];
    if (self) {
        _diameter = 400.0f;
    }
    return self;
}
 
-(NSString *)description
{
    return [NSString stringWithFormat:@"Wheel: %f mm", _diameter];
}
 
@end

定義Car類:
復制代碼 代碼如下:

#import <Foundation/Foundation.h>
 
@class NimoEngine, NimoWheel;
 
@interface NimoCar : NSObject
 
@property (nonatomic) NimoEngine *engine;
@property (nonatomic, readonly) NSArray *arrayOfWheels;
 
- (void)addWheel:(NimoWheel *)wheel atIndex:(NSUInteger) index;
 
@end

復制代碼 代碼如下:

@interface NimoCar()
 
@property (nonatomic, readwrite) NSMutableArray *mutableArrayOfWheels;
 
@end

復制代碼 代碼如下:

@implementation NimoCar
 
- (id)init
{
    if (self = [super init]) {
        _mutableArrayOfWheels = [[NSMutableArray alloc] initWithCapacity:4];
    }
    
    return self;
}
 
- (void)addWheel:(NimoWheel *)wheel atIndex:(NSUInteger) index
{
    [_mutableArrayOfWheels insertObject:wheel atIndex:index];
}
 
- (NSArray *)arrayOfWheels
{
    return [_mutableArrayOfWheels copy];
}
 
- (NSString *)description
{
    return [NSString stringWithFormat:@"My car: %@", [NSDictionary dictionaryWithObjects:@[_engine, self.arrayOfWheels] forKeys:@[@"Engine", @"Wheels"]]];
}
 
@end

我們的汽車結構很簡單,只包含1個引擎,4個車輪,并且各個類也沒有復雜的實現,僅僅覆寫了description,讓其輸出簡要的信息。

好,實例化一輛Car, 看看效果:

復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoCar.h"
#import "NimoEngine.h"
#import "NimoWheel.h"
 
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NimoCar *car = [[NimoCar alloc] init];
        NimoEngine *engine = [[NimoEngine alloc] initWithBrandName:@"V8"];
        NimoWheel *wheelA = [[NimoWheel alloc] init];
        NimoWheel *wheelB = [[NimoWheel alloc] init];
        NimoWheel *wheelC = [[NimoWheel alloc] init];
        NimoWheel *wheelD = [[NimoWheel alloc] init];
        
        car.engine = engine;
        [car addWheel:wheelA atIndex:0];
        [car addWheel:wheelB atIndex:1];
        [car addWheel:wheelC atIndex:2];
        [car addWheel:wheelD atIndex:3];
        
        NSLog(@"%@", car);
        
    }
    return 0;
}

201632293536226.png (768×152)

控制臺跟意料中一樣輸出了Car的信息。至此,準備工作做好了。

訪問者模式:表示一個作用于某對象結構中的各元素的操作。它讓我們可以在不改變各元素的類的前提下定義作用于這些元素的新操作。---《設計模式》(Addison-Wesley, 1994)

這段話比較拗口,不太好理解。拿剛剛完成的Car類來舉例,NimoCar類就是對象結構,其中包含的元素為:NimoEngine類和NimoWheel類。如果現在需要對Car進行全面升級(新操作),通常的做法是NimoEngine與NimoWheel都向外提供“升級”的接口。如果還需要對Car進行維修呢?那又得向外提供“維修”的接口。隨著類似的需求越多,NimoEngine與NimoWheel向外提供的接口就越多,類也變得越復雜。有沒有簡單的方法呢?有!把這些瑣事都交給訪問者來做吧,NimoEngine與NimoWheel只要同意被訪問就成。

定義訪問者協議:

復制代碼 代碼如下:

@class NimoEngine, NimoWheel;
 
@protocol NimoComponentVisitor <NSObject>
 
- (void) visitEngine:(NimoEngine *) engine;
- (void) visitWheel:(NimoWheel *) wheel;
 
@end

修改我們的類,使其能夠接受訪問

添加訪問支持的Engine類:

復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoComponentVisitor.h"
 
@interface NimoEngine : NSObject
 
@property (nonatomic, copy) NSString *modelName;
 
- (id)initWithModelName:(NSString *)modelName;
 
- (void)acceptComponentVisitor:(id<NimoComponentVisitor>) visitor;
 
@end

復制代碼 代碼如下:

#import "NimoEngine.h"
 
@implementation NimoEngine
 
- (id)initWithModelName:(NSString *)modelName
{
    self = [super init];
    if (self) {
        _modelName = [modelName copy];
    }
    return self;
}
 
- (id) init
{
    return [self initWithModelName:@"Slant 6"];
}
 
- (void)acceptComponentVisitor:(id<NimoComponentVisitor>) visitor
{
    [visitor visitEngine:self];
}
 
- (NSString *)description
{
    return [NSString stringWithFormat:@"Engine: %@", _modelName];
}
 
@end

添加訪問支持的Wheel類:
復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoComponentVisitor.h"
 
@interface NimoWheel : NSObject
 
@property (nonatomic, assign) float diameter; //直徑
 
- (void)acceptComponentVisitor:(id<NimoComponentVisitor>) visitor;
 
@end

復制代碼 代碼如下:

#import "NimoWheel.h"
 
@implementation NimoWheel
 
- (id)init
{
    self = [super init];
    if (self) {
        _diameter = 400.0f;
    }
    return self;
}
 
- (void)acceptComponentVisitor:(id<NimoComponentVisitor>) visitor
{
    [visitor visitWheel:self];
}
 
-(NSString *)description
{
    return [NSString stringWithFormat:@"Wheel: %f mm", _diameter];
}
 
@end

添加訪問支持的Car類
復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoComponentVisitor.h"
 
@class NimoEngine, NimoWheel;
 
@interface NimoCar : NSObject
 
@property (nonatomic) NimoEngine *engine;
@property (nonatomic, readonly) NSArray *arrayOfWheels;
 
- (void)addWheel:(NimoWheel *)wheel atIndex:(NSUInteger) index;
 
- (void)acceptComponentVisitor:(id<NimoComponentVisitor>) visitor;
@end

復制代碼 代碼如下:

#import "NimoCar.h"
#import "NimoEngine.h"
#import "NimoWheel.h"
 
@interface NimoCar()
 
@property (nonatomic, readwrite) NSMutableArray *mutableArrayOfWheels;
 
@end

復制代碼 代碼如下:

@implementation NimoCar
 
- (id)init
{
    if (self = [super init]) {
        _mutableArrayOfWheels = [[NSMutableArray alloc] initWithCapacity:4];
    }
    
    return self;
}
 
- (void)addWheel:(NimoWheel *)wheel atIndex:(NSUInteger) index
{
    [_mutableArrayOfWheels insertObject:wheel atIndex:index];
}
 
- (NSArray *)arrayOfWheels
{
    return [_mutableArrayOfWheels copy];
}
 
- (void)acceptComponentVisitor:(id<NimoComponentVisitor>) visitor
{
    [_engine acceptComponentVisitor:visitor];
    for (NimoWheel *wheel in self.arrayOfWheels) {
        [wheel acceptComponentVisitor:visitor];
    }
}
 
- (NSString *)description
{
    return [NSString stringWithFormat:@"My car: %@", [NSDictionary dictionaryWithObjects:@[_engine, self.arrayOfWheels] forKeys:@[@"Engine", @"Wheels"]]];
}
 
@end

我們在類中添加了-(void)acceptComponentVisitor:(id<NimoComponentVisitor>)visitor接口,同意實現了訪問者協議的visitor訪問。(我家大門常打開,啦啦啦啦啦)

讓我們來看下第一位訪問者是誰?剛剛上面我們有提到一個需求,想對汽車各組件進行全面升級。那么就讓這位專業的訪問者來做吧!

定義具體訪問者:此訪問者具備升級汽車各組件的能力

復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoComponentVisitor.h"
 
@interface NimoComponentUpgrade : NSObject <NimoComponentVisitor>
 
- (void) visitEngine:(NimoEngine *) engine;
- (void) visitWheel:(NimoWheel *) wheel;
 
@end

復制代碼 代碼如下:

#import "NimoComponentUpgrade.h"
 
@implementation NimoComponentUpgrade
 
- (void) visitEngine:(NimoEngine *) engine
{
    NSLog(@"我是升級人員,正在對引擎<%@>進行升級", engine);
}
 
- (void) visitWheel:(NimoWheel *) wheel
{
    NSLog(@"我是升級人員,正在對車輪<%@>進行升級", wheel);
}
 
@end

讓我們來看看這位訪問者的工作能力如何
復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoCar.h"
#import "NimoEngine.h"
#import "NimoWheel.h"
#import "NimoComponentMaintenance.h"
#import "NimoComponentUpgrade.h"
 
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        NimoCar *car = [[NimoCar alloc] init];
        NimoEngine *engine = [[NimoEngine alloc] initWithModelName:@"V8"];
        NimoWheel *wheelA = [[NimoWheel alloc] init];
        NimoWheel *wheelB = [[NimoWheel alloc] init];
        NimoWheel *wheelC = [[NimoWheel alloc] init];
        NimoWheel *wheelD = [[NimoWheel alloc] init];
        
        car.engine = engine;
        [car addWheel:wheelA atIndex:0];
        [car addWheel:wheelB atIndex:1];
        [car addWheel:wheelC atIndex:2];
        [car addWheel:wheelD atIndex:3];
        
        NSLog(@"%@", car);
        
        //對組建進行“升級”
        NimoComponentUpgrade *upgradeVisitor = [[NimoComponentUpgrade alloc] init];
        [car acceptComponentVisitor:upgradeVisitor];
    }
    return 0;
}

201632293606776.jpg (768×243)

看來這位訪問者的工作很出色。

如果我們還需要對汽車各組件進行維修呢?那就定義一個專職維修的訪問者

復制代碼 代碼如下:

#import <Foundation/Foundation.h>
#import "NimoComponentVisitor.h"
 
@interface NimoComponentMaintenance : NSObject <NimoComponentVisitor>
 
- (void) visitEngine:(NimoEngine *) engine;
- (void) visitWheel:(NimoWheel *) wheel;
 
@end

復制代碼 代碼如下:

#import "NimoComponentMaintenance.h"
 
@implementation NimoComponentMaintenance
 
- (void) visitEngine:(NimoEngine *) engine
{
    NSLog(@"我是維修人員,正在對引擎<%@>進行維修", engine);
}
 
- (void) visitWheel:(NimoWheel *) wheel
{
    NSLog(@"我是維修人員,正在對車輪<%@>進行維修", wheel);
}
 
@end

復制代碼 代碼如下:

//main.m
        ...
        //對組建進行“維修”
        NimoComponentMaintenance *maintenanceVisitor = [[NimoComponentMaintenance alloc] init];
        [car acceptComponentVisitor:maintenanceVisitor];
        ...
       

使用訪問者模式后,添加操作,只需實現具體的訪問者,不會對類的結構造成破壞。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品成人国产在线观看男人呻吟| 亚洲的天堂在线中文字幕| 97视频在线观看视频免费视频| 51午夜精品视频| 国产精品高清在线观看| 青青在线视频一区二区三区| 国产精品美女999| 国外成人在线视频| 伊人精品在线观看| 久久天堂电影网| 欧美午夜精品在线| 91大神福利视频在线| 中文字幕在线精品| 欧美孕妇与黑人孕交| 亚洲最大的成人网| 欧美日韩午夜视频在线观看| 国产精品免费看久久久香蕉| 国产精品久久久久免费a∨大胸| 宅男66日本亚洲欧美视频| 国产精品视频久久久久| 久久精品小视频| 国产亚洲精品激情久久| 国产精品免费福利| 国产乱人伦真实精品视频| 国产精品专区h在线观看| 精品久久久久久国产| 一本大道亚洲视频| 久久av在线播放| 日韩av免费看| 日韩久久免费电影| 国产精品久久久久久久久久新婚| 亚洲美女又黄又爽在线观看| 亚洲成人教育av| 国产精品影院在线观看| 国产成人精品免费久久久久| 欧美日韩国产丝袜美女| 日韩av一区在线观看| 在线成人免费网站| 成人久久18免费网站图片| 欧美在线免费观看| 亚洲精品在线91| 97热在线精品视频在线观看| 欧美激情欧美狂野欧美精品| 国产精品老牛影院在线观看| 欧美综合第一页| 青青精品视频播放| 亚洲自拍偷拍网址| 欧美大片免费观看在线观看网站推荐| 久热在线中文字幕色999舞| 欧美国产日本高清在线| 欧美性猛交xxxx乱大交极品| 国产精品∨欧美精品v日韩精品| 色偷偷88888欧美精品久久久| 国产自摸综合网| 2019中文字幕全在线观看| 欧美午夜宅男影院在线观看| 国产丝袜一区二区三区| 欧美激情国产日韩精品一区18| 欧美一区视频在线| 51视频国产精品一区二区| 色妞色视频一区二区三区四区| 国产精品久久久久久久美男| 国产精品99蜜臀久久不卡二区| 亚洲在线免费视频| 97视频免费在线观看| 久久亚洲综合国产精品99麻豆精品福利| 国产91色在线播放| www.欧美精品一二三区| 91精品视频一区| 欧美大片在线免费观看| 韩国v欧美v日本v亚洲| 另类色图亚洲色图| 国产在线精品成人一区二区三区| 一本久久综合亚洲鲁鲁| 日韩成人中文字幕在线观看| 97在线视频免费观看| 中文字幕九色91在线| 欧美激情精品久久久久久变态| 日韩欧美中文字幕在线播放| 欧美成人免费一级人片100| 欧美大全免费观看电视剧大泉洋| 国产va免费精品高清在线观看| 欧美日韩在线视频一区| 色偷偷噜噜噜亚洲男人的天堂| 日韩亚洲欧美成人| 久久久91精品国产| 色综合天天狠天天透天天伊人| 亚洲黄色av网站| 欧洲成人午夜免费大片| 久久久精品国产一区二区| 成人午夜黄色影院| 亚洲色图国产精品| 欧美成人h版在线观看| 欧美日韩国产成人高清视频| 欧美性资源免费| 日本高清视频精品| 国产一区二区三区欧美| 日韩国产欧美精品在线| 欧美日韩在线视频观看| 中文字幕久热精品在线视频| 亚洲最大的网站| 亚洲黄色片网站| 亚洲精品美女在线观看| 久久久久久久香蕉网| 久久这里只有精品99| 成人高h视频在线| 亚洲电影免费观看高清| 欧美高清videos高潮hd| 日韩一区二区欧美| 国产乱肥老妇国产一区二| 69精品小视频| 久久久精品美女| 亚洲视频精品在线| 国产精品av免费在线观看| 韩国三级电影久久久久久| 国产精品91免费在线| 国产精品一区二区性色av| 国产+人+亚洲| 久久精品电影网站| 性欧美激情精品| 精品国产一区二区三区四区在线观看| 中文字幕日韩精品在线观看| 日韩免费中文字幕| 亚洲女人初尝黑人巨大| 国产精品永久免费| 国产裸体写真av一区二区| 国产精品高清在线| 亚洲欧美视频在线| 亚洲精品日韩欧美| 国产91精品网站| 日本欧美精品在线| 81精品国产乱码久久久久久| 国产精品第8页| 国产午夜精品麻豆| 91天堂在线观看| 亚洲国产精品久久精品怡红院| 国产亚洲欧洲高清一区| 亚洲综合在线中文字幕| 亚洲激情中文字幕| 色午夜这里只有精品| 高清一区二区三区日本久| 91av在线影院| 亚洲一区中文字幕| 亚洲va欧美va国产综合久久| 九九视频直播综合网| 欧美亚洲另类在线| 色悠久久久久综合先锋影音下载| 精品国产91久久久| 欧美一级视频一区二区| 日本一区二区不卡| 亚洲精品国产精品久久清纯直播| 日韩美女免费线视频| 在线播放精品一区二区三区| 欧美黑人性生活视频| 精品一区电影国产| 亚洲综合中文字幕68页| 亚洲黄页网在线观看| 亚洲www在线| 国产精品高精视频免费| 最近2019中文字幕在线高清| 色综合伊人色综合网| 欧美精品九九久久| 日韩精品免费电影| 国产亚洲a∨片在线观看|