Java常用设计模式-代码实例详解

news/2025/2/23 10:29:35

1. 单例模式(Singleton Pattern)

原理

确保一个类只有一个实例,并提供全局访问点。核心是通过私有构造器和静态方法控制实例化。

应用场景
  • 配置管理类
  • 数据库连接池
  • 日志记录器
代码实例1:日志管理器(懒汉式,线程安全)

场景:在一个电商系统中,需要一个全局日志管理器记录操作日志。

java">public class Logger {
    // volatile确保多线程环境下可见性
    private static volatile Logger instance;

    private Logger() {
        // 防止反射破坏单例
        if (instance != null) {
            throw new RuntimeException("Use getInstance() method to get the single instance.");
        }
    }

    public static Logger getInstance() {
        if (instance == null) {
            synchronized (Logger.class) {
                if (instance == null) {
                    instance = new Logger();
                }
            }
        }
        return instance;
    }

    public void log(String message) {
        System.out.println("Log: " + message);
    }
}

// 使用
public class OrderService {
    public void createOrder() {
        Logger logger = Logger.getInstance();
        logger.log("Order created at " + System.currentTimeMillis());
    }
}

说明:双重检查锁(Double-Checked Locking)确保线程安全,适用于延迟加载。

代码实例2:配置管理(饿汉式)

场景:读取应用的全局配置(如API密钥)。

java">public class ConfigManager {
    // 类加载时即创建实例
    private static final ConfigManager INSTANCE = new ConfigManager();

    private final String apiKey;

    private ConfigManager() {
        this.apiKey = "12345-ABCDE"; // 模拟从文件加载
    }

    public static ConfigManager getInstance() {
        return INSTANCE;
    }

    public String getApiKey() {
        return apiKey;
    }
}

// 使用
public class PaymentService {
    public void processPayment() {
        ConfigManager config = ConfigManager.getInstance();
        System.out.println("Using API Key: " + config.getApiKey());
    }
}

说明:饿汉式在类加载时初始化,简单但不支持延迟加载。

注意事项
  • 线程安全:懒汉式需加锁,饿汉式天然安全。
  • 序列化/反射破坏:需额外处理(如上例中的构造器检查)。

2. 工厂方法模式(Factory Method Pattern)

原理

定义一个创建对象的接口,由子类决定实例化哪个类,推迟实例化到子类。

应用场景
  • 创建不同类型的日志记录器
  • 动态生成数据库连接
代码实例1:日志工厂

场景:支持文件日志和数据库日志。

java">public interface Logger {
    void log(String message);
}

public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("File Log: " + message);
    }
}

public class DatabaseLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("DB Log: " + message);
    }
}

public abstract class LoggerFactory {
    public abstract Logger createLogger();

    public void writeLog(String message) {
        Logger logger = createLogger();
        logger.log(message);
    }
}

public class FileLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}

// 使用
public class Client {
    public static void main(String[] args) {
        LoggerFactory factory = new FileLoggerFactory();
        factory.writeLog("Order processed");
    }
}
代码实例2:数据库连接工厂

场景:支持MySQL和PostgreSQL连接。

java">public interface DatabaseConnection {
    void connect();
}

public class MySQLConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Connected to MySQL");
    }
}

public class PostgreSQLConnection implements DatabaseConnection {
    @Override
    public void connect() {
        System.out.println("Connected to PostgreSQL");
    }
}

public abstract class ConnectionFactory {
    public abstract DatabaseConnection createConnection();
}

public class MySQLConnectionFactory extends ConnectionFactory {
    @Override
    public DatabaseConnection createConnection() {
        return new MySQLConnection();
    }
}

// 使用
public class DataService {
    public void queryData(ConnectionFactory factory) {
        DatabaseConnection conn = factory.createConnection();
        conn.connect();
    }
}
注意事项
  • 扩展性强,但工厂类增多可能导致复杂度上升。
  • 可结合Spring的依赖注入简化实现。

3. 建造者模式(Builder Pattern)

原理

将复杂对象的构建过程与其表示分离,逐步构建。

应用场景
  • 创建复杂配置对象
  • 构造HTTP请求
代码实例1:订单对象构建

场景:电商系统中构造订单。

