Developer/Pattern

[Object-c]DecoratorPattern - 데코레이터 패턴

블로blow 2016. 4. 20. 15:25
728x90

데코레이터 패턴


- 테코레이터 패턴은 객체의 추가적인 요건을 동적으로 추가할 수 있습니다.

- 데코레이터는 서브 클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있습니다.

- 한 객체를 여러 개의 데코레이터로 감쌀 수 있습니다.

- 기존 코드를 수정하지 않고도 행동을 확장할 수 있습니다.


요약하면 기존의 코드를 수정하지 않고 객체를 여러개의 데코레이터로 감사서 유연하게 확장해 추가적인 동작을 수행할 수 있습니다.



코드 설명


여행을 계획을 짜는 도중에, 여행비용을 계산하기 위한 어플을 만들려고 합니다.

자유여행을 위해 먹는것과 노는것은 직접 가서 결정하기로 하고, 여행 가기전에는 에어텔(비행기+호텔)만 예약하려고 합니다.

여러가지 조합이 있어서 선택 후 가격을 알아보려고 합니다.


투어 클래스에서 항공사, 호텔 마다 클래스를 만들수가 없어서 각각의 클래스를 데코레이터로 만들어서,

내가 결정한 항공사와, 호텔을 데코레이터로 감싸고,

최종적으로 내가 감싼 비행기와 호텔의 가격을 알기 위한 코드입니다.



코드




Tour.h

#import <Foundation/Foundation.h>


@interface Tour : NSObject {

    NSString *description;

}


-(NSString*)getDescription;

-(double)cost;


@end


Tour.m

#import <Foundation/Foundation.h>


@interface Tour : NSObject {

    NSString *description;

}


-(NSString*)getDescription;

-(double)cost;


@end


기본 Tour클래스로 설명을 볼수 있는 Description과 가격을 알수있는 cost 함수가 있다.




KoreanAir.h


#import "Tour.h"


@interface KoreanAir : Tour


@end



KoreanAir.m


#import "KoreanAir.h"


@implementation KoreanAir


- (instancetype)init {

    self = [super init];

    

    if (self) {

        description = @"Airplane - KoreanAir";

    }

    

    return self;

}


- (double)cost {

    return 100;

}


@end


Tour클래스를 상속받은 비행기클래스이다.

생성자에 비행기 정보와 비용을 설정한다.




AsianaAir.h


#import "Tour.h"


@interface AsianaAir : Tour


@end


AsianaAir.m

#import "AsianaAir.h"


@implementation AsianaAir


- (instancetype)init {

    self = [super init];

    

    if (self) {

        description = @"Airplane - AsianaAir";

    }

    

    return self;

}

- (double)cost {

    return 101;

}


@end


비행기 클래스로 위의 

Korean클래스와 같다.




JinAir.h


#import "Tour.h"


@interface JinAir : Tour


@end


JinAir.m


#import "JinAir.h"


@implementation JinAir



- (instancetype)init {

    self = [super init];

    

    if (self) {

        description = @"Airplane - JinAir";

    }

    

    return self;

}


- (double)cost {

    return 80;

}


@end


비행기 클래스로 위의 

Korean클래스와 같다.




HotelDecorator.h


#import "Tour.h"


@interface HotelDecorator : Tour


@end


HotelDecorator.m


#import "HotelDecorator.h"


@implementation HotelDecorator


- (NSString *)getDescription {

    NSAssert(NO, @"This is an abstract method so should be overridden.");

    return nil;

}


@end


HotelDecorator 클래스는 Tour클래스를 상속받아서 생성합니다. 모든 호텔클래스는 이 클래스를 기반으로 합니다.



HennanRagoonHotel.h


#import "HotelDecorator.h"

#import "Tour.h"

@interface HennanRagoonHotel : HotelDecorator{

    Tour *_tour;

}

- (instancetype)initWithTour:(Tour *)tour;

@end


HennanRagoonHotel.m


#import "HennanRagoonHotel.h"


@implementation HennanRagoonHotel


- (instancetype)initWithTour:(Tour *)tour{

    self = [super init];

    

    if (self) {

        _tour = tour;

    }

    

    return self;

}


- (NSString *)getDescription {

    return [NSString stringWithFormat:@"%@%@",_tour.getDescription,@", HeaanaRagoonHotel"];

}


- (double)cost {

    return 10 + _tour.cost;

}


@end


HotelDecorator를 상속받아 생성합니다. 헤난라군 클래스는 Tour클래스를 인스턴스 변수로 가지고 있고, 나중에 래핑할 때 이용됩니다.

