设计模式

github代码仓库:https://github.com/wanggangkun/DesignPatterns/tree/master/src/main/java/com/kun
bilibili视频链接:
https://www.bilibili.com/video/av29988660
这是我自己的代码仓库:
https://gitee.com/DP_zhouyang/DesignMode_Java

1.策略模式

2.观察者模式

3.装饰者模式

在这里插入图片描述

在这里插入图片描述
Java中的io就是装饰者模式设计的
我们如果要求读一个文件,然后把文件里的字符全部变成大写,那么可以继承FilterInputStream这个装饰者,覆写其read方法,然后在声明这个类的时候传入一个超类InputStream类型的实现类。
在这里插入图片描述
这两种调用方法都是可以的在这里插入图片描述

4.单例模式

在这里插入图片描述
在这里插入图片描述
构造函数是私有的,静态方法可以调用

但是有一个问题,如果在多线程的环境下运行,无法保证初始化实例这个过程只执行一次,如果这个实例多执行多次,那么就违背了我们单例模式的原则。

下面有三种方式可以保证单例模式的线程安全

1)用synchronized关键字或者互斥锁,保护初始化实例的临界区,但是这样有一个问题,这样的确在初始化时保证了只有一个线程进入临界区,但是实例被初始化后,每个访问实例的线程都要等待锁的调度,增大了os的压力,效果很差。

2)用懒汉模式,static关键字或者声明的时候就new这个对象,这样也有一个问题。假如我们的服务很庞大,每个单例都是采用这种模式初始化,那么项目启动时会有资源竞争问题(如磁盘io,网络的io),并且所有的单例并非能保证初始化后会被使用,这样增加了服务器的压力,并且当初始化实例这个过程很复杂的时候会出现不可预料的错误。

3)双重检测机制:推荐,结合了上面两种方法的优点,只有实例化的过程会被加锁,意味着可能有若干线程进入实例话的过程,实例话后增加一层检测机制,那么这层检测需volatile关键字来保证实例的可见效。

具体代码如下:
在这里插入图片描述

5.工厂模式

假设有这么一个场景,有一个披萨店对外提供各种披萨,制造pizza有一系列共有的流程,如烘焙,切割,包装等。最终的需求就是用户需要什么pizza,店内就提供什么样的pizza。

假如我们用这样一种方式,每次用户点什么pizza,店里就会用if-else的结构来判断这样的pizza存不存在。这样有一个问题,假设新增一种pizza或者减少一种pizza,那么除了增改的pizza代码需要变更,判断的过程也要重新设计。这样就违背了我们设计的原则:新的代码不影响原有代码。

而工厂模式就是为了解决这样一个问题:

定义了一个创建对象的类,由这个类来封装创建实例的行为。
在这里插入图片描述

5.命令模式

所有的命令抽象成命令接口,具体的调用放到serCommand里,跟插槽关联起来。使命令的请求者和执行者解耦。
在这里插入图片描述
在这里插入图片描述
假设有这样一个场景,一个室内有若干设备,各种设备有各种功能。最终我们要实现的是一个开关,按什么开关就能触发什么设备的功能。

基于命令模式,我们需要把开关的按钮和设备的执行解耦。

那么就需要一个接口Command抽象所有的命令,该接口有两个方法,一个是execute执行命令,一个是undo取消上次的命令。那么实现类就必须要在构造方法里传入一个具体的facility的类型,假如这个类是LightOnCommand,那么在execute()里就要调用light的lightOn()方法(当然,如果有其它逻辑,必须写在lightOn()方法中,不能让command来控制facility的执行逻辑)。

那么对于我们的controller来说,应该绑定执行code和command的关联。因为command已经和facility关联上了,那么执行相应的code就能执行相应的command。

现在说一个扩展性需求:我们需要一个宏指令,这个指令需要执行若干指令,那么只需要这个指令也implents Command接口,然后在构造器里传入它需要实现的具体command类,再在execute()方法里依次执行就可以了。
外层的code和command的绑定依旧不会有变动。这样就实现了执行者和命令的解耦。

6.适配器模式

有这样一种场景,去不同的国家地区旅游,需要的充电口的类型不一致,此时我们就需要引入相应的转换器来解决这个问题,而适配器模式也是为了解决这一问题:使不同的类有相同的表现形式

有类适配器和接口适配器这两种,具体的实现是在适配器里传入实现类,而适配器继承或者实现某个抽象类或者方法。这样在外部就能调用被适配类完成某些功能。

下面是枚举器到迭代器的适配过程:
在这里插入图片描述

7.外观模式

有这样一种场景,智能家居的大系统下有很多子系统,但是各个子系统未必兼容,现在我需要有一个遥控器操控多个系统的开关,而这个遥控器的设计就是外观模式的体现。

和命令模式的区别:外观模式强调的是系统对外暴露高聚合的接口,而屏蔽内层接口的实现细节。但命令模式是接口的命令化,把各种命令抽象成类,再统一组合。

最少知识原则:设计项目中不要让太多的类耦合在一起。

