Java设计模式:深入解析与应用示例

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 引言设计模式是一种在特定上下文中反复出现的可重用解决方案,用于处理软件设计中常见的问题。掌握设计模式不仅可以帮助我们编写出更优雅、更易于理解和维护的代码,而且也是Java面试中的常考知识点。在本文中,我们将探讨几种常见的设计模式,包括它们的定义、使用场景和Java实现。

引言

设计模式是一种在特定上下文中反复出现的可重用解决方案,用于处理软件设计中常见的问题。掌握设计模式不仅可以帮助我们编写出更优雅、更易于理解和维护的代码,而且也是Java面试中的常考知识点。在本文中,我们将探讨几种常见的设计模式,包括它们的定义、使用场景和Java实现。

一、单例模式

单例模式确保一个类只有一个实例,并提供全局访问点。这种设计模式属于创建型模式,它涉及一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。


应用场景:需要频繁实例化然后销毁的对象,数据库连接、线程池等长时间存在于系统中的对象。

示例代码:

public class Singleton {
    // 使用volatile关键字防止指令重排序
    private static volatile Singleton instance;
    private Singleton() {}
    // 提供全局访问点
    public static Singleton getInstance() {
        // 第一次检查
        if (instance == null) {
            // 加锁
            synchronized (Singleton.class) {
                // 第二次检查
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

我们创建了一个 Singleton 类。Singleton 类有一个 getInstance() 方法,它可以返回 Singleton 类的一个实例。在这个类中,我们有一个私有构造函数,它可以防止其他类实例化这个类。而 getInstance() 方法可以为其他类提供了一种方式来获取这个类的单一实例。

二、工厂模式

工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

应用场景:在编码时不能预见需要创建哪种类的实例,系统需要提供一个接口,让系统与其各种具体实现类之间解耦。

示例代码:

public interface Shape {
    void draw();
}
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}
public class ShapeFactory {
    // 使用getShape方法获取形状类型的对象
    public Shape getShape(String shapeType) {
        if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        }
        // other shape types...
        return null;
    }
}

我们首先创建了一个接口 Shape 和实现了 Shape 接口的实体类。然后我们创建了一个工厂类 ShapeFactory。ShapeFactory 类有一个方法 getShape ,根据输入的类型,返回一个实体类的实例。在这个例子中,我们的工厂类 ShapeFactory 是如何根据我们提供的信息来返回不同类的实例的。

三、抽象工厂模式

抽象工厂模式是一种创建型设计模式,它提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。在抽象工厂模式中,抽象工厂定义了产品是什么,为创建一系列相关或相互依赖应用场景:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

示例代码:

public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}
public class WinFactory implements GUIFactory {
    // 返回WinButton类的实例
    public Button createButton() {
        return new WinButton();
    }
    // 返回WinCheckbox类的实例
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
}

和工厂模式类似,但是这次我们添加了一个新的层次——工厂创造器/生成器类 FactoryProducerAbstractFactory 类是所有工厂类的超类,FactoryProducer 可以根据传入的信息返回一个特定的工厂

四、建造者模式

建造者模式是一种创建型设计模式,它可以将一个复杂对象的建造过程抽象出来(抽象为指挥者和建造者),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的复杂对象。具体来说,将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。


应用场景:需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个部分。示例代码:

public class Pizza {
    private String dough = "";
    private String sauce = "";
    private String topping = "";
    // setters...
}
public class PizzaBuilder {
    private Pizza pizza;
    public PizzaBuilder() {
        pizza = new Pizza();
    }
    public PizzaBuilder setDough(String dough) {
        pizza.setDough(dough);
        return this;
    }
    public PizzaBuilder setSauce(String sauce) {
        pizza.setSauce(sauce);
        return this;
    }
    public PizzaBuilder setTopping(String topping) {
        pizza.setTopping(topping);
        return this;
    }
    // 最终构建复杂的Pizza对象并返回
    public Pizza build() {
        return pizza;
    }
}

Packing 和 Item 接口表示食物和食物包装。然后我们有了实体类实现了这些接口,Burger 和 ColdDrink 实现了 Item 接口,Wrapper 和 Bottle 实现了 Packing 接口。Meal 类是一个组合类,包含了 Item 对象。MealBuilder 是实际的构建器,负责创建 Meal 对象。

五、原型模式

原型模式是创建型设计模式,通过复制一个已存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。

应用场景:创建对象成本较大(如初始化需要消耗很多

时间,占用太多CPU资源或网络资源),新的对象可以通过原型模式对已有对象进行复制来获得,如果是相似对象,则可以对其成员变量稍作修改。

示例代码:

public class Prototype implements Cloneable {
    // 使用 clone() 方法来创建新的实例
    public Prototype clone() {
        try {
            return
 (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

在原型模式中,我们通过复制一个已存在的对象来创建新的对象。我们创建了一个抽象类 Shape 和几个扩展了 Shape 类的实体类。ShapeCache 类是一个缓存类,将shape对象存储在一个 Hashtable 中,并在请求的时候返回它们的克隆。

六、适配器模式

适配器模式是一种结构型设计模式,它通过把一个类的接口变换成客户端所期待的另一种接口,可以帮助我们解决不兼容的问题。这个模式主要应用于希望复用那些与新系统不兼容的旧组件的场景,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。


应用场景:已经存在的类,它的方法和我们的需求不一样,也就是接口不相同,或者我们创建了一个可复用的类,该类可能和现有的类库不是很兼容,需要在双方都不易修改的情况下使用适配器模式。示例代码:

// 目标接口,或称为标准接口
public interface MediaPlayer {
    void play(String audioType, String fileName);
}
// 适配器类,实现MediaPlayer接口
public class MediaAdapter implements MediaPlayer {
    // 适配器中包含了一个需要适配的对象
    AdvancedMediaPlayer advancedMusicPlayer;
    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer = new Mp4Player();
        }
    }
    // 调用适配器中的方法
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}

我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类。然后我们创建了另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。然后我们创建了一个适配器类 MediaAdapter,它使用 AdvancedMediaPlayer 对象来播放所需要的格式。

七、装饰器模式

装饰器模式是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它在不需要使用继承的情况下为对象动态添加新的功能。

应用场景:在不想增加很多子类的情况下扩展类,需要动态增加及撤销对象的功能。

示例代码:

// 定义接口Shape
public interface Shape {
    void draw();
}
// 定义装饰器DecoratorShape
public class DecoratorShape implements Shape {
    protected Shape decoratedShape;
    public DecoratorShape(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }
    // 在装饰器中调用原始对象的方法,并添加新的功能
    public void draw() {
        decoratedShape.draw();
        System.out.println("Additional decoration function.");
    }
}

我们有一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建了一个抽象的装饰器类 ShapeDecorator,并扩展了 Shape 接口,此装饰器类在被装饰类上进行了一层包装,以增加新的功能。

八、观察者模式

观察者模式是一种行为型设计模式,定义对象间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,其相关依赖对象皆会得到通知并被自动更新。观察者模式属于行为型模式。

应用场景:当一个对象的改变需要同时改变其他对象,并且它不知道具体有多少对象需要改变,就可以考虑使用观察者模式。

示例代码:

// 定义Subject,持有观察者的列表,并提供attach和notifyAllObservers方法
public class Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    public void attach(Observer observer) {
        observers.add(observer);
    }
    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
// 定义Observer,声明更新自己的抽象方法
public abstract class Observer {
    protected Subject subject;
    public abstract void update();
}

我们创建了 Subject 类、Observer 抽象类和扩展了 Observer 类的实体类。Subject 对象改变状态时,所有依赖于它的对象都会得到通知,并自动更新。

九、策略模式

策略模式是一种行为型设计模式,它定义了一系列的算法,并将每一个算法封装起来,而且使它们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。


应用场景:一个系统有很多类的算法或者业务逻辑,可以把这些算法或者业务逻辑封装在同一个接口的不同的实现类中,减少使用多重转移语句(if…else if…else)。示例代码:

// 定义策略接口,声明算法方法
public interface Strategy {
    public int doOperation(int num1, int num2);
}
// 定义具体策略类
public class OperationAdd implements Strategy {
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}
// 环境类,持有一个策略类的引用
public class StrategyContext {
    private Strategy strategy;
    public StrategyContext(Strategy strategy) {
        this.strategy = strategy;
    }
    // 使用策略的方法
    public int executeStrategy(int num1, int num2) {
        return strategy.doOperation(num1, num2);
    }
}

我们定义了一个策略接口 Strategy 和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。Context 对象使用了一些策略对象,这个策略对象改变了 Context 对象的执行算法。

十、命令模式

命令模式是一种行为型设计模式,它通过在对象之间引入级别,使得对象之间的依赖关系变得更加简单,并且降低了组合和调用的复杂性。这种模式涉及到五个组件:Client、Invoker、Command、ConcreteCommand、Receiver。


应用场景:当需要为请求调用者与请求接收者解耦时,命令模式使得调用者与接收者不直接交互,并且调用者无需知道接收者的接口。命令模式可以用于有多个触发者或接收者,需要向多个对象发出请求。示例代码:

// 命令接口,声明执行方法
public interface Order {
    void execute();
}
// 具体命令类,实现Order接口的execute方法,调用接收者的方法
public class StockRequest implements Order {
    private Stock stock;
    public StockRequest(Stock stock) {
        this.stock = stock;
    }
    public void execute() {
        stock.buy();
    }
}
// 调用者类,接收命令并执行
public class Broker {
    private List<Order> orderList = new ArrayList<Order>();
    public void takeOrder(Order order) {
        orderList.add(order);
    }
    public void placeOrders() {
        for (Order order : orderList) {
            order.execute();
        }
        orderList.clear();
    }
}

我们创建了一个请求类 Stock,一个命令接口 Order 和实现了 Order 接口的实体命令类。命令实现类持有一个对请求的引用,并执行这个请求。Broker 对象使用命令对象和队列来执行请求。

结语

在这篇博客中,我们研究了10种常用的Java设计模式,希望这些知识能帮助你在日常开发或面试中更好地解决问题。记住,设计模式只是工具。在实际项目中,我们应该根据项目需求和具体情况选择合适的设计模式,而不是强行套用。

相关文章
|
1月前
|
存储 Java 计算机视觉
Java二维数组的使用技巧与实例解析
本文详细介绍了Java中二维数组的使用方法
47 15
|
1天前
|
存储 人工智能 程序员
通义灵码AI程序员实战:从零构建Python记账本应用的开发全解析
本文通过开发Python记账本应用的真实案例,展示通义灵码AI程序员2.0的代码生成能力。从需求分析到功能实现、界面升级及测试覆盖,AI程序员展现了需求转化、技术选型、测试驱动和代码可维护性等核心价值。文中详细解析了如何使用Python标准库和tkinter库实现命令行及图形化界面,并生成单元测试用例,确保应用的稳定性和可维护性。尽管AI工具显著提升开发效率,但用户仍需具备编程基础以进行调试和优化。
66 9
|
14天前
|
搜索推荐 数据挖掘 API
Lazada 淘宝详情 API 的价值与应用解析
在全球化电商浪潮下,Lazada 和淘宝作为东南亚和中国电商市场的关键力量,拥有海量商品数据和庞大用户群体。详情 API 接口为电商开发者、商家和分析师提供了获取商品详细信息(如描述、价格、库存、评价等)的工具,助力业务决策与创新。本文深入解析 Lazada 和淘宝详情 API 的应用场景及价值,并提供 Python 调用示例,帮助读者更好地理解和运用这两个强大的工具。
46 18
|
13天前
|
数据采集 搜索推荐 API
小红书笔记详情 API 接口:获取、应用与收益全解析
小红书(RED)是国内领先的生活方式分享平台,汇聚大量用户生成内容(UGC),尤以“种草”笔记闻名。小红书笔记详情API接口为开发者提供了获取笔记详细信息的强大工具,包括标题、内容、图片、点赞数等。通过注册开放平台账号、申请API权限并调用接口,开发者可构建内容分析工具、笔记推荐系统、数据爬虫等应用,提升用户体验和运营效率,创造新的商业模式。本文将详细介绍该API的获取、应用及潜在收益,并附上代码示例。
116 13
|
9天前
|
XML JSON Java
Java中Log级别和解析
日志级别定义了日志信息的重要程度,从低到高依次为:TRACE(详细调试)、DEBUG(开发调试)、INFO(一般信息)、WARN(潜在问题)、ERROR(错误信息)和FATAL(严重错误)。开发人员可根据需要设置不同的日志级别,以控制日志输出量,避免影响性能或干扰问题排查。日志框架如Log4j 2由Logger、Appender和Layout组成,通过配置文件指定日志级别、输出目标和格式。
|
24天前
|
搜索推荐 测试技术 API
探秘电商API:从测试到应用的深度解析与实战指南
电商API是电子商务背后的隐形引擎,支撑着从商品搜索、购物车更新到支付处理等各个环节的顺畅运行。它通过定义良好的接口,实现不同系统间的数据交互与功能集成,确保订单、库存和物流等信息的实时同步。RESTful、GraphQL和WebSocket等类型的API各自适用于不同的应用场景,满足多样化的需求。在测试方面,使用Postman、SoapUI和jMeter等工具进行全面的功能、性能和安全测试,确保API的稳定性和可靠性。未来,随着人工智能、大数据和物联网技术的发展,电商API将进一步智能化和标准化,为用户提供更个性化的购物体验,并推动电商行业的持续创新与进步。
56 4
|
1月前
|
JSON 小程序 UED
微信小程序 app.json 配置文件解析与应用
本文介绍了微信小程序中 `app.json` 配置文件的详细
141 12
|
24天前
|
搜索推荐 API 开发者
深度解析:利用商品详情 API 接口实现数据获取与应用
在电商蓬勃发展的今天,数据成为驱动业务增长的核心。商品详情API接口作为连接海量商品数据的桥梁,帮助运营者、商家和开发者获取精准的商品信息(如价格、描述、图片、评价等),优化策略、提升用户体验。通过理解API概念、工作原理及不同平台特点,掌握获取权限、构建请求、处理响应和错误的方法,可以将数据应用于商品展示、数据分析、竞品分析和个性化推荐等场景,助力电商创新与发展。未来,随着技术进步,API接口将与人工智能、大数据深度融合,带来更多变革。
62 3
|
3月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
133 2
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

推荐镜像

更多