一文搞懂常用设计模式:提升代码架构的必备指南

[复制链接]
发表于 2025-5-7 17:22:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
引言

在软件开发领域,设计模式是开发者们用来构建高效、可维护和可扩展代码的有力工具。只管设计模式种类繁多,但此中一些模式在一样平常开发中频繁使用,它们能解决各种常见问题,从对象创建到布局组织,再到行为交互。把握这些常用设计模式,如同拥有一套万能钥匙,能帮助我们轻松应对软件开发过程中的诸多挑衅。接下来,让我们深入探讨这些常用设计模式的原理与应用。
单例模式(Singleton Pattern)

模式界说与原理

确保一个类仅有一个实例,并提供一个全局访问点。其核心原理是通过将构造函数私有化,阻止外部直接实例化,同时提供一个静态方法来获取唯一的实例。
实现方式

饿汉式

  1. public class Singleton {
  2.     // 在类加载时就创建唯一实例
  3.     private static final Singleton instance = new Singleton();
  4.     // 私有构造函数,防止外部实例化
  5.     private Singleton() {}
  6.     // 提供全局访问该实例的方法
  7.     public static Singleton getInstance() {
  8.         return instance;
  9.     }
  10. }
复制代码
这种方式简单直接,类加载时实例就已创建,自然线程安全,但大概造成资源浪费,如果实例不停未被使用。
懒汉式(线程安全

  1. public class Singleton {
  2.     // 声明实例,但延迟初始化
  3.     private static volatile Singleton instance;
  4.     // 私有构造函数,防止外部实例化
  5.     private Singleton() {}
  6.     // 提供全局访问该实例的方法,采用双重检查锁确保线程安全
  7.     public static Singleton getInstance() {
  8.         if (instance == null) {
  9.             synchronized (Singleton.class) {
  10.                 if (instance == null) {
  11.                     instance = new Singleton();
  12.                 }
  13.             }
  14.         }
  15.         return instance;
  16.     }
  17. }
复制代码
懒汉式实现了延迟加载,只有在第一次使用时才创建实例。双重检查锁机制包管了在多线程环境下的线程安全性,同时制止了不必要的同步开销。
应用场景

实用于资源管理器类型的场景,如数据库连接池、日志日志记载器等。以数据库连接池为例,多个模块大概都必要获取数据库连接,如果每个模块都创建自己的连接池实例,会造成资源浪费和管理混乱。使用单例模式,整个应用步伐只有一个数据库连接池实例,既节省资源又便于统一管理。
工厂模式(Factory Pattern)

模式界说与原理

将对象的创建和使用分离,通过一个工厂类来负责创建对象。它基于一个抽象的创建接口,由详细的工厂子类决定创建何种详细对象。如许,当必要创建新的对象类型时,只需在工厂类中添加相应的创建逻辑,而无需修改大量的客户端代码,提高了代码的可维护性和可扩展性。
工厂方法模式示例

  1. // 产品接口,定义产品的通用行为
  2. interface Product {
  3.     void use();
  4. }
  5. // 具体产品A,实现产品接口
  6. class ProductA implements Product {
  7.     @Override
  8.     public void use() {
  9.         System.out.println("使用产品A");
  10.     }
  11. }
  12. // 抽象工厂类,定义创建产品的抽象方法
  13. abstract class Factory {
  14.     // 抽象方法,由子类实现具体的产品创建逻辑
  15.     abstract Product createProduct();
  16. }
  17. // 具体工厂A,继承抽象工厂类并实现创建产品A的逻辑
  18. class ConcreteFactoryA extends Factory {
  19.     @Override
  20.     Product createProduct() {
  21.         return new ProductA();
  22.     }
  23. }
复制代码
在客户端代码中:
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         Factory factory = new ConcreteFactoryA();
  4.         Product product = factory.createProduct();
  5.         product.use();
  6.     }
  7. }
复制代码
应用场景

在电商体系中,不同类型商品的创建可以使用工厂模式。比方,创建实体商品和虚拟商品,它们的创建过程大概涉及不同的初始化操作,通过工厂模式可以将这些复杂的创建逻辑封装在工厂类中,客户端只需调用工厂方法获取商品实例,无需关心详细的创建细节。
署理模式(Proxy Pattern)

