1.什么是设计模式?
概念:为解决特定场景下的问题而定制的解决方案
2.设计模式的基本原则
接口隔离原则:
接口里面只做必要的事情,不做其他相关的事情
需求:封装创建一个Button,但是按钮的尺寸由我自己控制
创建一个baseView
BaseView.h
#import <UIKit/UIKit.h>
@interface BaseView : UIView
/** 自定义按钮 **/
@property(nonatomic,strong)UIButton * btnPrint;
//接口隔离原则:接口里面只做必要的事情,不做其他相关的事情
-(void)changeBtnFrame:(CGRect)frame;
//违背了接口隔离原则
-(void)changeBtnFrame:(CGRect)frame backgroundColor:(UIColor *)backgroundColor;
@end
BaseView.m
#import "BaseView.h"
@implementation BaseView
//接口隔离原则:接口里面只做必要的事情,不做其他相关的事情
-(void)changeBtnFrame:(CGRect)frame{
self.btnPrint = [[UIButton alloc]initWithFrame:frame];
[self.btnPrint setTitle:@"print" forState:UIControlStateNormal];
[self.btnPrint setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];
[self.btnPrint setBackgroundColor:[UIColor redColor]];
[self.btnPrint addTarget:self action:@selector(onPrintClicks) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.btnPrint];
}
-(void)onPrintClicks{
NSLog(@"采集打印的事件");
}
//抛开接口隔离原则不谈:抽象方法(声明了这个方法,但是不实现)
-(void)changeBtnFrame:(CGRect)frame backgroundColor:(UIColor *)backgroundColor{
}
@end
开闭原则:
对模块拓展开放,对修改关闭。.m文件实现代码不改变。
是比较理想的状态,在实际开发中很难去遵守。
需求:封装创建一个Button,但是按钮的尺寸由我自己控制
增加需求:不但能自己控制尺寸,还要能修改title
根据需求的增加,我们肯定不能在baseView上面新增功能,因为这样就违背了接口隔离原则了,那么我们怎么办呢?
创建一个firstView,继承自baseView
FirstView.h文件
#import "BaseView.h"
@interface FirstView : BaseView
/** 添加字符串 **/
@property(nonatomic,copy)NSString * string;
/* 设置按钮的文字 */
-(void)changeBtnFrame:(CGRect)frame title:(NSString *)title;
@end
里氏替换原则:
1.子类可以实现父类的抽象方法但不能覆盖父类的非抽象方法
2.子类可以增加自己特有的方法
跟多肽类似,多肽:重写父类的方法
里氏替换原则要求父类提供尽可能多的接口,尽可能把所有的情况都考虑到,这个原则是和接口隔离原则想背离的,不可能完全满足里氏替换原则和接口隔离原则。这就尴尬了。。。
我们修改baseView,把firstView中的方法,放到baseView中,忽略firstView
需求更改为:封装创建一个Button,但是按钮的尺寸由我自己控制,能修改title,修改backgroundColor
BaseView.h
#import <UIKit/UIKit.h>
@interface BaseView : UIView
/** 自定义按钮 **/
@property(nonatomic,strong)UIButton * btnPrint;
//接口隔离原则:接口里面只做必要的事情,不做其他相关的事情
-(void)changeBtnFrame:(CGRect)frame;
//违背了接口隔离原则
-(void)changeBtnFrame:(CGRect)frame backgroundColor:(UIColor *)backgroundColor;
/* 设置按钮的文字 这是原来在firstView中定义的方法*/
-(void)changeBtnFrame:(CGRect)frame title:(NSString *)title;
@end
创建一个secondView,继承自baseView
secondView.h
#import "BaseView.h"
@interface SecondView : BaseView
@end
secondView.m
#import "SecondView.h"
@implementation SecondView
-(void)changeBtnFrame:(CGRect)frame backgroundColor:(UIColor *)backgroundColor{
}
-(void)changeBtnFrame:(CGRect)frame title:(NSString *)title{
self.btnPrint = [[UIButton alloc]initWithFrame:frame];
[self.btnPrint setTitle:title forState:UIControlStateNormal];
[self.btnPrint setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];
[self.btnPrint setBackgroundColor:[UIColor redColor]];
[self.btnPrint addTarget:self action:@selector(onPrintClicks) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.btnPrint];
}
//依赖倒转原则
-(void)onPrintClicks{
[self printString];
}
-(void)printString{
NSLog(@"这里实现了打印文字的需求");
}
@end
这样就遵循了里氏替换原则,注意和多肽是有区别的:
里氏替换原则:尽量不要重写父类本身实现的逻辑。
依赖倒转原则:
抽象不依赖于细节,细节依赖于抽象(一般指的是接口)
//依赖倒转原则
-(void)onPrintClicks{
[self printString];
}
-(void)printString{
NSLog(@"这里实现了打印文字的需求");
}
合成/聚合复用原则
需要从一个类拓展出另外一种方法,尽量不要使用继承,使用新的方法
新建继承自UIView的ButtonView
ButtonView.h文件
#import <UIKit/UIKit.h>
//#import "BaseView.h"
#import "SecondView.h"
@interface ButtonView : UIView
/** 设置属性 **/
@property(nonatomic,strong)SecondView * secondView;
//设置按钮的图片
-(void)changeBtnFrame:(CGRect)frame backgroundImage:(UIImage *)image;
@end
ButtonView.m
#import "ButtonView.h"
@implementation ButtonView
-(void)changeBtnFrame:(CGRect)frame backgroundImage:(UIImage *)image{
//编写secondView的相关代码
}
@end
最小知识原则:
两个类没有彼此直接通信,而是使用另一个类来通信
单一职责原则:
一个类只负责一个功能领域(例子:一个登陆的model,只负责登陆模块的数据)
3.设计模式的类型
1.GOF设计模式
2.结构型设计模式
3.框架级别的行为型设计模式
23种设计模式的分类
1.创建型模式:5种
包含:单例模式,抽象工厂模式,建造者模式,原型模式,工厂模式
2.结构型设计模式:7种
包含:代理模式,组合模式,桥接模式,享元模式,外观模式,装饰模式,适配器模式
3.框架级别的行为型设计模式:11种
包含:观察者模式,访问者模式,中介者模式,解释器模式,策略模式,迭代器模式,命令模式,状态模式,备忘录模式,模板方法模式,责任链模式
由很多设计模式构成的复合型设计模式