java">public class Order {
    private final String orderId;
    private final String customerName;
    private final double amount;

    private Order(Builder builder) {
        this.orderId = builder.orderId;
        this.customerName = builder.customerName;
        this.amount = builder.amount;
    }

    public static class Builder {
        private String orderId;
        private String customerName;
        private double amount;

        public Builder orderId(String orderId) {
            this.orderId = orderId;
            return this;
        }

        public Builder customerName(String customerName) {
            this.customerName = customerName;
            return this;
        }

        public Builder amount(double amount) {
            this.amount = amount;
            return this;
        }

        public Order build() {
            return new Order(this);
        }
    }
}

// 使用
public class OrderService {
    public Order createOrder() {
        return new Order.Builder()
                .orderId("ORD001")
                .customerName("Alice")
                .amount(100.0)
                .build();
    }
}
代码实例2:HTTP请求构建

场景:构造HTTP请求参数。

java">public class HttpRequest {
    private final String url;
    private final String method;
    private final String body;

    private HttpRequest(Builder builder) {
        this.url = builder.url;
        this.method = builder.method;
        this.body = builder.body;
    }

    public static class Builder {
        private String url;
        private String method = "GET";
        private String body;

        public Builder url(String url) {
            this.url = url;
            return this;
        }

        public Builder method(String method) {
            this.method = method;
            return this;
        }

        public Builder body(String body) {
            this.body = body;
            return this;
        }

        public HttpRequest build() {
            return new HttpRequest(this);
        }
    }
}

// 使用
public class ApiClient {
    public HttpRequest sendRequest() {
        return new HttpRequest.Builder()
                .url("https://api.example.com")
                .method("POST")
                .body("{'data': 'test'}")
                .build();
    }
}
注意事项
  • 适合复杂对象,避免过多构造函数参数。
  • 可结合Lombok的@Builder简化代码。

4. 装饰者模式(Decorator Pattern)

原理

动态为对象添加职责,不修改原有类。

应用场景
  • 日志增强
  • 数据流处理
代码实例1:咖啡订单装饰

场景:咖啡店系统中添加额外配料。

java">public interface Coffee {
    double cost();
    String description();
}

public class SimpleCoffee implements Coffee {
    @Override
    public double cost() {
        return 5.0;
    }

    @Override
    public String description() {
        return "Simple Coffee";
    }
}

public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double cost() {
        return coffee.cost() + 1.5;
    }

    @Override
    public String description() {
        return coffee.description() + ", Milk";
    }
}

// 使用
public class CoffeeShop {
    public static void main(String[] args) {
        Coffee coffee = new MilkDecorator(new SimpleCoffee());
        System.out.println(coffee.description() + " costs " + coffee.cost());
    }
}
代码实例2:日志装饰

场景:为日志添加时间戳。

java">public interface Logger {
    void log(String message);
}

public class BasicLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println(message);
    }
}

public abstract class LoggerDecorator implements Logger {
    protected Logger logger;

    public LoggerDecorator(Logger logger) {
        this.logger = logger;
    }
}

public class TimestampLogger extends LoggerDecorator {
    public TimestampLogger(Logger logger) {
        super(logger);
    }

    @Override
    public void log(String message) {
        logger.log(System.currentTimeMillis() + " - " + message);
    }
}

// 使用
public class App {
    public static void main(String[] args) {
        Logger logger = new TimestampLogger(new BasicLogger());
        logger.log("Order processed");
    }
}
注意事项
  • 灵活性高,但可能增加类数量。
  • Spring AOP本质上也类似装饰者模式。

5. 代理模式(Proxy Pattern)

原理

为对象提供代理,控制访问或增强功能。

应用场景
  • 权限控制
  • 延迟加载
代码实例1:权限代理

场景:限制用户访问敏感操作。

java">public interface UserService {
    void deleteUser(String userId);
}

public class UserServiceImpl implements UserService {
    @Override
    public void deleteUser(String userId) {
        System.out.println("User " + userId + " deleted");
    }
}

public class UserServiceProxy implements UserService {
    private UserService target;
    private String role;

    public UserServiceProxy(UserService target, String role) {
        this.target = target;
        this.role = role;
    }

    @Override
    public void deleteUser(String userId) {
        if ("admin".equals(role)) {
            target.deleteUser(userId);
        } else {
            System.out.println("Permission denied");
        }
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        UserService service = new UserServiceProxy(new UserServiceImpl(), "user");
        service.deleteUser("001");
    }
}
代码实例2:延迟加载代理

场景:延迟加载大文件。

java">public interface FileLoader {
    void load();
}

public class RealFileLoader implements FileLoader {
    private String fileName;

