设计模式分为三大类
创造型模式:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式
结构型模式:适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式
行为型模式:策略模式,模板方法模式,观察者模式,迭代子模式,责任链模式,命令模式,备忘录模式,状态模式,访问者模式,中介者模式,解释器模式
其实还有两类,并发型模式和线程池模式
单例模式
比较简单常用的模式,在当前内存中只有一个实例,
因为每次new一次类,都会分配内存空间,单例模式是将实例化对象放在静态属性中,静态调用返回,静态数据会放在常驻内存中,不会每次new,
饿汉模式:直接在静态变量上new 不管此类用不用
懒汉模式:在静态方法中调用,访问静态方法才会new
线程安全的懒汉模式:多线程可能会new多个对象,用synchronized关键字,多线程资源同步性,保证被他修饰的方法或代码,在任意时刻只有一个线程执行
DCL双剑车锁机制:就是先判断是否已经实例化,进到下一步再用synchronized关键字判断,双检查
工厂模式
将多个类进行汇总,集中在一个类中实例化返回,这个类就是工厂类,多个一个封装,通过传入参数,返回需要的实例化类,统一管理控制,switch 干的活
简单工厂 :不属于23中模式 ,就是封装汇总
统一访问一个工厂类,掺入需要实例化的类,switvh 判断,返回对象
工厂方法模式:
将工厂类变为一个抽象类,定义一个抽象方法,子类继承实现,根据不同的类,返回不同的实例化,
去掉了switch 实现推迟到子类,返回对象,
抽象工厂模式:
抽象工厂模式跟工厂方法模式相比,都是抽象类,子类实现,返回对象,不过不同的是抽象工厂返回的不是一个抽象方法,而是多个,每个子类需要实现多个方法
注册模式
也叫对象管理,在单例基础上进行了扩展,将单例对象保存在一个数组中,需要的时候直接获取就行
一个注册类,将单例对象存储在类中,添加删除,获取,统一管理
这样的好处是在程序中有条不稳的存放管理对象,肯定有一个存,一个取,取得时候发现没有就初始化,存起来,以后就直接用了,跟redis缓存一个道理
适配器模式
将不同名字的方法,加个外套,封装成统一的名字,对外统一调用,不修改返回,跟内部结构
电源适配器,三孔变两孔,
将一个接口转换成另外的一个接口,不改变内部结构,只是改变名称,统一名称
装饰器模式
扩展,在不改变现有类结构的情况加,增加新的功能,作为现有的类的一个包装
创建一个装饰类,用来包装原有的类,并在保持类方法签名完整性的全体下,提供了额外的功能
调用装饰类,增加功能,装饰类方法内部最终调用原方法
代理模式
隐藏真正的操作类,定义代理类,返回操作对象,起到控制访问的作用,
享元模式
运用共享技术有效的支持大量细粒度的对象
一般池技术就是享元模式的重要实现方式,string常量池,数据库连接池,缓冲池等,
分享元素的意思,跟注册当时的意思差不多,注册到一个容器中,这个是保存在享元工厂中,有就返回,没有就实例化然后返回
有对象的外部状态跟内部状态,内部状态时确定这个类的,共享,不能修改,外部状态就是参数,不共享能修改
比如下围棋,黑白只需要实例化一次,通过内部状态确定是黑还是白,之后就不用实例化了,直接根据内部状态(黑白)返会之前存的对象,外部状态就是落子位置,操作
观察者模式
在观察的主体发生改变时,坐出对应的动作
定义对象间的一对多的关系,一个对象发生改变,对应的多个观察者随之修改状态,
每个观察者都有更新状态的操作,绑定观察者,主体关系,休提修改,调用观察者方法,修改状态
发布订阅模式
跟观察者模式类似,都是一对多的关系,一个改变,其他依次改变,
订阅模式,是把订阅的事件注册到调度中心类,主体改变时,通知调度中心,调度中心操作订阅者,调用处理订阅者处理类
策略模式
定义一系列的算法,封装起来,可以互相替换使用
跟简单工厂类似,不过工厂返回对象,策略直接执行方法,
迭代器模式
其实就是对一个数组,对象,进行遍历,foreach的工作
定义游标指针,依次指向下一个,返回当前指针对象的数据
while判断,循环遍历全部元素
建造者模式
将一个复杂对象的构建与他的表示分来,使得同样的建造过程可以构建不同的表示
保证流程不会改变,不会增加或者遗漏,
比如:
盖房子,流程一样,但是房子不同
餐厅取餐,肉菜,素菜,主食,饮料,水果,流程时候一样的,但是结果不同,就是实例化不同
创建一个产品,
创建一个接口,
实例化接口,实例化接口中调用产品类的方法,返回产品实例,(可以实例化多个类)
然后建一个创造者类,调用实例化接口,按照顺序执行实例化接口的方法,返回实例化对象
原型模式
克隆,将实例化后的对象克隆下来,节省了实例化,构造函数等流程,节省资源
使用clone 关键字就可以克隆对象,__clone 模式方法是克隆时候触发的
浅拷贝:直接拷贝一份,原型内的实例化对象指向的内存空间跟,拷贝后的对象指向空间一致,一旦对象改变,原型也会改变
深拷贝:拷贝之后,实例化对象内的指向空间不一致,个改个的
外观模式
又称为门面模式,
子接口太多,操作类太乱,将子接口封装在一起,对外提供一个总接口,操作类直接调用总接口就可以
模板方法模式
模板方法模式,是日常容易用到的模式之一,是对继承最好的诠释,当子类中有重复的动作的时候,将他们提取出来,放在父类中进行统一的出路,
比如下楼,吃饭,回家,睡觉,中间吃饭不固定,不知道吃什么,其他都是固定的,将除了吃饭,其他的放在父类中,吃饭在继承的子类中实现,调用父类的方法返回整个流程
桥接模式
将抽象部分与实现部分分离,各自都可以独立变化
继承的话,实现类修改的话,抽象子类也会有影响
使用组合聚合的方法共享一些能用的方法,php的trait
实现类自己独立的类,抽象接口引入实现类,赋值给一个变量,自己子类使用一些实现类的方法又可以独立变化
组合模式
将对象组合成树形结构以表示“部分-整体”的层次结构,composite使得用户对单个对象和组合对象的使用具有一致性,
说白了就是用对象组成一个树形结构,用户在操作的时候不用在意对象是单一的,还是多个对象,只用一个操作就可以,剩余的交给组合模式的属性结构来解决
实例 比如说发送短信,定义很多组,需要给固定的组,以及组员发送短信,就可以用组合模式,定义好关系,发送短息,只用一个组长,发送,组员(子节点)也会发送
责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象练成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止,
中间件就是这个的实现,请求过来,执行中间件,再执行别的,
定义好几个接受处理类,类里面定义好下一级处理类,实例化后,传入,绑定责任链,执行首个,会依次执行全部,最终一定要有返回,每个处理都可终止,修改信息,或者跳过
责任链对处理进行层层过滤处理
命令模式
举个例子:
饭店吃饭,顾客是命令的下达者,服务员是命令的接收者,菜单是整个命令,厨师是命令的执行者
这个模式解决了,修改菜单命令的时候,只需要跟服务员说就行了,实现了顾客厨师的解耦,可以实现一个命令接收者,多个命令,(下单,拿酒,上菜),或者把一条命令转达给多个执行者(热菜,凉菜)这个才是命令模式的发挥作用的地方
创建执行者,放入命令列表,接收者调用命令 就ok了
备忘录模式
就是备份,存档,将对象某一时刻备份下来,然后需要的话,还原,管理类可以存储多个备份
git svn 备份,都是备忘录模式的体现
状态模式
通过一个状态改变当前类的对象,使之成为另一个对象,执行另一个对象的方法
通过一个状态,修改对象的抽象类,对象包含抽象类的方法,可以根据状态修改引入类,再执行新的引入类的方法,方法中可以调用对象的修改方法,一直循环下去,知道出现最终结果,
将对象的状态变化封装到外部的实现类中去,需要状态经常修改,例如订单,OA,会员,等等
比如订单,未支付的时候,传入未支付的类,会执行未支付的下一步动作,已支付的会执行已支付的下一步动作
实现A传入目标类,执行的方法是实现A的方法,
实现B传入目标类,执行的方法是实现B的方法,
根据传入的类,修改状态,对象,执行不同的下一步方法
中介者模式
这个就真的式中介了,你租房,他出租,中介在两边调节,
代理类只是返回一个类,用于代理控制,而不是交互
中介类处理两个交互类的关系,互相调用需要交互的对象的方法,而对象只需要调用中介提供的接口就可以
访问者模式
表示一个作用于某对象结构中的各元素的操作,它是你可以在不改变个元素的类的前提下定义作用于这些元素的新操作
适用于对象结构很少改变的类,比如,男 女 ,收入 支出,
访问类跟对象结构类,互相调用,互相传入,
结构类中传入访问类对象,调用访问类的方法,回传本身结构类,互相调用,访问者可以多个
会有一个控制器类,将访问者添加进去,循环结构类,传入访问者类,执行方法
管道模式
管道模式也叫流水线模式,是责任链模式的一种对于管道模式来说,有三个对象,管道,载荷,过滤器(阀门)
再管道种对附载进行一系列的处理,因为可以对过滤器进行动态添加,所以对负载的处理可以变得更加灵活
定义许多操作(过滤器)添加到管理器(管道) 将数据(载荷)添加到管理器种,执行管理器的方法,管理器会执行添加到其中的过滤器