헤난라군 클래스는 초기화 할때, Tour객체를 인자값을 넣고 getDescription과 cost를 구현합니다. 이 객체는 다른 객체를 중복해서 포함 해서 총 비용을 구할 수 있습니다.




ShangrilaHotel.h


#import "HotelDecorator.h"

#import "Tour.h"


@interface ShangrilaHotel : HotelDecorator {

    Tour *_tour;

}

- (instancetype)initWithTour:(Tour *)tour;


@end


ShangrilaHotel.m


#import "ShangrilaHotel.h"


@implementation ShangrilaHotel


- (instancetype)initWithTour:(Tour *)tour{

    self = [super init];

    

    if (self) {

        _tour = tour;

    }

    

    return self;

}


- (NSString *)getDescription {

    return [NSString stringWithFormat:@"%@%@",_tour.getDescription,@", ShangrilaHotel"];

}


- (double)cost {

    return 50 + _tour.cost;

}


@end


HennanRagoonHotel 클래스와 구조는 같습니다.



Thelindhotel.h

#import "HotelDecorator.h"

#import "Tour.h"


@interface ThelindHotel : HotelDecorator {

    Tour *_tour;

}

- (instancetype)initWithTour:(Tour *)tour;


@end


Thelindhotel.m


#import "ThelindHotel.h"


@implementation ThelindHotel



- (instancetype)initWithTour:(Tour *)tour{

    self = [super init];

    

    if (self) {

        _tour = tour;

    }

    

    return self;

}


- (NSString *)getDescription {

    return [NSString stringWithFormat:@"%@%@",_tour.getDescription,@", TheLindHotel"];

}


- (double)cost {

    return 30 + _tour.cost;

}



@end


HennanRagoonHotel 클래스와 구조는 같습니다.




main.m

#import "Tour.h"


#import "KoreanAir.h"

#import "AsianaAir.h"

#import "JinAir.h"


#import "HotelDecorator.h"


#import "HennanRagoonHotel.h"

#import "ShangrilaHotel.h"

#import "ThelindHotel.h"


int main(int argc, char * argv[]) {

    @autoreleasepool {

        //return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

        

        //진에어를 타고가서, 헤난라군2, 샹글릴라 1박했을 경우 입니다.

        Tour *tour1 = [JinAir new];

        tour1 = [[HennanRagoonHotel alloc] initWithTour:tour1];

        tour1 = [[HennanRagoonHotel alloc] initWithTour:tour1];

        tour1 = [[ShangrilaHotel alloc] initWithTour:tour1];

        

        NSLog(@"%@ $%0.2f",tour1.getDescription,tour1.cost);

        

        //진에어를 타고가서, 더린드 1, 샹그릴라 2 했을 경우 입니다.

        Tour *tour2 = [JinAir new];

        tour2 = [[ThelindHotel alloc] initWithTour:tour2];

        tour2 = [[ShangrilaHotel alloc] initWithTour:tour2];

        tour2 = [[ShangrilaHotel alloc] initWithTour:tour2];

        

        NSLog(@"%@ $%0.2f",tour2.getDescription,tour2.cost);

        

        //대한항공을 타고가서, 샹그릴라3 했을 경우입니다.

        Tour *tour3 = [KoreanAir new];

        tour3 = [[ShangrilaHotel alloc] initWithTour:tour3];

        tour3 = [[ShangrilaHotel alloc] initWithTour:tour3];

        tour3 = [[ShangrilaHotel alloc] initWithTour:tour3];

        

        NSLog(@"%@ $%0.2f",tour3.getDescription,tour3.cost);


    }

    return 0;

}


2016-04-20 12:03:35.358 04_DecoratorPattern[1675:98082] Airplane - JinAir, HeaanaRagoonHotel, HeaanaRagoonHotel, ShangrilaHotel $150.00

2016-04-20 12:03:35.359 04_DecoratorPattern[1675:98082] Airplane - JinAir, TheLindHotel, ShangrilaHotel, ShangrilaHotel $210.00

2016-04-20 12:03:35.359 04_DecoratorPattern[1675:98082] Airplane - KoreanAir, ShangrilaHotel, ShangrilaHotel, ShangrilaHotel $250.00


728x90

'Developer > Pattern' 카테고리의 다른 글

iOS 아키텍처 VIPER  (1) 2018.06.22
[Object-c]FactoryPattern - 팩토리 패턴  (0) 2016.04.19