确保一个类只有一个实例,并提供全局访问点
single
- 是双重锁定,通过同步synchronzed确保多线程下只被一个线程执行,并在在同步前后判空,确保不会重复实例化该类。
- voliatile确保执行的顺序不会改变。jvm会对代码进行优化,当执行顺序是这样就会出现问题。1、分配内存-->2、把内存的引用赋值给instance-->3、再把实例化的对象初始化到该内存下。(事实不一定这样,可以当一个场景)
当线程A把2执行完,线程B判断instance是否为空,发现不为空,调用方法,这时就报nullpointException
static模式
- 有人说这是饿汉模式,服务一启动就加载。
enum
- 枚举模式,好处:防止反射、反编译、返序列化、确保加载一个。在枚举初始化的时候实例化
单例模式减少重复创建,节省空间,加载速度更快,节省时间。单例模式是无状态的
将请求封装成对象,这可以让你使用不同的请求、队列,或者日志请求 来参数化其他对象。命令模式可以支持撤销操作
比如我有个遥控,只有三个按钮,打开、关闭、退回。然后我可以控制所有的电器。譬如,空调、电视、电扇、电脑、手机、冰箱、热水器等等。
但我在网上看到的例子是,client、commond、invoke、receiver,一点都不生动
- 调用者与被调用者完全解耦
- 命令的扩展性比较好
- 命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题。
- 如果有大量命令,拿需要创建这么多命令
我刚开始觉得调用者(invoke)特别多余,直接调用命令就行,何必再加一层。
后来想了想,调用者可以做一些额外的操作。譬如日志、权限等等。
提供一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子类系统更容易使用优势
我们要开启一台电脑,需要哪些操作。首先接通电源、开启cpu、开启内存条、开启风扇、开启硬盘、开启显示屏、开启显卡等等。
但实际我们只需要点击电脑开关,就直接开机。电脑自己把这些元件都打开了。这就是外观模式
- 松散耦合
使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护;
- 简单易用
客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成, 它只需要跟Facade类交互即可。
- 更好的划分访问层次
有些方法是对系统外的,有些方法是系统内部相互交互的使用的。 子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用, 很好的隐藏了子系统内部的细节。
工厂方法模式: 定义了一个创建对象的接口, 但由于子类决定要实例化的类是哪一个。工厂方法 让类把实例化推迟到子类
以pizza店说明,有两个pizz store,然后都本地化,有各自特色的pizza。但pizza的流程是一样的,只是具体的细节有区别。
- 工厂模式可将这些创建对象的代码用栅栏围起来,就像你把所有的羊毛堆到眼前 一样,一旦围起来后,就可以保护这些创建对象的代码,如果让创建对象的代码 导出乱跑,就无法收集了。譬如要修改,就比较麻烦了 - 倒置原则--依赖抽象,不要依赖具体的类
- 简单工厂于工厂模式的区别: 一个简单工厂不能变更正在创建的产品。这个例子不错:https://blog.csdn.net/abc709272013/article/details/52654266
- 工厂模式
工厂模式的好处就是把创建对象封装起来,减少对具体
抽象工厂模式: 提供一个接口,用于创建相关或依赖对象的家族,而不需要 明确指定具体类
一个pizza店,需要各种原料。每个pizza的原料种类相同,但口味不一样。比如甜的奶酪 咸的奶酪,纯牛奶和酸牛奶,热的和冷的。那就需要给每个pizza创建唯一的原料工厂。
工厂模式是创建不同的对象,而抽象工厂更大,创建不同的一群对象。而且抽象工厂创建的对象是确定的。
在一个方法中定义一个算法的骨架, 而将一些步骤延迟到子类中, 模板方法使得子类可以在不改变算法结构的情况下, 重新定义算法中的某些步骤。
比如做馒头和包子,都需要准备,揉面,蒸煮, 这三个步骤,且顺序是固定的。这个就可以用模板方法来做
策略模式: 定义了算法族,分别封装起来,让它们之间可以相互替换
- 此模式让算法的变化独立于使用算法的客户
- 多用组合,少用继承
- 这个算法很常见,一个接口不同的实现就是策略模式啊
动态地将责任附加到对象上。若要扩展功能,装饰者提供了 比继承更有弹性的替代方案或者 可以这样说包装对象
- CondimentDecorator继承Beverage,这是利用继承达到“类型匹配” 而不是继承获得“行为”
- 对扩展开放,对修改关闭
- 当一个对象依赖特定的类型,然后忽然导入,导致错误。插入装饰者必须小心谨慎
- 增加代码复杂度,使用者不知道到底导入了多少个装饰着
- 装饰者导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂
数据流
父类:InputStream
装饰类:FilterInputStream
装饰者:BufferedInputStream, CheckedInputStream, CipherInputStream,DataInputStream, DeflaterInputStream, DigestInputStream,InflaterInputStream, LineNumberInputStream, ProgressMonitorInputStream,PushbackInputStream
被装饰者:AudioInputStream, ByteArrayInputStream, FileInputStream,FilterInputStream,ObjectInputStream, PipedInputStream, SequenceInputStream,StringBufferInputStream
共享session的一个例子,
request,HttpServletRequestWrapper就是HttpservletRequest的装饰类。而httpserverletReuest是接口,具体的对象还在tomcat里。
- HttpServletRequestWrapper是装饰类,那这个类的作用是什么?
- 为何不直接继承具体类,这样更简单。
- 因为具体类有多个时,我们就需要进行解耦
在对象之间定义一对多的依赖,这样依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
天气展示栏,当天气有改变时,通知展示栏
首先把多个展示栏注册到天气处理中心,当天气改变时,就遍历一个一个通知。
Subject、Observer、DisplayElement是接口
Subject 是一个对象,代表一种类型
Observer 是观察者,update方法
DisplayElement 是展示栏
使用的就是java.util的observer。具体流程,每次请求封装session,请求结束后,判断session有没有改变,改变就更新redis的数据。
场景说明:当用户做完一个操作后,我们需要发邮件通知。如果一个个通知就太麻烦,这时可以用事件监听。
示例:https://blog.csdn.net/erbao_2014/article/details/68924231?locationNum=9&fps=1
要素:
- 事件
- 监听
- 事件发布者
- 发生的事
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间
比如服务提供一个接口是json格式,而需要的是String格式的。
再比如,业务需要一个接口有用户信息和部门节点的,而提供接口并没有。就需要开发一个接口,把用户信息接口与部门节点接口聚合