<commit_before>---
layout: post
title: iOS设计模式
category: iOS
tags: iOS iOS设计模式
keywords: iOS iOS设计模式
description: iOS iOS设计模式
---

设计模式的五大原则
1. 单一职责
（职责分离）在定义类、接口、方法后，不能多于一个动机去改变这个类、接口、方法。
2. 开闭原则
类、模块、方法可以扩展，但是不可以修改。开发人员应该仅仅对程序中频繁出现变化的地方进行抽象（封装变化点，继承的使用，抽象类的使用）。
3. 替换原则（is-a）
保证子类可以替换它的基类。
在项目中所有使用子类的地方都可用父类替换，但在调用方法的时候 ，即呈现面向对象编程的多态性。即替换原则，非常重要的原则，也是比较难的原则。
4. 依赖倒置原则
a、高层模块不应该依赖于低层模块。二者都应该依赖于抽象
　　b、抽象不应该依赖于细节。细节应该依赖于抽象。
5. 接口隔离原则
接口隔离的方法有两种（分享客户就是分离接口）：
1、使用委托（此委托非.net委托[delegate]）分离接口
使用委托即，创建一个委托类，用此类去实现分离后的其它接口中的方法。
2、使用多重继承分离接口、
此方法，即将现有“胖”接口分成供不同客户程序调用的两个或多个接口，而需要实现多个接口的客户程序，则使用多重继承来实现。


设计模式的类型：  


## 一、适配器模式
例子：不同的model数据，对应转化给view的一个特定model。

类适配器方法：
1.建一个抽象类的协议:cartAdapterProtocol
2、新定义一个类ModelAdapter遵循上面的协议，就是一个适配器model类。每一个输入类都需要新建一个对应的适配类。
3、用的时候创建ModelAdapter，用model初始化；
[CardView loadView：（id <adapterProtocol>）ModelAdapter];  

对象适配器：
1、就新建一个类适配所有不同的model；
根据传入不同model，isMemberOfClass 分别处理返回对应的modelData。

优缺点：
1、降低耦合度，提高复用维护
2、复杂了一点，降低了一点可读性。

## 二、策略模式  

例子：一个view中有很多textfield_custom，每个都需要添加输入验证合法性的方法，一般写会加很多if-else判断控件然后走对应的验证方式.  
使用策略的方式：  
1、先建一个抽象类validator，有一个之后需要重写的方法validateInput().
2、建个子类，重载父类的验证方法validateInput(). 如：EmailValidator, phoneValidator
3、textfield_custom中会添加一个属性：validator；初始化的时候这个属性赋值上对应的子类。
验证就直接调用：EmailTextfield.validator.validateInput();  

优缺点：
1、简化ifelse 代码维护性高
2、使用化之前就是确定的类型，不能动态判断  

## 三、观察者模式  

例子：   
1、
2、
3、

优缺点：
1、
2、


## 四、原型/外观  

例子：   
1、
2、
3、

优缺点：
1、
2、


## 五、装饰  

例子：   
1、
2、
3、

优缺点：
1、
2、


## 六、工厂  

例子：   
1、
2、
3、

优缺点：
1、
2、

## 七、桥接模式

例子：   
1、
2、
3、

优缺点：
1、
2、

## 八、代理  

例子：   
1、
2、
3、

优缺点：
1、
2、

<commit_msg>add learn<commit_after>---
layout: post
title: iOS设计模式
category: iOS
tags: iOS iOS设计模式
keywords: iOS iOS设计模式
description: iOS iOS设计模式
---

设计模式的五大原则
1. 单一职责
（职责分离）在定义类、接口、方法后，不能多于一个动机去改变这个类、接口、方法。
2. 开闭原则
类、模块、方法可以扩展，但是不可以修改。开发人员应该仅仅对程序中频繁出现变化的地方进行抽象（封装变化点，继承的使用，抽象类的使用）。
3. 替换原则（is-a）
保证子类可以替换它的基类。
在项目中所有使用子类的地方都可用父类替换，但在调用方法的时候 ，即呈现面向对象编程的多态性。即替换原则，非常重要的原则，也是比较难的原则。
4. 依赖倒置原则
a、高层模块不应该依赖于低层模块。二者都应该依赖于抽象
　　b、抽象不应该依赖于细节。细节应该依赖于抽象。
5. 接口隔离原则
接口隔离的方法有两种（分享客户就是分离接口）：
1、使用委托（此委托非.net委托[delegate]）分离接口
使用委托即，创建一个委托类，用此类去实现分离后的其它接口中的方法。
2、使用多重继承分离接口、
此方法，即将现有“胖”接口分成供不同客户程序调用的两个或多个接口，而需要实现多个接口的客户程序，则使用多重继承来实现。


