在iOS中Delegate使用單例模式保證只有一份對象,那麼多個單例的狀況,可使用享元模式,下降了對象的讀寫次數,提升了性能,使用NSString、NSArray、NSMutableArray
等使用了建立型的抽象工廠模式,保留了內部建立步驟,產出多個類型產品,AppDelegate
使用狀態模式來改變APP的狀態,UIView
使用外觀模式封裝了一系列接口使view顯示出來,tableview
使用代理模式實現了view
和數據的分離。其實還有不少咱們在用而不是很清楚的設計模式,那麼咱們就來看下經常使用的設計模式。html
設計模式(Design Pattern)是一套被反覆使用、多數人知曉的、通過分類的、代碼設計經驗的總結。 使用設計模式的目的:爲了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式使代碼編寫真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構同樣。java
設計模式分爲建立型、結構型模式、行爲型模式,經過借來一張圖來表示一下git
這些設計模式提供了一種在建立對象的同時隱藏建立邏輯的方式,而不是使用 new 運算符直接實例化對象。這使得程序在判斷針對某個給定實例須要建立哪些對象時更加靈活。github
簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。在簡單工廠模式中,能夠根據參數的不一樣返回不一樣類的實例。簡單工廠模式專門定義一個類來負責建立其餘類的實例,被建立的實例一般都具備共同的父類。算法
在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用一個共同的接口來指向新建立的對象。編程
Sample sample=new Sample(參數);
複製代碼
在OC中咱們一般這樣子用設計模式
// productMethod 產品的方法
@protocol Product <NSObject>
-(void)productMethod;
@end
//工廠類
@interface SimpleFactory : NSObject
+(id<Product>)createProduct:(NSString *)productName;
@end
//產品A 實現協議代替 抽象方法
@interface ProductA : NSObject<Product>
@end
//產品B 實現協議代替 抽象方法
@interface ProductB : NSObject<Product>
@end
@class ProductA,ProductB;
@implementation SimpleFactory
+ (id<Product>)createProduct:(NSString *)productName{
if ([productName isEqualToString:NSStringFromClass(ProductA.class)]) {
return [[ProductA alloc]init];
}else if ([productName isEqualToString:NSStringFromClass(ProductB.class)]){
return [[ProductB alloc]init];
}else{
return nil;
}
}
@end
@implementation ProductA
- (void)productMethod {
}
@end
@implementation ProductB
- (void)productMethod {
}
@end
複製代碼
使用的時候是這樣子bash
//建立產品A
ProductA *a =[SimpleFactory createProduct:NSStringFromClass(ProductA.class)];
[a productMethod];
//建立產品B
ProductB *b =[SimpleFactory createProduct:NSStringFromClass(ProductB.class)];
[b productMethod];
複製代碼
優勢是經過一個參數肯定想要的哪一個類的實例,而不用關心內部如何實現,缺點是新增長一個產品須要更改createProduct:(NSString *)productName
的實現。app
工廠方法模式(Factory Method Pattern)又稱爲工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多態工廠(Polymorphic Factory)模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責定義建立產品對象的公共接口,而工廠子類則負責生成具體的產品對象,這樣作的目的是將產品類的實例化操做延遲到工廠子類中完成,即經過工廠子類來肯定究竟應該實例化哪個具體產品類。性能
工廠方法模式包含以下角色:
//工廠抽象方法
@protocol Factory <NSObject>
+ (void)createProduct:(NSString *)productName;
@end
//工廠類A
@interface FactoryA : NSObject<Factory>
+(id<Product>)createProduct:(NSString *)productName;
@end
//工廠類B
@interface FactoryB : NSObject<Factory>
+(id<Product>)createProduct:(NSString *)productName;
@end
//建立產品A
@implementation FactoryA
+ (id<Product>)createProduct:(NSString *)productName{
if ([productName isEqualToString:NSStringFromClass(ProductA.class)]) {
return [[ProductA alloc]init];
}else{
return nil;
}
}
@end
//建立產品B
@implementation FactoryB
+ (id<Product>)createProduct:(NSString *)productName{
if ([productName isEqualToString:NSStringFromClass(ProductB.class)]){
return [[ProductB alloc]init];
}else{
return nil;
}
}
@end
複製代碼
使用起來很簡單
//建立產品A
ProductA *a =[FactoryA createProduct:NSStringFromClass(ProductA.class)];
[a productMethod];
//建立產品B
ProductB *b =[FactoryB createProduct:NSStringFromClass(ProductB.class)];
[b productMethod];
複製代碼
優勢是當建立新的產品的時候,不須要對舊生產線進行更改,只須要新增一個方法便可,缺點是產品是單一的生產線,則工廠繼承協議,稍顯複雜,功能退化成簡單工廠模式。
抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象建立型模式。
抽象工廠模式包含以下角色:
// productMethod 產品的方法
@protocol ProductA <NSObject>
-(void)productMethod;
@end
@protocol ProductB <NSObject>
-(void)productMethod;
@end
//工廠抽象方法
@protocol Factory <NSObject>
//建立產品A實例
+ (id<ProductA>)createProductA:(NSString *)ProductAName;
//建立產品B實例
+ (id<ProductB>)createProductB:(NSString *)ProductBName;
@end
//工廠類A 協議在.m中實現
@interface Factory1 : NSObject<Factory>
@end
//工廠類B 協議在.m中實現
@interface Factory2 : NSObject<Factory>
@end
//產品A 實現協議代替 抽象方法 協議在.m中實現
@interface ProductA1 : NSObject<ProductA>
@end
@interface ProductA2 : NSObject<ProductA>
@end
//產品B 實現協議代替 抽象方法 協議在.m中實現
@interface ProductB1 : NSObject<ProductB>
@end
@interface ProductB2 : NSObject<ProductB>
@end
複製代碼
使用起來很簡單,首先建立工廠,而後根據工廠來產出想要的產品。
//A工廠生產產品
ProductA1 *a1 =[Factory1 createProductA:NSStringFromClass(ProductA1.class)];
ProductA1 *a2 =[Factory1 createProductA:NSStringFromClass(ProductA2.class)];
[a1 productMethod];
[a2 productMethod];
//B工廠生產產品B
//此處 省略代碼
複製代碼
優勢很明顯只須要更改工廠就能夠改變生產流水線,缺點是當須要進行新增一個產品,則須要對工廠的全部子類進行更改。
當抽象工廠模式中每個具體工廠類只建立一個產品對象,也就是隻存在一個產品等級結構時,抽象工廠模式退化成工廠方法模式;當工廠方法模式中抽象工廠與具體工廠合併,提供一個統一的工廠來建立產品對象,並將建立對象的工廠方法設計爲靜態方法時,工廠方法模式退化成簡單工廠模式。
簡單工廠有一個靜態方法生產一個產品,工廠模式是工廠方法抽象出來生產一個產品,抽象工廠是工廠抽象方法生產多個產品。
建造者模式(Builder Pattern):將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
建造者模式是一步一步建立一個複雜的對象,它容許用戶只經過指定複雜對象的類型和內容就能夠構建它們,用戶不須要知道內部的具體構建細節。建造者模式屬於對象建立型模式。根據中文翻譯的不一樣,建造者模式又能夠稱爲生成器模式。
建造者模式包含以下角色:
代碼
@protocol Builder <NSObject>
@optional
- (void)buildPartA;
- (void)buildPartB;
- (void)buildPartC;
- (instancetype)getResult;
@end
@interface BuilderA : NSObject<Builder>
- (void)buildPartA;
@end
@interface BuilderB : NSObject<Builder>
- (void)buildPartB;
@end
@interface Builder : NSObject
- (id)constuct;//加工
- (void)setBuilder:(id<Builder>)bd;
@end
//實現
//.m
@implementation BuilderA
- (void)buildPartA{
printf("build A");
}
-(instancetype)getResult
{
return self;
}
@end
@implementation BuilderB
- (void)buildPartB{
printf("build B");
}
-(instancetype)getResult
{
return self;
}
@end
@interface Builder ()
{
id<Builder> _bd;
}
@end
@implementation Builder
- (id)constuct{
//加工幾個步驟
[_bd buildPartA];
[_bd buildPartB];
[_bd buildPartC];
//組裝獲得產品
return [_bd getResult];
}
- (void)setBuilder:(id<Builder>)bd{
_bd = bd;
}
@end
複製代碼
優勢是客戶不知道具體的生產步驟,將生產步驟和過程解耦,能夠相同的步驟(有子類實現不一樣過程)生產不一樣的產品,擴展方便,只須要(子類)實現每一個步驟,缺點是多個產品類似點不少才能抽象出來步驟。
單例模式(Singleton Pattern):單例模式確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例,這個類稱爲單例類,它提供全局訪問的方法。
單例模式的要點有三個:一是某個類只能有一個實例;二是它必須自行建立這個實例;三是它必須自行向整個系統提供這個實例。單例模式是一種對象建立型模式。單例模式又名單件模式或單態模式。
單例模式包含以下角色:
代碼
@interface Singleton : NSObject
+ (instancetype)getInstace;
@end
@implementation Singleton
+ (instancetype)getInstace{
static dispatch_once_t onceToken;
static Singleton *_t;
dispatch_once(&onceToken, ^{
_t = [Singleton new];
});
return _t;
}
@end
複製代碼
使用起來也很簡單
Singleton *ton=[Singleton getInstace];
//next code
複製代碼
優勢內存中該類的實例化只有一次,省略了頻繁建立和銷燬步驟,提升了性能。缺點是單例模式沒有抽象層,擴展比較困難。
結構型模式(Structural Pattern)描述如何將類或者對 象結合在一塊兒造成更大的結構,就像搭積木,能夠經過 簡單積木的組合造成複雜的、功能更爲強大的結構。
結構型模式包含模式
適配器模式(Adapter Pattern) :將一個接口轉換成客戶但願的另外一個接口,適配器模式使接口不兼容的那些類能夠一塊兒工做,其別名爲包裝器(Wrapper)。適配器模式既能夠做爲類結構型模式,也能夠做爲對象結構型模式。
適配器模式包含以下角色:
代碼
@interface Adaptee : NSObject
- (void)specificRequest;
@end
@interface Adapter : NSObject
@property (nonatomic,strong) Adaptee *adaptee;
+ (instancetype)initWithAdaptee:(Adaptee *)obj;
- (void)request;
@end
@implementation Adaptee
- (void)specificRequest{
NSLog(@"適配器 第三方工人幹活了");
}
@end
@implementation Adapter
+ (instancetype)initWithAdaptee:(Adaptee *)obj{
Adapter *adapter=[Adapter new];
adapter.adaptee = obj;
return adapter;
}
//經過適配器 指導三方工人幹活,達到 客戶忽略過程,多個客戶能夠複用適配器代碼
- (void)request{
[self.adaptee specificRequest];
}
@end
複製代碼
優勢是通過加工第三方能夠爲客戶服務了,缺點是不支持多繼承的一次只能適配一個。
橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們均可以獨立地變化。它是一種對象結構型模式,又稱爲柄體(Handle and Body)模式或接口(Interface)模式。
橋接模式包含以下角色:
優勢是抽象Implementor
,具體實如今Implementor
子類實現,下降耦合。缺點是橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。
裝飾模式(Decorator Pattern) :動態地給一個對象增長一些額外的職責(Responsibility),就增長對象功能來講,裝飾模式比生成子類實現更爲靈活。其別名也能夠稱爲包裝器(Wrapper),與適配器模式的別名相同,但它們適用於不一樣的場合。根據翻譯的不一樣,裝飾模式也有人稱之爲「油漆工模式」,它是一種對象結構型模式。 裝飾模式包含以下角色:
代碼
//定義了協議
@protocol ComponentProtocol <NSObject>
- (void)opertion;
@end
//實現協議的類
@interface ComponentA : NSObject<ComponentProtocol>
@end
@interface ComponentB : NSObject<ComponentProtocol>
@end
//ComponentA的分類
@interface Component : ComponentA(add)
- (void)addMethod;
@end
//實現部分
//.m
@implementation ComponentA
- (void)opertion{
NSLog(@"ComponentA opertion ");
}
@end
@implementation ComponentB
- (void)opertion{
NSLog(@"ComponentB opertion ");
}
@end
//ComponentA的分類
@implementation Component(add)
- (void)addMethod{
NSLog(@"addMethod");
}
@end
複製代碼
優勢動態添加功能(iOS中的分類),缺點是類變多(多個分類)時,排查錯誤很差排查。
外觀模式(Facade Pattern):外部與一個子系統的通訊必須經過一個統一的外觀對象進行,爲子系統中的一組接口提供一個一致的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。外觀模式又稱爲門面模式,它是一種對象結構型模式。
外觀模式包含以下角色:
//子系統角色
@interface SystemA : NSObject
- (void)run;
@end
//子系統角色
@interface SystemB : NSObject
- (void)eat;
@end
//子系統角色
@interface SystemC : NSObject
- (void)play;
@end
//外觀角色
@interface Facade : NSObject
@property (nonatomic,strong) SystemA *a;
@property (nonatomic,strong) SystemB *b;
@property (nonatomic,strong) SystemC *c;
@end
複製代碼
優勢下降用戶和子系統的耦合,並且能夠經過外觀訪問子系統,子系統可移植性強,缺點是外觀沒有進行抽象化,更改子系統必須更改外觀類。
享元模式(Flyweight Pattern):運用共享技術有效地支持大量細粒度對象的複用。系統只使用少許的對象,而這些對象都很類似,狀態變化很小,能夠實現對象的屢次複用。因爲享元模式要求可以共享的對象必須是細粒度對象,所以它又稱爲輕量級模式,它是一種對象結構型模式。
享元模式包含以下角色:
@interface FYFly : NSObject
@property (nonatomic,strong) NSMutableDictionary * dic;
@end
@protocol FlyweightProtocol <NSObject>
- (void)play;
@end
@interface FlyweightA : NSObject<FlyweightProtocol>
- (void)eat;
@end
@interface FlyweightB : NSObject<FlyweightProtocol>
- (void)run;
@end
@implementation FlyweightA
- (void)play{
NSLog(@"我在玩耍");
}
- (void)eat{
NSLog(@"我在吃飯");
}
@end
@implementation FlyweightB
- (void)play{
NSLog(@"我在玩耍");
}
- (void)run{
NSLog(@"我在跑步");
}
@end
複製代碼
優勢多個重複使用率高的對象使用該模式,能夠提升效率,缺點使系統更加複雜。
代理模式比較簡單,系統的tableView
中就是使用代理實現的。
行爲型模式(Behavioral Pattern)是對在不一樣的對象之間劃分責任和算法的抽象化。 行爲型模式不只僅關注類和對象的結構,並且重點關注它們之間的相互做用。 經過行爲型模式,能夠更加清晰地劃分類與對象的職責,並研究系統在運行時實例對象 之間的交互。在系統運行時,對象並非孤立的,它們能夠經過相互通訊與協做完成某些複雜功能,一個對象在運行時也將影響到其餘對象的運行。
行爲型模式分爲類行爲型模式和對象行爲型模式兩種:
類行爲型模式:類的行爲型模式使用繼承關係在幾個類之間分配行爲,類行爲型模式主要經過多態等方式來分配父類與子類的職責。
對象行爲型模式:對象的行爲型模式則使用對象的聚合關聯關係來分配行爲,對象行爲型模式主要是經過對象關聯等方式來分配兩個或多個類的職責。根據「合成複用原則」,系統中要儘可能使用關聯關係來取代繼承關係,所以大部分行爲型設計模式都屬於對象行爲型設計模式。
包含模式
下面咱們挑選幾種重要的演練一下
命令模式(Command Pattern):將一個請求封裝爲一個對象,從而使咱們可用不一樣的請求對客戶進行參數化;對請求排隊或者記錄請求日誌,以及支持可撤銷的操做。命令模式是一種對象行爲型模式,其別名爲動做(Action)模式或事務(Transaction)模式。
命令模式包含以下角色:
代碼
@interface Order : NSObject
- (void)exe;
@end
@protocol CommandProtocol <NSObject>
- (void)play;
@end
@interface Order1 : NSObject<CommandProtocol>
@end
@interface Order2 : NSObject<CommandProtocol>
@end
@interface Order3 : NSObject<CommandProtocol>
@end
@implementation Order
- (void)exe{
[[Order1 new] play];
}
@end
@implementation Order1
- (void)play {
NSLog(@"進入公園");
[[Order2 new] play];
}
@end
@implementation Order2
- (void)play {
NSLog(@"開始打球");
[[Order3 new] play];
}
@end
@implementation Order3
- (void)play{
NSLog(@"開始打羽毛球");
}
@end
複製代碼
優勢類之間耦合度低,缺點單一的命令會形成過多的實體類。
中介者模式(Mediator Pattern)定義:用一箇中介對象來封裝一系列的對象交互,中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。中介者模式又稱爲調停者模式,它是一種對象行爲型模式。
中介者模式包含以下角色:
@interface Meditor : NSObject
- (void)registerObj:(NSString *)key;
- (void)sendMsg:(NSString *)key msg:(NSString *)msg;
@end
@protocol ColleagueProtocol <NSObject>
- (void)sendmsg:(NSString *)msg;
@end
@interface ColleagueA : NSObject<ColleagueProtocol>
@end
@interface ColleagueB : NSObject<ColleagueProtocol>
@end
@interface Meditor(){
NSMutableDictionary *_dic;
}
@end
@implementation Meditor
- (void)registerObj:(NSString *)key id:(id<ColleagueProtocol>)obj{
if (_dic ==nil) {
_dic=[NSMutableDictionary dictionary];
}
[_dic setObject:key forKey:obj];
}
- (void)sendMsg:(NSString *)key msg:(NSString *)msg{
id <ColleagueProtocol> obj = _dic[key];
[obj sendmsg:msg];
}
@end
@implementation ColleagueA
- (void)sendmsg:(NSString *)msg{
NSLog(@"ColleagueA send %@",msg);
}
@end
@implementation ColleagueB
- (void)sendmsg:(NSString *)msg{
NSLog(@"ColleagueB send %@",msg);
}
@end
複製代碼
優勢簡化對相互之間交互,下降耦合,缺點會致使終結者很是複雜。
觀察者模式(Observer Pattern):定義對象間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆獲得通知並被自動更新。觀察者模式又叫作發佈-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
觀察者模式是一種對象行爲型模式。
觀察者模式包含以下角色:
@interface ViewController ()
@property (nonnull,nonatomic,assign) int age;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self addObserver:self forKeyPath:@"age"
options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld
context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
NSLog(@"%@",change);
}
@end
複製代碼
優勢能夠實時監測到對象的變化,缺點是訂閱者過多會形成性能低下,觀察者只知道變化的結果,不瞭解變化的是如何變化的。
狀態模式(State Pattern) :容許一個對象在其內部狀態改變時改變它的行爲,對象看起來彷佛修改了它的類。其別名爲狀態對象(Objects for States),狀態模式是一種對象行爲型模式。
狀態模式包含以下角色:
typedef enum : NSUInteger {
StateClose = 0,
StateOpen = 1,
} State;
@interface StateClass : NSObject
@property (nonatomic,assign) State s;
@end
@implementation StateClass
- (void)setS:(State)s{
switch (s) {
case StateOpen:
{
NSLog(@"飛機已啓動");
}
break;
case StateClose:
{
NSLog(@"飛機已落地");
}
break;
default:
break;
}
}
@end
複製代碼
優勢是使用狀態控制類的行爲,缺點是新增狀態須要修改狀態類對應的源碼。
策略模式(Strategy Pattern):定義一系列算法,將每個算法封裝起來,並讓它們能夠相互替換。策略模式讓算法獨立於使用它的客戶而變化,也稱爲政策模式(Policy)。
策略模式包含以下角色:
@interface Strategy : NSObject
- (void)handle;
@end
@interface StrategyA : NSObject
- (void)handle;
@end
@interface StrategyB : NSObject
- (void)handle;
@end
@interface Context : NSObject
@property (nonatomic,strong) Strategy *obj;
- (void)opertion;
@end
@implementation Context
- (void)opertion{
[self.obj handle];
}
@end
@implementation Strategy
- (void)handle{}
@end
@implementation StrategyA
- (void)handle{
NSLog(@"老三 算數");
}
@end
@implementation StrategyB
- (void)handle{
NSLog(@"老四 算數");
}
@end
複製代碼
優勢能夠靈活增長算法,缺點是客戶必須知道策略的算法從而決定了解使用哪一個算法,策略會產生多個對象,可使用享元模式進行對象管理。
廣告時間