模式界说与原理

为其他对象提供一种署理以控制对这个对象的访问。署理对象与真实对象实现相同的接口,客户端通过署理对象访问真实对象,署理对象可以在调用真实对象的方法前后添加额外的逻辑,如权限验证、日志日志记载等。
示例代码

  1. // 主题接口,定义真实主题和代理主题的共同接口
  2. interface Subject {
  3.     void request();
  4. }
  5. // 真实主题类,实现主题接口
  6. class RealSubject implements Subject {
  7.     @Override
  8.     public void request() {
  9.         System.out.println("真实主题执行请求");
  10.     }
  11. }
  12. // 代理类,持有真实主题的引用,并实现主题接口
  13. class Proxy implements Subject {
  14.     private RealSubject realSubject;
  15.     // 构造函数,传入真实主题对象
  16.     public Proxy(RealSubject realSubject) {
  17.         this.realSubject = realSubject;
  18.     }
  19.     @Override
  20.     public void request() {
  21.         // 在调用真实主题的方法前,可以进行一些预处理操作,如权限验证
  22.         System.out.println("代理进行权限验证");
  23.         realSubject.request();
  24.         // 在调用真实主题的方法后,可以进行一些后处理操作,如日志日志记录
  25.         System.out.println("代理记录请求日志");
  26.     }
  27. }
复制代码
在客户端代码中:
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         RealSubject realSubject = new RealSubject();
  4.         Proxy proxy = new Proxy(realSubject);
  5.         proxy.request();
  6.     }
  7. }
复制代码
应用场景

在远程服务调用中,署理模式常用于创建远程署理。客户端通过远程署理对象调用远程服务,署理对象负责处理网络通信、序列化 / 反序列化等复杂操作,对客户端隐藏了远程调用的细节。比方,调用第三方付出接口时,使用署理模式可以在调用前后添加参数校验、记载付出日志等功能
观察者模式(Observer Pattern)

模式界说与原理

界说了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,会通知全部观察者对象,使它们可以或许自动更新。
示例代码

  1. // 主题接口,定义注册、移除和通知观察者的方法
  2. interface Subject {
  3.     void registerObserver(Observer observer);
  4.     void removeObserver(Observer observer);
  5.     void notifyObservers();
  6. }
  7. // 观察者接口,定义更新方法
  8. interface Observer {
  9.     void update();
  10. }
  11. // 具体主题类,实现主题接口
  12. class ConcreteSubject implements Subject {
  13.     private java.util.List<Observer> observers = new java.util.ArrayList<>();
  14.     @Override
  15.     public void registerObserver(Observer observer) {
  16.         observers.add(observer);
  17.     }
  18.     @Override
  19.     public void removeObserver(Observer observer) {
  20.         observers.remove(observer);
  21.     }
  22.     @Override
  23.     public void notifyObservers() {
  24.         for (Observer observer : observers) {
  25.             observer.update();
  26.         }
  27.     }
  28.     // 模拟主题状态变化的方法
  29.     public void changeState() {
  30.         System.out.println("主题状态发生变化");
  31.         notifyObservers();
  32.     }
  33. }
  34. // 具体观察者类,实现观察者接口
  35. class ConcreteObserver implements Observer {
  36.     @Override
  37.     public void update() {
  38.         System.out.println("观察者收到通知并更新");
  39.     }
  40. }
复制代码
在客户端代码中:
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         ConcreteSubject subject = new ConcreteSubject();
  4.         ConcreteObserver observer = new ConcreteObserver();
  5.         subject.registerObserver(observer);
  6.         subject.changeState();
  7.     }
  8. }
复制代码
计谋模式(Strategy Pattern)

模式界说与原理