设计模式的类型：  


## 一、适配器模式
例子：不同的model数据，对应转化给view的一个特定model。

类适配器方法：
1.建一个抽象类的协议:cartAdapterProtocol
2、新定义一个类ModelAdapter遵循上面的协议，就是一个适配器model类。每一个输入类都需要新建一个对应的适配类。
3、用的时候创建ModelAdapter，用model初始化；
[CardView loadView：（id <adapterProtocol>）ModelAdapter];  

对象适配器：
1、就新建一个类适配所有不同的model；
根据传入不同model，isMemberOfClass 分别处理返回对应的modelData。

优缺点：
1、降低耦合度，提高复用维护
2、复杂了一点，降低了一点可读性。

## 二、策略模式  

例子：一个view中有很多textfield_custom，每个都需要添加输入验证合法性的方法，一般写会加很多if-else判断控件然后走对应的验证方式.  
使用策略的方式：  
1、先建一个抽象类validator，有一个之后需要重写的方法validateInput().
2、建个子类，重载父类的验证方法validateInput(). 如：EmailValidator, phoneValidator
3、textfield_custom中会添加一个属性：validator；初始化的时候这个属性赋值上对应的子类。
验证就直接调用：EmailTextfield.validator.validateInput();  

优缺点：
1、简化ifelse 代码维护性高
2、使用化之前就是确定的类型，不能动态判断  

## 三、观察者模式  

例子： KVO与通知中心 


## 四、原型/外观  

原型模式：
例子： 一个类有很多属性如student，创建对象时很多属性都是一样的，需要student1 = [student2 clone]; 然后只改一下不一样的几个属性。
1、基类实现NScopying, 里面有一个复制自己属性的函数让子类去实现。
2、这样就可以所有子类都只需要实现复制自己的函数就实现了NScopying协议。
3、深拷贝--针对数组和字典集合类的属性

外观模式：
例子：1、画圆、画正方形等每个是一个类， 
2、建立一个统一的画图类，根据传入的不同参数而输出不同的图形，
3、外观control跟内部实现画圆等类隔绝，只需要调用画图类传入参数。简化了代码和耦合


## 五、装饰  

例子：ios中提供了 category-装饰模式 
1、一旦添加了一个category 哪怕不用这个文件如果有方法重写，一样会被覆盖，这个要注意。
2、如果增加了成员或属性，要使用runtime 添加set和get方法

优缺点：
1、不改变原始类
2、不改变使用继承的情形
3、动态扩展对象的功能
4、持有对象的引用

## 六、工厂  

简单工厂   
1、简化生成流程
2、隔离生产产品的细节
3、不同类型的产品之间有着一些共同的功能
4、一个具体的工厂


抽象工厂
多了一层抽象模式，根据类型返回不同的工厂类（都继承于一个抽象工厂的基类），可以动态切换工厂
1、NSNumber
2、[NSMubmber alloc] init = 为nil
3、只有 numberWithInt 通过具体工厂才返回数据。
4、因为NSNumber保存处理的数据都是数值类型，产品是可以相互转化的，比较特殊


## 七、桥接模式
原理：
1、就是把抽象层次结构从具体的实现中分离出来，使其能够独立变更。
2、抽象层次定义了供客户端使用的上层抽象接口。
3、实现层结构定义了供抽象层使用的底层接口。实现类的引用被封装到抽象层的实例中，桥接就形成了。

例子：
1、不同游戏机模拟器


## 八、代理  

例子：   
1、
2、
3、

优缺点：
1、
2、


{'fraction_non_alphanumeric': 0.1140148603638227, 'fraction_numerical': 0.02485267742761978, 'mean_word_length': 7.48695652173913, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4655858', 'n_tokens_mistral': 3026, 'n_tokens_neox': 3500, 'n_words': 249}