    public RealFileLoader(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void load() {
        System.out.println("Loading file: " + fileName);
    }
}

public class LazyFileLoaderProxy implements FileLoader {
    private RealFileLoader realLoader;
    private String fileName;

    public LazyFileLoaderProxy(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void load() {
        if (realLoader == null) {
            realLoader = new RealFileLoader(fileName);
        }
        realLoader.load();
    }
}

// 使用
public class FileSystem {
    public static void main(String[] args) {
        FileLoader loader = new LazyFileLoaderProxy("largeFile.txt");
        loader.load(); // 仅在需要时加载
    }
}
注意事项
  • 动态代理(如java.lang.reflect.Proxy)更灵活。
  • Spring AOP大量使用代理模式。

6. 观察者模式(Observer Pattern)

原理

定义一对多依赖,主体状态变化时通知观察者。

应用场景
  • 事件监听
  • 库存变化通知
代码实例1:库存通知

场景:库存不足时通知采购部门。

java">import java.util.ArrayList;
import java.util.List;

public interface Observer {
    void update(String message);
}

public class Stock {
    private List<Observer> observers = new ArrayList<>();
    private int quantity;

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
        if (quantity < 10) {
            notifyObservers("Stock low: " + quantity);
        }
    }

    private void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

public class PurchasingDept implements Observer {
    @Override
    public void update(String message) {
        System.out.println("Purchasing: " + message);
    }
}

// 使用
public class Warehouse {
    public static void main(String[] args) {
        Stock stock = new Stock();
        stock.addObserver(new PurchasingDept());
        stock.setQuantity(5);
    }
}
代码实例2:订单状态通知

场景:订单状态变化时通知用户。

java">import java.util.ArrayList;
import java.util.List;

public interface OrderObserver {
    void onOrderUpdate(String orderId, String status);
}

public class Order {
    private List<OrderObserver> observers = new ArrayList<>();
    private String orderId;
    private String status;

    public Order(String orderId) {
        this.orderId = orderId;
    }

    public void addObserver(OrderObserver observer) {
        observers.add(observer);
    }

    public void setStatus(String status) {
        this.status = status;
        notifyObservers();
    }

    private void notifyObservers() {
        for (OrderObserver observer : observers) {
            observer.onOrderUpdate(orderId, status);
        }
    }
}

public class Customer implements OrderObserver {
    @Override
    public void onOrderUpdate(String orderId, String status) {
        System.out.println("Customer notified: Order " + orderId + " is " + status);
    }
}

// 使用
public class OrderService {
    public static void main(String[] args) {
        Order order = new Order("ORD001");
        order.addObserver(new Customer());
        order.setStatus("Shipped");
    }
}
注意事项
  • Java提供了ObservableObserver(已过时),推荐自定义或用java.util.EventListener
  • Spring的ApplicationEvent是观察者模式的典型应用。

7. 策略模式(Strategy Pattern)

原理

定义一系列算法,动态选择使用。

应用场景
  • 支付方式选择
  • 折扣计算
代码实例1:支付策略

场景:电商系统中的支付方式。

java">public interface PaymentStrategy {
    void pay(double amount);
}

public class AlipayStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " via Alipay");
    }
}

public class CreditCardStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

public class PaymentContext {
    private PaymentStrategy strategy;

    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment(double amount) {
        strategy.pay(amount);
    }
}

// 使用
public class CheckoutService {
    public void checkout(double amount, String paymentType) {
        PaymentContext context = new PaymentContext();
        if ("alipay".equals(paymentType)) {
            context.setStrategy(new AlipayStrategy());
        } else {
            context.setStrategy(new CreditCardStrategy());
        }
        context.executePayment(amount);
    }
}
代码实例2:折扣策略

场景:促销活动中计算折扣。

java">public interface DiscountStrategy {
    double applyDiscount(double price);
}

public class NoDiscountStrategy implements DiscountStrategy {
    @Override
    public double applyDiscount(double price) {
        return price;
    }
}

public class HolidayDiscountStrategy implements DiscountStrategy {
    @Override
    public double applyDiscount(double price) {
        return price * 0.8; // 20% off
    }
}

public class ShoppingCart {
    private DiscountStrategy discountStrategy;

    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public double calculateTotal(double price) {
        return discountStrategy.applyDiscount(price);
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.setDiscountStrategy(new HolidayDiscountStrategy());
        System.out.println("Total: " + cart.calculateTotal(100));
    }
}
注意事项
  • 可结合Spring的@Conditional动态注入策略。
  • 避免策略类过多导致维护困难。