界说一系列算法,将每个算法都封装起来,而且使它们可以相互更换。计谋模式让算法的变化独立于使用算法的客户。通过将不同的算法封装成详细的计谋类,客户端可以根据不同的需求选择不同的计谋。
示例代码

  1. // 策略接口,定义算法的抽象方法
  2. interface Strategy {
  3.     void execute();
  4. }
  5. // 具体策略A,实现策略接口
  6. class StrategyA implements Strategy {
  7.     @Override
  8.     public void execute() {
  9.         System.out.println("执行策略A");
  10.     }
  11. }
  12. // 具体策略B,实现策略接口
  13. class StrategyB implements Strategy {
  14.     @Override
  15.     public void execute() {
  16.         System.out.println("执行策略B");
  17.     }
  18. }
  19. // 上下文类,持有策略接口的引用
  20. class Context {
  21.     private Strategy strategy;
  22.     // 构造函数,传入具体的策略对象
  23.     public Context(Strategy strategy) {
  24.         this.strategy = strategy;
  25.     }
  26.     // 执行策略的方法
  27.     public void executeStrategy() {
  28.         strategy.execute();
  29.     }
  30. }
复制代码
在客户端代码中:
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         Strategy strategyA = new StrategyA();
  4.         Context context = new Context(strategyA);
  5.         context.executeStrategy();
  6.         Strategy strategyB = new StrategyB();
  7.         context = new Context(strategyB);
  8.         context.executeStrategy();
  9.     }
  10. }
复制代码
应用场景

在电商体系的促销运动中,不同的促销计谋(如满减、扣头、赠品等)可以使用计谋模式实现。体系可以根据不同的运动类型选择相应的促销计谋,使得促销逻辑易于扩展和维护。
装饰器模式(Decorator Pattern)

模式界说与原理

动态地给一个对象添加一些额外的职责。装饰器模式通过组合的方式,让装饰对象持有被装饰对象的引用,并实现与被装饰对象相同的接口。在调用装饰对象的方法时,会先调用被装饰对象的方法,然后实行装饰对象添加的额外逻辑,从而在不改变原有对象布局的情况下为其添加新功能
示例代码

  1. // 组件接口,定义组件的基本行为
  2. interface Component {
  3.     void operation();
  4. }
  5. // 具体组件类,实现组件接口
  6. class ConcreteComponent implements Component {
  7.     @Override
  8.     public void operation() {
  9.         System.out.println("具体组件的操作");
  10.     }
  11. }
  12. // 装饰器抽象类,继承组件接口并持有组件实例
  13. abstract class Decorator implements Component {
  14.     protected Component component;
  15.     // 构造函数,传入组件实例
  16.     public Decorator(Component component) {
  17.         this.component = component;
  18.     }
  19.     @Override
  20.     public void operation() {
  21.         component.operation();
  22.     }
  23. }
  24. // 具体装饰器类,继承装饰器抽象类并添加额外功能
  25. class ConcreteDecorator extends Decorator {
  26.     // 构造函数,传入组件实例
  27.     public ConcreteDecorator(Component component) {
  28.         super(component);
  29.     }
  30.     @Override
  31.     public void operation() {
  32.         // 先执行原有组件的操作
  33.         super.operation();
  34.         // 添加额外的操作
  35.         System.out.println("具体装饰器添加的额外操作");
  36.     }
  37. }
复制代码
在客户端代码中:
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         Component component = new ConcreteComponent();
  4.         Component decoratedComponent = new ConcreteDecorator(component);
  5.         decoratedComponent.operation();
  6.     }
  7. }
复制代码
应用场景

在 Java 的 I/O 流中,装饰器模式得到了广泛应用。比方,BufferedInputStream就是对InputStream的装饰,它为InputStream添加了缓冲功能,提高了读取效率。在实际开发中,如果必要在运行时为对象动态添加功能,如给游戏角色添加临时增益效果,就可以使用装饰器模式。
总结

这些常用设计模式在软件开发中各自发挥侧重要作用,无论是创建对象、管理对象关系,还是处理对象行为,它们都提供了优雅且高效的解决方案。通过深入明确和纯熟运用这些设计模式,开发者可以或许构建出更加健壮、可维护和可扩展的软件体系。盼望本文的介绍能帮助你在实际项目中更好地应用这些设计模式,提升代码质量与开发效率。你在使用这些设计模式时有什么独特的经验或问题吗?欢迎在批评区分享交换。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表