好久了,過去了一個月沒有動筆寫東西了,除了工作的忙,還有最近在學習一個課程和看一些技術類的書籍,騰不出時間來寫部落格了,說了這麼多,其實歸根結底都是我懶的藉口,確實挺慚愧,還是得繼續加油,多寫多練習,做更好的自己。。。
策略模式
本文使用OC語言實現策略模式的實現
定義
定義一系列可以相互替換的演算法類,提供給客戶端相同的呼叫介面,客戶端呼叫不同的物件的相同方法來達到快速切換演算法的目的。
使用場景
下面是從程式設計原則討論策略模式的使用場景
- 針對同一個問題的多種不同的處理方式,但是具體的實現有差異,需要實現統一的介面,對變化部分進行封裝【面向抽象而非面向具體原則】。
- 分支太多導致了客戶端對演算法實現類的依賴太大,演算法擴充套件需要去修改實現--新增對應的分支,使得擴充套件不方便以及演算法類中的程式碼量膨脹。為了讓演算法類的擴充套件容易,需要對具體的演算法獨立封裝【開閉原則】;為了讓演算法程式碼保持最小和最簡單,需要對具體的演算法獨立實現【單一職責原則】。
案例實現
理財產品的回報計算,處理方式是一樣的,客戶端只要給固定的引數(平臺、月份、金額),需要計算出本金及利息的和,不同理財產品的計算介面定義是統一的,在實現上有差別,所以類似這種場景是比較適合使用策略模式的。
不同產品的利率:
有利網:
短期理財:6個月以內,年化收益:3%
中期理財:12個月以內,年化收益:4%
長期理財:24個月以內,年化收益:4.5%
支付寶:
定期理財3個月,年化收益:7%
定期理財6個月,年化收益:8%
定期理財12個月,年化收益:9.5%
定期理財24個月,年化收益:10.5% :10.5%
下面是理財產品這個案例的具體模組的程式碼實現。
定義策略介面
這個案例中策略介面是理財產品計算演算法的介面
#import <Foundation/Foundation.h>
@protocol FinancyStrategyProtocal <NSObject>
- (NSInteger)financyWithMonth:(NSInteger)month money:(NSInteger)money;
@end
複製程式碼
定義Context類
Context類使用到了演算法物件,這個物件是可以相互替換的
// FinancyContext.h
#import <Foundation/Foundation.h>
#import "FinancyStrategyProtocal.h"
@interface FinancyContext : NSObject
@property (nonatomic, strong) id<FinancyStrategyProtocal> financy;
- (instancetype)initWithFinancy:(id<FinancyStrategyProtocal>)financy;
- (NSInteger)financyWithMonth:(NSInteger)month money:(NSInteger)money;
@end
// FinancyContext.m
#import "FinancyContext.h"
@implementation FinancyContext
- (instancetype)initWithFinancy:(id<FinancyStrategyProtocal>)financy {
self = [super init];
if (self) {
_financy = financy;
}
return self;
}
- (NSInteger)financyWithMonth:(NSInteger)month money:(NSInteger)money {
return [_financy financyWithMonth:month money:money];
}
@end
複製程式碼
策略類的具體實現
A. 有利網的演算法策略實現
// YouLiFinancyStrategy.h
#import <Foundation/Foundation.h>
#import "FinancyStrategyProtocal.h"
@interface YouLiFinancyStrategy : NSObject <FinancyStrategyProtocal>
@end
// YouLiFinancyStrategy.m
#import "YouLiFinancyStrategy.h"
@implementation YouLiFinancyStrategy
- (NSInteger)financyWithMonth:(NSInteger)month money:(NSInteger)money {
// 短期理財:6個月以內,年化收益:3%
// 中期理財:12個月以內,年化收益:4%
// 長期理財:24個月以內,年化收益:4.5%
if (month <= 6) {
return money * 0.03f / 12 * month + money;
} else if (month <= 12) {
return money * 0.04f / 12 * month + money;
} else if (month <= 24) {
return money * 0.045f / 12 * month + money;
}
return 0;
}
@end
複製程式碼
A. 餘額寶的演算法策略實現
// AlipayFinancyStrategy.h
#import <Foundation/Foundation.h>
#import "FinancyStrategyProtocal.h"
@interface AlipayFinancyStrategy : NSObject <FinancyStrategyProtocal>
@end
// AlipayFinancyStrategy.m
#import "AlipayFinancyStrategy.h"
@implementation AlipayFinancyStrategy
- (NSInteger)financyWithMonth:(NSInteger)month money:(NSInteger)money {
// 定期理財3個月,年化收益:7%
// 定期理財6個月,年化收益:8%
// 定期理財12個月,年化收益:9.5%
// 定期理財24個月,年化收益:10.5%
if (month <= 3) {
return money * 0.07f / 12 * month + money;
} else if (month <= 6) {
return money * 0.08f / 12 * month + money;
} else if (month <= 12) {
return money * 0.095f / 12 * month + money;
} else if (month <= 24) {
return money * 0.105f / 12 * month + money;
}
return 0;
}
@end
複製程式碼
客戶端使用
id<FinancyStrategyProtocal> alipayFinancy = [[AlipayFinancyStrategy alloc] init];
FinancyContext* context = [[FinancyContext alloc] initWithFinancy:alipayFinancy];
NSInteger money = [context financyWithMonth:6 money:10000];
NSLog(@"Alipay money = %@", @(money));
id<FinancyStrategyProtocal> ylFinancy = [[YouLiFinancyStrategy alloc] init];
context.financy = ylFinancy;
money = [context financyWithMonth:6 money:10000];
NSLog(@"YouLi money = %@", @(money));
複製程式碼