浅谈常用设计模式

一、设计原则
  1. 开闭原则
    释义:对扩展开放,对修改关闭
    理解:我们平常的业务一般会不断进行迭代,一般的做法是在原流程上直接改,“开闭原则”的目的通俗的说就是不在原流程上直接改,而是在第一次写原流程时就留一些“口子”,之后的迭代在这些口子中改。
    例子:卡券核销的流程,原流程是传入卡券和用户id然后核销,现在需要在核销之前判断用户如果在黑名单则禁止核销。原流程可以这样写

    public class Moshi1 {
    
        public void hexiao(String userid, String couponNo) {
            beforehexiao(userid);
            consume(couponNo);
        }
    
        // 核销之前
        public void beforehexiao(String userid) {
        }
    
        // 核销
        public void consume(String couponNo) {
           //核销业务
        }
    }
    

    beforehexiao()是为未来可能的迭代留的口子,之后可以继承重写beforehexiao()这个方法来实现黑名单验证。事实上,很少有人会像上面例子那样写代码,原因是大部分业务都是比较稳定的业务,很少有变化。
    总结:开闭原则就是不在原有的流程上修改,而是在最初设计的“口子”上做业务迭代

  2. 依赖倒置
    释义:依赖抽象而不是依赖具体对象
    理解:依赖常见的有聚合、方法依赖等;倒置是指抽象(接口和抽象类)和抽象的实现对象。依赖对象属于正置(对象才真正实现了功能),依赖抽象属于倒置
    例子:mvc中service依赖mybatis的mapper接口

  3. 单一职责
    释义:一个类只干“一件事“,实现类要单一
    理解:感觉有两层含义,第一层是:一件事,并不是只有一个方法,像卡券从领取、赠送,核销、删除虽然是四个方法,但都是处理卡券所以应该写在一个类里;第二层是:没有逻辑内聚,就是领取、赠送,核销、删除写在一个方法里,然后通过控制变量来选择走那个流程。
    总结:向我们平常写的controller,都会把相同的业务写在一起,方便寻找和修改

  4. 迪米特法则
    释义:不该知道的不要知道,一个类应该保持对其它对象最少的了解,降低耦合度
    理解:就是不直接依赖对象,感觉依赖倒置也是其中一种,另一种是在依赖对象间创建一个对象来间接依赖。 如下图2
    总结:无论是依赖抽象还是依赖间接对象,目的就是让依赖对象改变时不会影响被依赖对象

依赖
模块A
模块B
依赖
依赖
模块A
间接对象
模块B
  1. 里氏替换原则
    释义:不要破坏继承体系,子类重写方法功能发生改变,不应该影响父类方法的含义
    理解:抽象类和接口定义方法的功能,子类实现方法,但是不能跑破坏父类的定义。比如父类定义的是加法,可你实现却用乘法,这会带来灾难。
二、分类
  1. 按作用可以分为如下两类
    • 提升灵活性:让对象可以独立变化,不会影响其他对象
      这类设计模式有:代理模式、装饰模式、桥模式、组合模式、解释器、观察者、状态模式、命令模式、责任链、策略模式、模板方法、享元模式、备忘录、访问者
    • 降低复杂度:对象的方法或构造过程很复杂,通过另一个对象来屏蔽对外的复杂性。
      这类设计模式有:建造者模式、工厂、抽象工厂、外观、适配器模式、迭代器、中介者、原型模式、单例模式
三、结构相似的模式
  1. 依赖抽象
    桥模式、访问者、观察者、策略模式
    • 桥模式、观察者、策略模式一般是聚合依赖,访问者一般是方法依赖
    • 甚至可以说,桥模式是访问者、观察者、策略模式的基础。
    • 访问者主要用于对象集遍历;观察者主要用于与主流程无直接关联的流程调用;策略模式用于处理主流程中易变部分,是主流程的一部分。
  2. 通过间接对象处理构建
    工厂、抽象工厂、建造者
    • 工厂、抽象工厂构造的对象是固定的(属性),是编译时就可以确定的
    • 建造者构造对象是动态的,根据不同条件会有不同结果(属性)
  3. 继承的方式
    适配器、模板方法
    • 模板方法和策略模式的使用场景类似,区别是,他是用继承的方式处理主流程中易变部分
    • 适配器用于两个体系的连接,一个框架会通过适配器调用另一个框架
  4. 将目标和处理目标的方法封装在一起
    解释器、状态模式、命令模式
    • 解释器用于语法的解释,日常开发应该很难用到;
    • 状态模式,用于状态的处理,像订单会有很多种状态,每种状态都会有不同的处理,且状态间是有序的,相互关联的;
    • 命令模式,用于一些特定情景的处理,每个命令是相互独立的,没有关联的。
  5. 都会创建一个间接对象来包裹被调用对象
    装饰模式、代理模式、外观、中介者
    • 装饰模式,一般是增强原有的功能,会依赖原有功能;
    • 代理模式,并不依赖原有功能,一般是对原有功能进行访问控制拦截;
    • 外观,将原先复杂的调用细节抽取出来,提供一个简单的对外接口,像我们平时会把很长的方法一部分抽取到一个单独方法中,这就是一种外观模式;
    • 中介者,可以认为是外观的升级版,处理更复杂的调用关系。
  6. 多个有序对象组合在一起
    组合模式和责任链
    • 组合模式一般在构造上下级菜单时有所应用
    • 责任链,日常开发中很少应用
四、使用情景相似的模式
  1. 处理主流程中变化部分
    策略模式,模板方法
    • 策略模式,模板方法实现方式不同,前者用依赖,后者用继承
  2. 调用多个的对象
    观察者、责任链
    • 观察者是无序的,相互间没有影响的;责任链是有序的,相互间是有影响的,责任链就像流水线一样,前一个人的处理会影响的下一个人。
    • 观察者依赖其他流程,观察者随着其他流程的进行而进行;责任链不依赖其他流程。
五、常用的设计模式
  1. 桥模式
    这应该是最常见的了,mvc模型就是
  2. 代理模式
    spring aop,事务 使用的是动态代理,我们日常开发应该很少用
  3. 命令模式
    使用java8 的话可能会常用,比如这种Map<String,Consumer> ,把目标和处理目标的方法封装在一起(map中)
  4. 责任链
    servlet 过滤器,spring拦截器
  5. 访问者
    sax 方式xml遍历
  6. 工厂
    spring工厂
  7. 外观
    这个也很常见,像将一个长方法部分抽取到几个方法中就是。
  8. 迭代器
    集合的迭代器
  9. 原型模式、单例模式
    spring 的
  10. 策略模式、模板方法
    这两个如果稍微的思考和设计一下我们的代码,能应用的地方应该很多
六、总结

23种设计模式是对遵循了设计原则的好的代码的总结,并不需要刻板的照搬结构,只要你遵循了设计原则,很可能会写出第24种设计模式。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值