Java 设计模式
简介:使用设计模式是为了代码复用、增加可维护性。
一、七个原则
1. 单一职责原则:一个类只有一个引起它变化的原因;
2. 开闭原则:对扩展开放,对修改关闭,多使用抽象类和接口;
3. 里氏替换原则:基类可以被子类替换,使用抽象类集成而不是具体类集成;
4. 依赖倒转原则:针对接口编程,不针对具体实现类编程;
5. 接口隔离原则:使用多个隔离的接口,比使用单个接口好,建立最小的接口;
6. 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用,通过中间类建立联系;
7. 合成复用原则:尽量使用合成/聚合,而不是使用继承。
二、设计模式分类
1. 结构型模式
A. 桥接模式(Bridge):将抽象和抽象操作的实现进行了解耦,这样使得抽象和实现可以独立地变化,如:JDBC;
B. 代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的访问,如java.lang.reflect.Proxy,应用见Spring AOP中JDK和CGLIB动态代理;
C. 适配器模式(Adapter):将一个类的接口转换成另外一个期望的接口,让原本不兼容的类可以合作,如:java.util.Arrays#asList();
D. 装饰器模式(Decorator):用来包装原有的类,在对使用者透明的情况下做功能的增强,如:java.io.BufferedInputStream(InputStream);
E. 外观模式(Facade):对外提供一个统一的入口,用来访问子系统中的一群接口,从而让子系统更容易使用,如:SpringMVC#DispaterServlet。
2. 创建型模式
A. 单例模式(Singleton):保证一个类仅有一个实例,并提供该实例的全局访问点,如:java.lang.Runtime#getRuntime();
B. 简单工厂模式(Simple Factory):由一个工厂对象决定创建哪一种产品类的实例,简单工厂模式适用于工厂类负责创建对象较少的情况,且客户端只需要传入工厂类的参数,对于如何创建对象不关心,如:Spring BeanFactory;
C. 工厂方法模式(Factory Method):指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行,如:Spring FactoryBean接口。
3. 行为型模式
A. 模板方法模式(Template Method):在一个方法中定义若干个抽象方法或具体方法组成一个模板算法框架,使得子类在不改变算法结构的情况下,继承后实现或重写某些方法,如:java.util.Collections#sort();
B. 责任链模式(Chain Of Responsibility):请求在一个链条上处理,链条上的受理者处理完毕之后决定是继续往后传递还是中断当前处理流程,如:javax.servlet.Filter#doFilter();
C. 策略模式(Strategy):定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换,如:javax.servlet.http.HttpServlet;
D. 观察者模式(Observer):在对象之间定义一对多的依赖,当一个对象的改变,依赖它的对象都会收到接收通知,并自动更新,如:java.util.EventListener;
三、单例模式
1. 懒汉式(线程安全)

package com.ruhuanxingyun.singleton; /** * 优点:第一次调用才实例化,避免内存浪费 * 缺点:必须加锁才能保证单例 * * @description: 懒汉式(线程安全) * @author: ruphie * @date: Create in 2020/9/17 9:28 * @company: ruhuanxingyun */ public class LockLazySingleton { private static LockLazySingleton singleton; private LockLazySingleton() { } public static synchronized LockLazySingleton getInstance() { if (singleton == null) { singleton = new LockLazySingleton(); } return singleton; } }
2. 饿汉式(线程安全)

package com.ruhuanxingyun.singleton; /** * 优点:没有加锁,执行效率会提高 * 缺点:类加载时就初始化,浪费内存 * * @description: 饿汉式(线程安全) * @author: ruphie * @date: Create in 2020/9/17 9:33 * @company: ruhuanxingyun */ public class HungrySingleton { private static final HungrySingleton SINGLETON = new HungrySingleton(); private HungrySingleton() { } public static HungrySingleton getInstance() { return SINGLETON; } }
3. 静态内部类式(线程安全)

package com.ruhuanxingyun.singleton; /** * 优点:内部类只有在外部类被调用时才加载,而且不加锁,是较好的单例模式 * * @description: 静态内部类(线程安全) * @author: ruphie * @date: Create in 2020/9/17 9:42 * @company: ruhuanxingyun */ public class StaticInnerClassSingleton { private StaticInnerClassSingleton() { } public static StaticInnerClassSingleton getInstance() { return SingletonHolder.SINGLETON; } private static class SingletonHolder { private static final StaticInnerClassSingleton SINGLETON = new StaticInnerClassSingleton(); } }
4. DCL双重校验锁式(线程安全)

package com.ruhuanxingyun.singleton; /** * @description: 双重校验锁(线程安全) * @author: ruphie * @date: Create in 2020/9/17 9:35 * @company: ruhuanxingyun */ public class DoubleCheckLockSingleton { private volatile static DoubleCheckLockSingleton singleton; private DoubleCheckLockSingleton() { } public static DoubleCheckLockSingleton getInstance() { if (singleton == null) { synchronized (DoubleCheckLockSingleton.class) { if (singleton == null) { singleton = new DoubleCheckLockSingleton(); } } } return singleton; } }
5. 枚举(线程安全)
可参考:菜鸟教程-设计模式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
2019-08-07 SpringBoot Zip打包