一、单例模式
1、简介
韦小宝有7个老婆,但是每个都只有他这一个老公,他的所有老婆叫老公时,指的都是他,他就是一个单例。
2、目的
为了确保一个类有且仅有一个实例,并为它提供一个全局访问点。
3、结构图解
4、特点
- 单例模式保证了类仅有一个实例,并为其提供了一个全局访问点。通过延迟初始化(仅在第一次使用它时才初始化),一个单例对象是达到此目的的通用做法。
- 在多线程环境下,必须小心管理线程间的协作,因为它们访问单例对象方法与数据的时间,可能只有毫厘之差。
- 对象具有唯一性,并不意味着使用了单例模式。单例模式通过隐藏构造函数,提供对象创建的唯一入口点。
- 单例模式初始化时创建对象。
- 只对外提供公共的getInstance方法,不提供任何公共构造函数。
5、代码
public class Singleton { //保证 instance 在所有线程中同步 private static volatile Singleton instance = null; private Singleton() { } //private 避免类在外部被实例化 public static synchronized Singleton getInstance() { //getInstance 方法前加同步 if (instance == null) { instance = new Singleton(); } return instance; } }
6、适用场景
适合需要做全局统一控制的场景,例如:全局唯一的编码生成器。
二、工厂模式
1、简介
小明追妹子的时候,请她喝了不少咖啡,她爱喝卡布奇诺,每次去咖啡店,只要跟服务员说“来杯卡布奇诺”就行了,虽然各家的口味有些不同,但是不管是星爸爸还是Costa,都能够提供卡布奇诺这种咖啡。这里的星爸爸和Costa就是生产咖啡的工厂。
2、目的
直接从工厂类中获取各种产品,不在需要亲自去挑选产品。
3、结构图解
4、特点
- 客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。
5、代码
用户
public class FactoryPattern { public static void main(String[] args) { // 1、创建工程类 Factory factory = new ConcreteFactoryA(); // 2、生产产品 Product product = factory.createProduct(); // 3、消费产品 product.use(); } }
产品力
//实体类产品 interface Product { public void use(); } //具体产品A:实现抽象产品中的抽象方法 class ConcreteProductA implements Product { public void use() { System.out.println("具体产品A显示..."); } }
工厂类
//抽象工厂:提供了厂品的生成方法 interface Factory { public Product createProduct(); } //具体工厂A:实现了厂品的生成方法 class ConcreteFactoryA implements Factory { @Override public Product createProduct() { System.out.println("具体工厂A生成-->具体产品A."); return new ConcreteProductA(); } }
三、装饰者模式
1、简介
大学毕业,想要送给室友一个有纪念意义的礼物,就找到一张大家的合照,在上面写上“永远的兄弟!”,然后拿去礼品店装了个相框,再包上礼盒。这里的我和礼品店都是装饰器,都没有改变照片本身,却都让照片变得更适合作为礼物送人。
2、目的
在不改变原有功能的基础下,对功能进行扩展。
3、结构图解
4、特点
- 使用不同的装饰器组合为对象扩展N个新功能,而不会影响到对象本身。
5、代码
用户
public class DecoratorPattern { public static void main(String[] args) { Component component = new ConcreteComponent(); component.operation(); System.out.println("---------------------------------"); ConcreteDecorator decorator = new ConcreteDecorator(component); decorator.operation(); } }
构建角色
//抽象构件角色 interface Component { public void operation(); } //具体构件角色 class ConcreteComponent implements Component { public ConcreteComponent() { System.out.println("创建具体构件角色"); } public void operation() { System.out.println("调用具体构件角色的方法operation()"); } }
装饰角色
class ConcreteDecorator { private Component component; public ConcreteDecorator(Component component) { this.component = component; } public void operation() { component.operation(); System.out.println("为具体构件角色增加额外的功能addBehavior()"); } }
6、使用场景
- 适合需要(通过配置,如:diamond)来动态增减对象功能的场景。
- 适合一个对象需要N种功能排列组合的场景(如果用继承,会使子类数量爆炸式增长)
四、代理模式
1、简介
淘宝店客服总是会收到非常多的重复问题,例如:有没有现货?什么时候发货?发什么快递?大量回答重复性的问题太烦了,于是就出现了小蜜机器人,他来帮客服回答那些已知的问题,当碰到小蜜无法解答的问题时,才会转到人工客服。这里的小蜜机器人就是客服的代理。
2、目的
代理用户的请求,去完整后续的各项任务。
3、结构图解
4、特点
- 代理可以协调调用方与被调用方,降低了系统的耦合度。根据代理类型和场景的不同,可以起到控制安全性、减小系统开销等作用。
5、代码
用户
public class ProxyPattern { public static void main(String[] args) { // 获取代理对象 Proxy proxy = new Proxy(); // 执行方法 proxy.request(); } }
真实主题
//真实主题 class RealSubject { // 2、真实方法 public void request() { System.out.println("访问真实主题方法..."); } }
代理类
//代理 class Proxy { private RealSubject realSubject; public void request() { realSubject = new RealSubject(); // 1、之前方法 preRequest(); // 2、真实方法 realSubject.request(); // 3、之后方法 afterRequest(); } // 1、之前方法 public void preRequest() { System.out.println("访问真实主题之前的预处理。"); } // 3、之后方法 public void afterRequest() { System.out.println("访问真实主题之后的后续处理。"); } }
五、观察者模式
1、简介
出差在外,想了解孩子在家的情况,这时候只要加入“相亲相爱一家人”群,老爸老妈会经常把孩子的照片和视频发到群里,你要做的就是作为一个观察者,刷一刷群里的信息就能够了解一切了。
2、目的
适用于一对多的的业务场景,一个对象发生变更,会触发N个对象做相应处理的场景。
3、结构图解
4、特点
- 将复杂的串行处理逻辑变为单元化的独立处理逻辑,被观察者只是按照自己的逻辑发出消息,不用关心谁来消费消息,每个观察者只处理自己关心的内容。逻辑相互隔离带来简单清爽的代码结构。
5、代码
用户
public class ObserverPattern { public static void main(String[] args) { // 1、创建目标对象 ConcreteSubject subject = new ConcreteSubject(); // 2、创建具体观察者A、B Observer obsA = new ConcreteObserverA(); Observer obsb = new ConcreteObserverB(); // 3、将具体观察者加入到目标对象中 subject.add(obsA); subject.add(obsb); // 4、调用A、B查看 subject.notifoy(); } }
具体目标
//具体目标 class ConcreteSubject { protected List<Observer> observers = new ArrayList<Observer>(); //增加观察者方法 public void add(Observer observer) { observers.add(observer); } // 调用观察者执行 public void notifoy() { System.out.println("具体目标状态发生改变..."); System.out.println("--------------"); for (Observer obs : observers) { obs.process(); } } }
观察者A、B
//抽象观察者 interface Observer { void process(); //具体的处理 } //具体观察者A class ConcreteObserverA implements Observer { public void process() { System.out.println("具体观察者A处理!"); } } //具体观察者B class ConcreteObserverB implements Observer { public void process() { System.out.println("具体观察者B处理!"); } }
六、策略模式
1、简介
男生追妹子时,一般都会用到这种模式,常见的策略有这些:约会吃饭;看电影;看演唱会;逛街;去旅行……,虽然做的事情不同,但可以相互替换,唯一的目标都是捕获妹子的芳心。
2、目的
为同一的内容,选择不同的解决方案。
3、结构图解
4、特点
- 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为。干掉复杂难看的if-else。
5、代码
用户
public class StrategyPattern { public static void main(String[] args) { // 1、创建环境类对象 Context context = new Context(); // 2.1、创建策略类A对象 Strategy strategyA = new ConcreteStrategyA(); // 3.1、将策略A添加到环境类中 context.setStrategy(strategyA); // 4.1、执行策略A方法 context.algorithm(); System.out.println("-----------------"); // 2.1、创建策略类B对象 Strategy strategyB = new ConcreteStrategyB(); // 3.1、将策略B添加到环境类中 context.setStrategy(strategyB); // 4.1、执行策略B方法 context.algorithm(); } }
策略类
//抽象策略类 interface Strategy { public void algorithm(); //策略方法 } //具体策略类A class ConcreteStrategyA implements Strategy { public void algorithm() { System.out.println("具体策略A的策略方法被访问!"); } } //具体策略类B class ConcreteStrategyB implements Strategy { public void algorithm() { System.out.println("具体策略B的策略方法被访问!"); } }
待解决问题
//环境类 class Context { private Strategy strategy; public void setStrategy(Strategy strategy) { this.strategy = strategy; } public void algorithm() { strategy.algorithm(); } }
七、Xmind整理
下载地址
https://download.csdn.net/download/weixin_44624117/12840404
百度网盘
链接:https://pan.baidu.com/s/1qAAsPktlcCPYle0yHdkoyQ 提取码:f0zv