设计模式

一.对象创建

1.原型

2.工厂 (单一的产品)

父类 --------->方法 + 属性 (通过调用多态生成相应子类的的实例)
|
|
|
子类 -------> 方法 + 属性

3.抽象工厂 (单一产品)

父类 --------->方法 + 属性 (通过预定义生成相应子类的的实例)
|
|
|
子类 -------> 方法 + 属性

4.生成器 (复杂的产品, 定制相应的属性, 最后返回产品)

5.单例 (生命周期内只有一个实例)

二.接口适配

6.适配器 (协议,继承)

用于连接量作用不同种类对象,时期毫无疑问地协同工作.又称为包装器(wrapper).主要作用是把被适配者的行为传递给管道另一端的客户端.

I.类适配器

protocol,继承

II.对象适配器

protocol,delegate,block

7.桥接模式

目的是把抽象层次结构从其实现中分离出来,使其能够独立变更. 抽象层定义了供客户端商用的上层的抽象接口. 实现层次机构定义了供抽象层次使用的底层接口.实现类的引用被封装于抽象层的实例中.

类图

8.外观

外观模式为子系统中一组不同的接口提供了统一的接口.外观定义了上层接口,通过降低复杂度和隐藏子系统间的通讯及依存关系,让子系统易于使用

外观模式

三.对象去耦

9.中介者

中介者模式定义一个集中测场所,对象间的交互可以在中介者对象中处理.减少他们之间的依存关系---松耦合.

普通模式 VS 中介者模式


普通模式
中介者模式

从类图中可以很明显的降低界面的耦合.

10.观察者

观察者模式类图

I.通知 (松耦合,程序级)

NSNotificationCenter 发布--订阅模式.
addObserver 订阅

removeObserver取消订阅

II.KVO (主要是观察对象属性变化)

addObserver:forKeyPath:options:context:
observerValueForKeyPath:ofObject:change:context:
willChangeValueForKey:
didChangeValueForKey:

四.抽象集合

11.组合(composite)

"部分-整体"的层次结构,它既是包含对象的组合(容器)又包含作为叶节点(基元)的单个对象的层次机构.

组合模式

12.迭代器(ListIterator)

提供了一种顺序访问聚合对象中元素的方法.基本上有两种迭代器:外部迭代器和内部迭代器.主要区别如下:

外部迭代器 VS 内部迭代器

I.外部迭代器
NSEnumerator集合迭代器,NSDirectoryEnumerator文件夹迭代器,还有基于块(block-base Enumeration)的迭代器 enumerateObjectsUsingBlock:(void(^)(id obj, NSInteger idx, BOOL *stop))block

II.内部迭代器
makeObjectsPerformSelector:(SEL)aSelector它允许客户端向数组中每个元素发送一个消息.

** 拓展 **
可以为组合指定外部枚举方法:allObjectsnextObject,可以借助栈实现该效果.
也可以指定内部迭代方法.

-(void)enumerateMarksUsingBlock:(void(^)(id obj, BOOL *stop))block{
  BOOL stop = NO;
  NSEnumerator *enumerator = [self enumerator];
  for(id mark in enumerator)
  {
    block(mark, &stop);
    if(stop) break;
  }
}

五.行为扩展

13.访问者

访问者模式涉及两个关键角色:访问者和访问的元素.访问者知道复杂结构中的每个元素,可以访问每个元素的节点,并根据元素的特征,属性或操作执行任何操作.让我们可以不更改各元素累的前提下定义作用这些元素的新操作.

类图如下:
访问者模式

14.装饰

标准的装饰模式包括一个抽象的Component父类,它为其他组件(component)声明一些操作.抽象的Component类可被细化成另外一个叫做Decorator的类.Decorator包含了另一个Component的引用.ConcreteDecorator为其他component或者Decorate定义了几个扩展行为,并且会在自己的操作中执行内嵌的component操作.
动态地给对象添加一些额外的职责.相比子类来说更为灵活.如UIImage 滤镜就是使用就是该模式

1.创建抽象类添加协议实现UIImage的绘图方法.

@optional
    -(void)draw...
@end

2.给UIImage分类 ,遵循协议

@interface UIImage(ImageComponent)< ImageComponent >
@end

3.实现抽象类,实行消息转发.

@interface ImageFilter: NSObject< ImageComponent >
{
@provate
    id< ImageComponent > _component;
}
-(void)apply;
...
@end
@implementation  ImageFilter
-(void)apply{
//应有子类重载,应用各种样式的滤镜
}
//消息转发
-(id)forwardingTargetForSelector:(SEL)aSelector
{

  NSString *name = NSStringFromSelector(aSelector);
  if([name hasPrefix:@"draw"]){
     [ self  apply];
  }
  return  _component;
}
@end

