IOS開發(fā)設(shè)計(jì)模式之裝飾者模式

概念:標(biāo)準(zhǔn)的裝飾模式有包括一個(gè)抽象的Component父類,它聲明了一些操作,它具體的類講進(jìn)行重載以實(shí)現(xiàn)自己特定的操作。這個(gè)Component具體類是模式中的被裝飾者,Component父類可以被細(xì)化為另一個(gè)叫做Decorator的抽象類,即裝飾者抽象類。Decorator類中包含了一個(gè)Component的引用。Decorator的具體類為Component或者Decorator定義了幾個(gè)擴(kuò)展行為,并且會(huì)在自己的操作中內(nèi)嵌Component操作。關(guān)系圖見 裝飾模式類圖
Component定義了一些抽象操作,具體類將進(jìn)行重載實(shí)現(xiàn)自己特定的操作。Decorator抽象類通過將一個(gè)Component(或Decorator)內(nèi)嵌到Decorator對(duì)象,定義了擴(kuò)展這個(gè)Component的實(shí)例的“裝飾性”的行為。默認(rèn)的operation方法只是想內(nèi)嵌的Component發(fā)送一個(gè)消息,Decorator的具體實(shí)現(xiàn)類重載父類的operation,通過super把自己增加的行為擴(kuò)展給Component的operation。如果只需要向Component添加一種職責(zé),那可以省掉抽象的Decorator類,讓具體的Decorator直接把請(qǐng)求轉(zhuǎn)發(fā)給Component。那么這種方式就好像形成一種操作鏈,把一種行為加到另一種行為之上。

2.裝飾者模式概念圖

裝飾者模式類圖

裝飾模式使用場(chǎng)景

想要在不影響其他對(duì)象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對(duì)象添加職責(zé)。想要擴(kuò)展一個(gè)類的行為,卻做不到。類定義可能被隱藏,無(wú)法進(jìn)行子類化;或者對(duì)類的每個(gè)行為的擴(kuò)展,為支持每種功能組合,將產(chǎn)生大量的子類,對(duì)類的職責(zé)的擴(kuò)展是可選的。

1.當(dāng)系統(tǒng)需要新功能時(shí),向舊類中添加新的代碼,這些新代碼只是裝飾了原有類的核心職責(zé),并沒有替換掉原有類的核心職責(zé)。新的字段、方法和邏輯增加了原有類的復(fù)雜度。這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才執(zhí)行的特殊需要,不必加入原有類,增加復(fù)雜度。
2.裝飾者模式提供了一個(gè)非常好的解決方案,它把每個(gè)要裝飾的功能放在單獨(dú)的類當(dāng)中,并讓這個(gè)類包裝它所要裝飾的對(duì)象。當(dāng)需要執(zhí)行特殊行為時(shí),viewController 中的代碼就可以在運(yùn)行時(shí)根據(jù)需要有選擇、按順序地使用裝飾對(duì)象了。
3.裝飾模式可以把類中的裝飾功能去除,簡(jiǎn)化類,有效區(qū)分核心職責(zé)和裝飾功能,去除相關(guān)類中重復(fù)的裝飾邏輯。

使用案例:

一個(gè)女孩需要出席一場(chǎng)晚會(huì),這個(gè)時(shí)候需要盛裝打扮下自己。使用裝飾者模式就再好不過了。

首先定義一個(gè)類,這個(gè)類是要出席晚會(huì)的girl,被裝飾對(duì)象。
實(shí)現(xiàn)代碼細(xì)節(jié)

@interface Girl : NSObject
代表名字
@property (nonatomic, strong) NSString *name;
//穿的裝飾品
- (void)show;
@end
//展示自己穿了什么衣服
- (void)show{
    NSLog(@"%@",self.name);  
}
- (void)setName:(NSString *)name{
    _name = name;
}

在定義一個(gè)裝飾類Finery 類 其實(shí)就是 Decorator 類(裝飾抽象類)

#import "Girl.h"
@class Girl;
@interface Finery : Girl;
@property(nonatomic,strong)Girl *component;
@end

#import "Finery.h"
@implementation Finery
- (void)show{
    if (self.component!= nil) {
        [self.component show];
    }
}
- (void)setComponent:(Girl *)component{
    _component = component;
}
@end

然后就可以定義具體的類,比如衣服,鞋子,褲子。去擴(kuò)展裝飾對(duì)象,修飾裝飾對(duì)象。

#import "Finery.h"

@interface Shoes : Finery

@end

#import "Shoes.h"

@implementation Shoes
- (void)show{
    [super show];
    NSLog(@"鞋子");
}
@end

具體調(diào)用方式

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.title = @"裝飾者模式";
    Girl *girl = [[Girl alloc] init];
    girl.name = @"james";
    Shoes *shoe = [Shoes new];
    shoe.component = girl;
    [shoe show];
}
實(shí)現(xiàn)結(jié)果
效果圖
分析實(shí)現(xiàn)過程:

Finery 不會(huì)被直接使用,而是作為具體裝飾類的父類存在。具體服飾類,就是Shoes 這些類,這些類需要在調(diào)用父類 show 方法的同時(shí)實(shí)現(xiàn)自己特有的方法。首先,創(chuàng)建的girl對(duì)象給name賦值為james,然后創(chuàng)建shoe對(duì)象,設(shè)置shoe的component = girl,然后調(diào)用[shoe show];來到show方法內(nèi)部 執(zhí)行 NSLog(@"鞋子");
[super show];會(huì)來到父類也就是裝飾類Finery中調(diào)用

- (void)show{
    if (self.component!= nil) {
        [self.component show];
    }
}

由于self.component是Girl類型,所以會(huì)執(zhí)行Girl內(nèi)部的show方法輸出James.

最后編輯于
?著作權(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)容

  • 1 場(chǎng)景問題# 1.1 復(fù)雜的獎(jiǎng)金計(jì)算## 考慮這樣一個(gè)實(shí)際應(yīng)用:就是如何實(shí)現(xiàn)靈活的獎(jiǎng)金計(jì)算。 獎(jiǎng)金計(jì)算是相對(duì)復(fù)雜...
    七寸知架構(gòu)閱讀 4,298評(píng)論 4 67
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,094評(píng)論 1 15
  • 設(shè)計(jì)原則: 少用繼承,多用組合 類應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉 目錄 本文的結(jié)構(gòu)如下: 什么是裝飾者模式 為什么要用...
    w1992wishes閱讀 1,296評(píng)論 0 7
  • 裝飾者Decorator 背景 問題 你如何組織你的代碼使其可以容易的添加基本的或者一些很少用到的 特性,而不是直...
    踐行者閱讀 325評(píng)論 0 2
  • 需求 寫一個(gè)給人模擬搭配不同服飾的程序,可以給人換各種各樣的衣服褲子的形象。 初步實(shí)現(xiàn) 需求比較簡(jiǎn)單,直接上代碼:...
    Mr丶sorrow閱讀 843評(píng)論 0 2

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