设计模式总结一

设计模式中的设计原则:

1,单一职责原则

2,开闭原则:对扩展开放,对修改关闭,也即面对需求,对程序的改动是通过增加代码而不是改变原来代码

3,里氏替换原则:子类可以替换父类,程序不会出现错误

4,依赖倒置原则:底层模块依赖于上层模块,细节依赖于抽象

5,接口隔离原则:接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。

6,迪米特法则:类与类之间能不交互就不交互,将类与类之间的耦合减少到极致

7,合成(组合/聚合)复用原则:尽量使用对象组合而不是使用继承来达到复用的目的,通过组合聚合的方式可以减少类与类之间的耦合,其次才考虑继承,不要乱用继承,否则难以维护,这里的主要原因是破坏了封装性,由于继承子类拿到了父类的方法,暴露了细节,然而通过组合的方式将已有的对象放入到新对象中,内部细节不可见


合成复用原则案例:

写一个DBMySql类定义一个方法来连接MySql数据库,用户Customer类继承DBMySql,通过调用父类的方法来连接数据库,但是如果是MySql数据库改成了Oracle数据库,那么要把Customer类继承DBMySql改成继承DBOracle那么就违背了开闭原则

正确做法是:将连接DBMySql还是DBOracle类名放到配置文件中,读取配置文件时才反射生成对象,原来Customer类继承改成调用某个类方法


状态模式:

比如一个游戏人物有多个状态,行走,跑步,射击,蹲下,刚开始学习的时候会用一个枚举类型保存所有状态,然后设置一个标志位,然后一个switch来判断,这样的缺点是,万一要添加一个状态,就要修改原来代码,可以使用状态模式,一个状态为一个状态类,

我们创建一个context类,一个state类,让不同状态继承state类,context创建一个setState方法,形参是state,实参是new出state子类,在方法中得到子类对象,创建另一个方法调用state的抽象方法即可执行子类State方法

这里注意的是,在每个子类state中需要状态切换,那么需要调用Context类里面的方法来切换,所以每个子类中的构造函数里面传入参数context,this.context=context; 来指明是哪个类

但是这种设计模式缺点是新增加类会修改状态转换的源代码,不符合开闭原则


比如游戏logo界面跳转到游戏主界面,在跳转到战斗场景,跳转到游戏主界面,此时就可以用状态模式进行切换


外观模式:


中间添加一个服务员可以方便的管理不同人对于开水,茶具,茶叶的调度,减少耦合


中介者模式:

对于多对多进行通信的类,还有中介者模式,和外观模式十分类似,区别是


桥接模式:

对于球体sphere类和立方体cube类,要想调用OpenGL类的渲染方法,首先sphere类拿到OpenGL类的引用,然后创建一个方法,调用引用.方法名来实现。但是如果增加了一个directx类调用它的渲染方法,在spherecube类中先拿到directx的引用,然后再增加一个方法,通过引用.方法名来实现,这样的话每增加一个渲染类每个类都要修改

重构后:sphere类和cube类抽象并继承一个Ishape类,OpenGLdirectx抽象出并继承一个IRenderEngine类,调用的话是IShape类调用IRenderEngine

Ishape中在构造方法中传入IRenderEngine并用引用保存,创建一个方法实现引用.方法名


在客户端调用时候渲染器类用多态new出来,作为参数放到Ishape子类的构造函数中



模板模式:

多个子类大部分流程一样,有个别细微不一样使用模板模式


享元模式:

对相同或者相似对象共享访问,实现内存的节约,比如围棋中那么多棋子,创建那么多对象浪费内存,我们让看上去都是每一个对象,实际上它们共享同一个享元对象,存储这些共享实例对象的地方称为享元池,针对每一个不同的字符创建一个享元对象,将其放在享元池中,需要时再从享元池取出。

享元分为内部状态和外部状态,内部部分是可以共享的部分,外部是不可以共享的部分

这个模式和工厂模式配合使用,一般在工厂类,初始化方法里放一个字典,add所有类型的对象,k为类型,v为new出来的对象,对象需要做成单例,如果为空才new不为空直接得到,再创建一个方法来根据类型取得对象,我们可以把这个字典或者hashMap看做享元模式的对象池


组合模式:

用处:一般用于递归电脑中的文件,比如杀毒,d盘中包括文件或者文件夹,通过递归来遍历整个树的所有节点。这里要把树下分为文件和文件夹两种类型,文件夹里面可以继续添加节点。

在组合模式中,文件类和文件夹类都要继承一个抽象类,抽象类包括四个方法,1,operation具体操作类方法,文件和文件夹都包含此方法,2,add节点

remove节点,getChild这三个方法让文件夹类去包括。当然在文件夹类中可以写个list来保存里面的子节点

最后要遍历的时候,写一个递归函数就行


命令模式

比如防御塔一下要生产一批小兵,那么在两者之间再加上一个invoker类,防御塔把命令发送给它即可,创建一个抽象command(命令)基类,包含一个抽象execute(执行)方法,创建一个receiver(接受者)类,在ConcreteCommand (具体命令)子类中的execute方法用执行receiver的特定方法,当然创建小兵的参数在该类的构造函数中获得,execute方法来调用小兵工厂类类创建小兵,在invoker中添加executeCommand方法来执行具体命令

观察者模式:

这样记:行人观察红绿灯的变化来判断行走方向,这种一个红绿灯来改变许多人行为的模式叫观察者模式.

定义一个通知者类,定义一个观察者类,观察者类写一个update函数用于当收到通知做出改变。在通知者类中用一个ArrayList保存所有的观察者。在创建添加,删除观察者的方法,再定义一个notify方法用于遍历ArrayList中所有观察者的update方法



单例模式:

两静态私有,一返回:

new 出对象私有化,注意在类中就通过静态new出来,别放到GetInstance函数中再new出来


构造函数私有化,注意构造函数没返回值


最后通过一个方法来返回对象


1 在使用时候,由于没有抽象层,也即没有父类,因此很难扩展,所以写单例模式的时候想好要不要扩展

2 很多时候把过多任务分配给单例类违背职责单一原则








加锁消耗资源,那么就判断需要new对象的时候再加锁,但是if instance==null判断完后可能另一个线程突然new了个对象所以加锁后还得再判断一次


饿汉式:



懒汉式在程序加载的时候就静态new出了




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值