8. 迭代器模式(Iterator Pattern)

原理

提供一种顺序访问集合元素的方法,隐藏底层实现。

应用场景
  • 遍历自定义集合
  • 数据分页
代码实例1:商品列表迭代

场景:遍历电商商品列表。

java">import java.util.ArrayList;
import java.util.Iterator;

public class ProductList {
    private ArrayList<String> products = new ArrayList<>();

    public void addProduct(String product) {
        products.add(product);
    }

    public Iterator<String> iterator() {
        return products.iterator();
    }
}

// 使用
public class Store {
    public static void main(String[] args) {
        ProductList list = new ProductList();
        list.addProduct("Phone");
        list.addProduct("Laptop");

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
代码实例2:订单分页迭代

场景:分页遍历订单。

java">import java.util.ArrayList;
import java.util.Iterator;

public class OrderRepository {
    private ArrayList<String> orders = new ArrayList<>();

    public OrderRepository() {
        orders.add("ORD001");
        orders.add("ORD002");
        orders.add("ORD003");
    }

    public Iterator<String> getPageIterator(int pageSize) {
        return new OrderIterator(pageSize);
    }

    private class OrderIterator implements Iterator<String> {
        private int index = 0;
        private int pageSize;

        public OrderIterator(int pageSize) {
            this.pageSize = pageSize;
        }

        @Override
        public boolean hasNext() {
            return index < orders.size() && index < pageSize;
        }

        @Override
        public String next() {
            return orders.get(index++);
        }
    }
}

// 使用
public class OrderService {
    public static void main(String[] args) {
        OrderRepository repo = new OrderRepository();
        Iterator<String> iterator = repo.getPageIterator(2);
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
注意事项
  • Java集合框架已内置Iterator,自定义时注意兼容性。
  • 可结合for-each语法简化使用。

9. 模板方法模式(Template Method Pattern)

原理

定义算法骨架,子类实现具体步骤。

应用场景
  • 数据处理流程
  • 报表生成
代码实例1:数据导入模板

场景:导入不同格式的数据。

java">public abstract class DataImporter {
    // 模板方法
    public void importData() {
        connect();
        String data = readData();
        processData(data);
        disconnect();
    }

    protected void connect() {
        System.out.println("Connected to source");
    }

    protected abstract String readData();

    protected abstract void processData(String data);

    protected void disconnect() {
        System.out.println("Disconnected");
    }
}

public class CsvImporter extends DataImporter {
    @Override
    protected String readData() {
        return "CSV data";
    }

    @Override
    protected void processData(String data) {
        System.out.println("Processing " + data);
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        DataImporter importer = new CsvImporter();
        importer.importData();
    }
}
代码实例2:报表生成模板

场景:生成不同格式的销售报表。

java">public abstract class ReportGenerator {
    public void generateReport() {
        fetchData();
        formatData();
        saveReport();
    }

    protected void fetchData() {
        System.out.println("Fetching sales data");
    }

    protected abstract void formatData();

    protected abstract void saveReport();
}

public class PdfReportGenerator extends ReportGenerator {
    @Override
    protected void formatData() {
        System.out.println("Formatting as PDF");
    }

    @Override
    protected void saveReport() {
        System.out.println("Saving as PDF file");
    }
}

// 使用
public class ReportService {
    public static void main(String[] args) {
        ReportGenerator generator = new PdfReportGenerator();
        generator.generateReport();
    }
}
注意事项
  • 确保抽象方法职责清晰。
  • Spring的JdbcTemplate是典型模板方法应用。

10. 外观模式(Facade Pattern)

原理

为子系统提供统一接口,简化调用。

应用场景
  • 封装第三方API
  • 简化复杂业务逻辑
代码实例1:支付外观

场景:封装支付子系统。

java">public class PaymentGateway {
    public void charge(double amount) {
        System.out.println("Charging " + amount);
    }
}

public class FraudCheck {
    public boolean isFraudulent(double amount) {
        return amount > 1000;
    }
}

public class PaymentFacade {
    private PaymentGateway gateway = new PaymentGateway();
    private FraudCheck fraudCheck = new FraudCheck();

    public void processPayment(double amount) {
        if (!fraudCheck.isFraudulent(amount)) {
            gateway.charge(amount);
            System.out.println("Payment processed");
        } else {
            System.out.println("Payment blocked due to fraud");
        }
    }
}

// 使用
public class CheckoutService {
    public static void main(String[] args) {
        PaymentFacade facade = new PaymentFacade();
        facade.processPayment(500);
    }
}
代码实例2:订单处理外观

场景:简化订单创建流程。

java">public class InventoryService {
    public void reserveStock(String productId) {
        System.out.println("Reserved stock for " + productId);
    }
}