4.子类继承.

@interface ImageTransformFilter: ImageFilter 
{
CGAffineTransform _transform;
}
-(void)apply;
-(id)initWithImageComponent:(id< ImageComponent >)component transform:(CGAffineTransform) transform;
...
@end
@implementation  ImageTransformFilter

-(void)apply{
    CGContextRef context = UIGraphicsGetCurrentContext();
  //设置变换
    CGContextConcatCTM(context, _transform);
}

@end

具体实现demo地址 github地址

类图:


类图

15.责任链

责任链模式的主要思想: 对象引用了统一类型的另一个对象,形成一条链.链中的每个对象实现相同的方法,处理链中第一个对象发起的同一个请求.如果一个对象不知道如何处理请求,它就把请求传达给下一个响应器(responder).

类图:


责任链类图

六.算法封装

16.模板方法

抽象类的一个方法定义标准算法.在这个方法中调用的基本操作应有子类重载予以实现.这个方法被称为模板.还可以留钩子(hook),子类实现重载,实现自定义效果.

模板设计模式

模板与委托的比较

模板 VS 委托

17.策略

把相关算法分离为不同类,成为策略.

策略模式
18.命令

把命令封装在对象中,命令对象封装了如何对目标指令的信息.因此客户端或者调用者不必了解目标的任何细节,却仍可以对它执行任何已有的操作.通过把请求封装成对象,客户端可以把它参数化并置于队列或日志中,也能够支持可撤销操作.命令模式消除了作为对象的动作和执行它的接收器之间的绑定.

七.性能与对象访问

18.享元

运用共享技术有效地支持大量细粒度的对象. 两个关键组件: 1.可共享的的享元对象 2.保存他们的池. 某种中央对象维护这个池,并返回适当的实例.

屏幕快照 2018-10-15 下午1.35.36.png

示例:百花池

@implementation FlowerViewFactory
{
    NSMutableDictionary *_flowerPools;
}

-(UIView *)flowerViewWithType:(FlowerType)type{
    
    if (_flowerPools == nil) {
        _flowerPools = [NSMutableDictionary dictionaryWithCapacity:kTotaoNumberOfFlowerTypes];
    }
    
    UIView *flowerView = [_flowerPools objectForKey:[NSNumber numberWithInt:type]];
    
    if (flowerView == nil) {
        
        UIImage *flowerImage;
        switch (type) {
            case kAnemone:
                flowerImage = [UIImage imageNamed:@"1"];
                break;
            case kCosmos:
                flowerImage = [UIImage imageNamed:@"2"];
                break;
                
            case kGerberas:
                flowerImage = [UIImage imageNamed:@"3"];
                break;
                
            case kHollyhock:
                flowerImage = [UIImage imageNamed:@"4"];
                break;
                
            case kJasmine:
                flowerImage = [UIImage imageNamed:@"5"];
                break;
            case kZinnia:
                flowerImage = [UIImage imageNamed:@"6"];
                break;
            default:
                break;
        }
        
        flowerView = [[FlowerView alloc] initWithImage:flowerImage];
        
        [_flowerPools setObject:flowerView forKey:[NSNumber numberWithInt:type]];
        
    }
    
    return flowerView;
    
}

@end

享元类

@interface ExtrinsicFlowerState : NSObject
@property (strong, nonatomic) UIView  *flower;
@property (assign, nonatomic) CGRect  area;
@end

controller里面

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    ShowFlowers *show = [[ShowFlowers alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:show];
    FlowerViewFactory *factory = [[FlowerViewFactory alloc] init];
    NSMutableArray *flowerList = [[NSMutableArray alloc] initWithCapacity:500];
    CGRect bounds = [[UIScreen mainScreen] bounds];
    NSInteger minSize = 10;
    NSInteger maxSize = 50;
    
    for (int i = 0; i<500; ++i) {
        
        FlowerType flowtype = arc4random()%kTotaoNumberOfFlowerTypes;
        
        UIView *flowerView = [factory flowerViewWithType:flowtype];
        
        CGFloat x = arc4random()%(int)bounds.size.width;
        CGFloat y = arc4random()%(int)bounds.size.height;
        
        CGFloat size = arc4random()%(maxSize-minSize+1)+minSize;
        
        ExtrinsicFlowerState *state = [ExtrinsicFlowerState new];
        state.flower = flowerView;
        state.area = CGRectMake(x, y, size, size);
        [flowerList addObject:state];
    }
    
    show.flowers = flowerList;
    
}

实现缓存池单元共享.

19.代理

为其他对象提供一种代理以控制这个对象的访问

持续更新中...

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351