常用设计模式随笔

常用设计模式随笔

最近在准备面试,于是乎整理了几个常用的设计模式方便“应试”,图文有来自网络的,有来自书本的,侵删。

个人感觉设计模式不常用确实容易忘记,但是看到类图的话也能说出个一二三了~

下面上点自己整理的干货吧

一、装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。
(动态的给对象增加一些额外职责,听起来是不是很像AOP呢?其实不然,在Spring中,AOP不论是通过jdk动态代理和反射机制来实现,还是cglib,还是proxyfactorybean,究其根本用的是代理模式,将增强与目标类代码“整合”到动态生成的代理类中。两者的区别在于:用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。我们可以用另外一句话来总结这些差别:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。

组件component概念为被装饰对象,装饰者decorator通过继承component获得组件的类继承,以此实现在装饰完后的对象依旧可以扮演组件角色重复装饰,此处通过接口继承或类继承来实现和保持“类”是重点。
基于接口的类图:

基于抽象类的类图也类似,只是把虚线变为实线:
在这里插入图片描述

一般来说习惯于使用抽象类来实线装饰者模式,java也可用接口获得类继承,因此java中也可使用接口

二、观察者模式(Observer):定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的多有依赖者都会收到通知并自动更新对象。
Subject为被“订阅对象”,observer为观察者,观察者在subject中注册订阅,Subject在有数据更新时通知所有在此订阅的观察者,通知后subject可主动push数据或者观察者pull数据。(Head First中举的报纸订阅例子很好理解 报社=subject 订阅者=observer)
类图:
在这里插入图片描述
三、工厂模式(factory):
1、 简单工厂模式(SimpleFactory):确切的说不是一种设计模式,而是一种编程习惯,简单工厂只是将对象的创建或加工细节转移到一个封装的类中,以此将繁琐的加工创建细节与主业务代码剥离,以后有创建加工细节变动时,只需要改动这个类即可,不会侵入业务代码,可维护性较好,实际开发中常用的工具加工类,经常可以看到简单工厂模式的身影。
2、 工厂模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到子类,使用继承的方式实现,一般用于创建同一个产品的不同类型的实例,比如说创建书本,不同类型的书有漫画书,小说,都属于书本类型。

类图: 在这里插入图片描述

3、抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,不需要明确指定具体类,换句话说,抽象工厂模式是用来创建不同类的产品,比如包子店还卖豆浆油条。
类图:
在这里插入图片描述

红色部分可以很明显的看出,抽象工厂模式也隐含了工厂模式。
具体的说,这两种设计模式主要的区别在于产品,工厂模式是用来创建同一个产品的不同类型的,但是抽象工厂模式是用来创建不同类的产品,比如包子店还卖豆浆油条。一般来说,产品种类单一,适合用工厂模式;如果有多个种类,各种类型时,通过抽象工厂模式来进行创建是很合适的。

四、单例模式:确保一个类只有一个实例,并提供一个全局访问点
几种单例模式的实现方式:
1、 饿汉模式
在这里插入图片描述
使用静态变量使jvm只拥有一个该实例对象,并且不提供任何new该对象的接口方法,但是饿汉模式对内存不友好,即不论是否使用到该对象,都为他创建好实例分配内存。
2、 懒汉模式方法级同步:
在这里插入图片描述
方法级同步可以完全解决线程安全问题,但是方法级同步,真正需要进行同步的,只有第一次执行该方法时候需要,之后每次调用该方法,同步过程都是一种累赘。会造成性能下降问题
3、 懒汉模式方法内同步(存在同步问题)
在这里插入图片描述
4、 懒汉模式双检锁模式(严格的说还有同步问题)
在这里插入图片描述
为什么说还有同步问题?因为在jvm中,给对象初始化并不是一个原子性的操作,jvm会做3件事:1、给对象分配内存 2、调用构造函数 3、将地址放还给引用。由于cpu有指令重排序的机制,首先并不能保证指令按序执行,第二因为非原子性的关系,有可能在其余线程进行单例非空判断时,当前线程的指令只执行第一步而未完成初始化,引用依旧是null,从而造成线程安全问题。
5、 懒汉模式双检锁(jdk1.4后线程安全)
在这里插入图片描述

使用volatile关键字:
1.volatile关键字可以保证指令执行的一定的“有序性”,在指令1和指令2执行完之前,指定3一定不会被执行。
为什么说是一定的"有序性"呢,因为对于非易失的读写,jvm仍然允许对volatile变量进行乱序读写

2.保证了volatile变量被修改后立刻刷新会驻内存中。

五、适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间
类图:
在这里插入图片描述
六、外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
类图:
在这里插入图片描述
外观模式和适配器模式看上去比较像,适配器模式虽然在举例时是一个适配器适配一个类,但同样的,适配器模式也可适配许多类,将许多类的方法组织包装为一个用户期望的接口进行暴露,外观模式同样可将多个类不同的方法进行组织包装暴露接口,从实现上来说两者都差不多,但是从意图来说,适配器模式的意图在于改变现有的接口,使其符合客户的期望,而外观模式的意图在于,屏蔽复杂的子系统方法(各子系统的各个方法进行复杂的组合或有执行先后顺序来达成某种目的),提供一个简化的接口,使客户代码与各子系统代码解耦。外观模式遵循一个“最少知识原则”(只和你的密友谈话,不要让太多的类耦合在一起,不要跟太多人讲秘密免去不必要的麻烦)。

持续更新。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值