想更深入探索一款软件的的生命周期, 从设计到它的使命完结被替换或者升级换代
- 做开发也有一段时间了, 想想自己还在为这个类那个对象蛋疼的时候, 别人已经开始做架构, 设计模式, 想着如何让工程更健壮具有弹性, 用以应付不断的需求变化。
- 我也/(ㄒoㄒ)/~~哭着在后面追赶了, 只希望不要被拉下太远。
- 接下来会陆续的对研究内容做一些整理和总结并记录下来。
简述设计模式(下一篇这里将只介绍本篇所学习的模式)
简述设计模式: 设计模式是让你和其他开发人员之间有共同的词汇(*********共享词汇*********), 一旦懂得这些词汇, 和其他开发人员之间的沟通就很容易, 也会促使那些不懂得程序员想开始学习设计模式。 设计模式也可以把你思考架构的层次提高到模式层面, 而不是及停留在琐碎的类和对象上。
共享词汇: 模式可以让你用更少的词汇做更充分的沟通, 帮助初级开发者快速成长, 它是我们程序员的"行话"
简述策略模式: 定义算法族, 分别封装起来, 让他们之间可以互相替换, 此模式让算法的变化独立于使用算法的客户
- PS: 书中是以JAVA为语言基础给出的例子, 这里作者主要做的是iOS开发, 所以翻译成OC进行举例
相关知识点和思路
涉及到的知识点
主要包括: ****封装****, ****继承****, ****多肽的使用****(****对应部分会在代码中详细标注****)。
思路分析
工程中经常遇到一些模块对象, 具有一些固定的习惯, 当然也有一些变化的习惯, 对于这些经常会发生变化的习惯, 我们采取策略模式将行为封装成类从父类中剥离出来, 这样不紧方便维护和管理, 也容易扩展, 使得这个类更具有弹性, 书中是以鸭子类来举例,
代码实现
准备工作
(1).鸭子父类
声明部分
/* Duck 类(所有鸭子的父类) */
#import <Foundation/Foundation.h>
@class FlyBehaviro;
@interface Duck : NSObject
#pragma mark -
#pragma mark 所有鸭子都有的习惯行为, 一般不会发生变化
- (void)swim; /* 游泳 */
- (void)display; /* 外观, 红头绿毛 */
#pragma mark -
#pragma mark 会发生变化的方法, 定义一个行为属性通过属性调用。
/**
* 用于实现替换和行为实现所封装的独立类
*/
@property (nonatomic, strong) FlyBehaviro *flyBehaviro;
@end
实现部分
#import "Duck.h"
#import "FlyBehaviro.h" /* 封装好的用于判断鸭子飞行行为的类 */
@interface Duck ()
@end
@implementation Duck
- (instancetype)init
{
self = [super init];
if (self) {
_flyBehaviro = [[FlyBehaviro alloc] init];/* 初始化方便继承鸭子类的子类直接调用 */
//_flyBehaviro = [FlyBehaviro sharedFlyBehaviro];
}
return self;
}
@end
(2).习惯类封装和实现
声明部分
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSUInteger, FlyStyle) {
Wings,
NoFly,
Rocket,
};
@interface FlyBehaviro : NSObject
+ (FlyBehaviro *)sharedFlyBehaviro;
/**
* 飞行方式
*
* @param flyStyle 飞行方式类型
*/
- (void)duckFlyWith:(FlyStyle)flyStyle;
@end
实现部分
/* 封装 */
#import "FlyBehaviro.h"
@implementation FlyBehaviro
static FlyBehaviro *sharedFlyBehaviro = nil;
+ (FlyBehaviro *)sharedFlyBehaviro
{
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedFlyBehaviro = [[self alloc] init];
});
return sharedFlyBehaviro;
}
- (void)duckWith:(FlyStyle)flyStyle {
switch (flyStyle) {
case 0:
[self noFly];
break;
case 1:
[self fly];
break;
case 2:
[self rockedFly];
break;
}
}
- (void)rockedFly {
NSLog(@"rocketFly");
}
- (void)fly {
NSLog(@"feifeifei");
}
- (void)noFly {
NSLog(@"noFly");
}
(3)继承了鸭子类的红头鸭子类
/* 继承 */
/* 声明 */
#import "Duck.h"
@interface mDuck : Duck
@end
/* 实现 */
#import "mDuck.h"
@implementation mDuck
@end
使用
/* 多肽 */
Duck *r = [[mDuck alloc] init]; /* 直接使用继承多肽性创建红头鸭对象, 父类指针指向子类 */
[r.flyBehaviro duckWith:Rocket];/* 在父类种已经初始化过了可以直接使用 */
- PS: 父类种的flyBehaviro属性可一个写成一个单利进行初始化, 避免多次使用浪费空间
优缺点分析
优点
策略模式提供了管理相关算法族的办法,恰当的使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
策略模式提供了可以替换继承关系的办法。
使用策略模式可以避免使用多重条件转移语句。
缺点
客户端必须了解所有的strategy,必须了解各个strategy之间的不同点,这样才能选择一个合适的strategy