public class ShippingService {
    public void scheduleShipping(String orderId) {
        System.out.println("Scheduled shipping for " + orderId);
    }
}

public class OrderFacade {
    private InventoryService inventory = new InventoryService();
    private ShippingService shipping = new ShippingService();

    public void createOrder(String orderId, String productId) {
        inventory.reserveStock(productId);
        shipping.scheduleShipping(orderId);
        System.out.println("Order " + orderId + " created");
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        OrderFacade facade = new OrderFacade();
        facade.createOrder("ORD001", "PROD001");
    }
}
注意事项
  • 避免外观类过于复杂,变成“上帝类”。
  • Spring的Service层常扮演外观角色。

http://www.niftyadmin.cn/n/5863318.html

相关文章

Openai Dashboard可视化微调大语言模型

1、Deepseek解释[大语言模型微调] 大语言模型微调&#xff08;Fine-tuning&#xff09;是指对已经预训练好的大规模语言模型&#xff08;如GPT、BERT等&#xff09;进行针对性调整&#xff0c;使其适应特定任务或领域的过程。以下是关键点的分步解释&#xff1a; 1. 预训练 vs…

MFC开发:如何创建第一个MFC应用程序

文章目录 一、概述二、MFC 的主要组件三、创建一个MFC窗口 一、概述 MFC 是微软提供的一个 C 类库&#xff0c;用于简化 Windows 应用程序的开发。它封装了 Windows API&#xff0c;提供面向对象的接口&#xff0c;帮助开发者更高效地创建图形用户界面&#xff08;GUI&#xf…

RoCEv2 高性能传输协议与 Lossless 无损网络

目录 文章目录 目录RoCERoCEv2 协议栈RoCEv2 需要 Lossless NetworkLossless Network 拥塞控制技术网络拥塞的原因PFC 基于优先级的流量控制PFC Deadlock&#xff08;死锁&#xff09;的问题PFC Storm&#xff08;风暴&#xff09;的问题ECN 显式拥塞通知拥塞控制ECN 拥塞控制滞…

HTML中,title和h1标签的区别是什么?

在 HTML 中&#xff0c;title和h1标签虽然都与文本内容展示相关&#xff0c;但它们的用途、位置和作用有明显的区别&#xff0c;下面为你详细介绍&#xff1a; 1. 用途 title标签&#xff1a;主要用于定义整个 HTML 文档的标题&#xff0c;这个标题通常显示在浏览器的标题栏或…

软件架构设计:架构风格

一、架构风格概述 定义 架构风格是对软件系统整体结构和组织方式的抽象描述&#xff0c;提供了一套通用的设计原则和模式。 作用 提高系统的可维护性、可扩展性和可复用性。帮助开发团队在设计和实现过程中保持一致性和规范性。 常见架构风格 分层架构、MVC架构、微服务架构、…

Scrum方法论指导下的Deepseek R1医疗AI部署开发

一、引言 1.1 研究背景与意义 在当今数智化时代&#xff0c;软件开发方法论对于项目的成功实施起着举足轻重的作用。Scrum 作为一种广泛应用的敏捷开发方法论&#xff0c;以其迭代式开发、快速反馈和高效协作的特点&#xff0c;在软件开发领域占据了重要地位。自 20 世纪 90 …

计算机网络————(一)HTTP讲解

基础内容分类 从TCP/IP协议栈为依托&#xff0c;由上至下、从应用层到基础设施介绍协议。 1.应用层&#xff1a; HTTP/1.1 Websocket HTTP/2.0 2.应用层的安全基础设施 LTS/SSL 3.传输层 TCP 4.网络层及数据链路层 IP层和以太网 HTTP协议 网络页面形成基本 流程&#xff1a…

【机器学习】13.十大算法之一K均值算法(K-means)聚类详细讲解

【机器学习】13.十大算法之一K均值算法&#xff08;K-means&#xff09;聚类详细讲解 一摘要二个人简介三K-均值聚类&#xff08;K-means&#xff09;3.1-K均值算法的基本原理3.1.1- 聚类分析的目标3.1.2- K - means算法算法原理 四K-means聚类算法的收敛性五证明K均值算法的收…