在这里插入图片描述
返回值是类就违背了这个原则。
那么外观模式就减少了对象间的耦合,外部系统和内部系统不会有太多类的交集。

8.模板模式

在这里插入图片描述
身边的典型模板模式:
1.排序
写好固定的遍历部分,至于对象的比较部分需要传入comparator的compare()方法来比较。
Arrays.sort()方法是传入object对象做比较的,通过比较this.val 和 obj.val来决定排序顺序。
2.Andriod
在超类中实现了若干方法步骤,抽象部分ondraw让子类自己实现。
BaseAdapter、Activity生命周期(onCreate等)

好莱坞原则:你别调用我,我来调用你。
高层无需知道调用底层的细节,解耦。

9.迭代器模式

提供一种方法顺序访问一个聚合对象中的各个对象。
在这里插入图片描述
自己实现的迭代器.
在这里插入图片描述
java内置迭代器

单一责任原则:一个类应该只有一个引起变化的原因。

10.组合模式

将对象组织成树形的部分与整体的数据结构的模式。
在这里插入图片描述
有这么一个场景,同样我是要用各种集合结构,这些结构最终都要以迭代器的形式返回。但是集合内部仍然会嵌套集合,为了解决这个问题,我们提出了组合模式。

将集合元素和子元素同样实现一个接口,它们的返回迭代器也实现同一个接口。

11.状态模式

有这么一个糖果机,某一时刻糖果机可能处于售罄,在售,已投硬币和未投硬币四种情况。
正常流程是投完硬币摇摇杆,就会出糖果。

如果按照普通设计来说,每一个动作都要去switch当前的状态,然后根据当前的状态做出下一步的动作。那么如果再增加一种状态,如出糖果可能有百分之二十的奖励,使其出两个糖果,那么按照上面的情况不仅要增加swtich里的分支,而且还有增加后续状态转变的代码,违背了我们设计好的方法封闭的思想。
在这里插入图片描述
把状态抽象化,把对象和动作绑定。
能根据内部状态的变化,改变对象的行为,看起来好像修改了类。

12.代理模式

还是接着上面的糖果机场景,现增加需求,要求增加监控器来监控所有糖果机的剩余糖果数,糖果机目前状态等信息。

如果是本地监控的话,只需要新增一个监控类,把糖果机放到这个类里就可以了。但是是远程监控,要走网络io,那么我们在此引入代理模式的方法。

在这里插入图片描述
在这里插入图片描述
代理模式:为一个对象提供一个替身,以控制对这个对象的访问。
被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象。
代理模式有很多变体,都是为了控制与管理对象访问。

JAVA RMI远程方法调用:是计算机通过网络实现对象调用的一种通讯机制。
在这里插入图片描述
RMI的四个步骤在这里插入图片描述
相当于stub里负责和远程沟通,skeleton里写上业务代码,stub代理负责转换。
与装饰者模式的区别: 装饰者模式,装饰以后会添加新功能。代理模式目的是对目标对象访问的控制和管理。

几种常见的代理模式:
1:虚拟代理。虚拟代理为创建开销大的对象提供代理服务,真正的对象在创建前和创建中,由虚拟代理来扮演替身。如Android的在线图片加载类

2:动态代理。运行时动态的创建代理类对象,并将方法调用转发到指定类。
在这里插入图片描述
控制和管理在invocationHandler中实现

动态代理的一种实现方式:

1:代理层向外提供bean对象,但这种对象只能通过代理生成,方法是私有的。
在这里插入图片描述
先生成代理类,然后所有方法由代理类生成在这里插入图片描述
实际上调用的是invoke()方法,在此处可以做权限控制
在这里插入图片描述
newProxyInstance参数含义

  • 第一个参数:代理的类加载器,必须和被代理的对象是一个类加载器
  • 第二个参数含义:代理对象要实现的那些接口
  • 第三个参数:指派方法调用的调用处理程序

动态代理的原理https://www.cnblogs.com/haitaofeiyang/p/7724263.html

3:保护代理

4:防火墙代理

5:缓存代理

6:只能引用代理

7:同步代理

8:写入时复制代理

13.复合模式

在这里插入图片描述
某些模式组合在一起,可以普世地解决一系列问题,我们称作这种模式为复合模式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

14.桥接模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
桥接模式与模板模式有点类似,它有固定不变的部分,这部分抽象成接口,自身又是抽象类,在抽象类被实例的时候传入接口的实现类,那这样类就既有了抽象类的公共方法,又有实现类的具体实现。

15.生成器模式

对复杂对象的生产。
封装一个复杂对象构造过程,并允许按步骤构造。
在这里插入图片描述
在这里插入图片描述

16.责任链模式

在这里插入图片描述
使处理的对象放在处理者中,来判断自己是否是处理者
使请求的发送者和接送者解耦
在这里插入图片描述
在这里插入图片描述

17.解释器模式

在这里插入图片描述

18.蝇量模式

对象设计的六大原则

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

在这里插入图片描述

设计模式的三个分类

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值