Java 中的设计模式:经典与现代实践

Java 中的设计模式:经典与现代实践

1. 设计模式简介

设计模式是一种软件开发中的思想,它为我们提供了一些经过验证的、能够应对常见问题的解决方案。学习和掌握设计模式能够让开发者在面对复杂的需求时,能够设计出更加灵活、可维护的代码。现代 Java 语言的特点(如 Lambda 表达式Stream APIOptional)使得设计模式的实现更加简洁和高效。

设计模式按照其功能可以分为三大类:

  1. 创建型模式:用于对象创建,避免直接实例化。
  2. 结构型模式:用于类和对象的组合,解决系统中类之间的关系问题。
  3. 行为型模式:描述对象之间的交互和职责划分。

在这篇文章中,我们将通过现代 Java 的特性来重构经典设计模式的实现,帮助开发者更好地理解和运用设计模式。


2. 创建型设计模式

2.1 工厂模式(Factory Pattern)

经典实现

工厂模式通过封装对象的创建逻辑,将客户端与具体类的实例化解耦。通常适用于在创建对象时需要复杂逻辑或者希望通过参数控制生成不同对象的场景。

经典代码示例
java 复制代码
// 产品接口
public interface Car {
    void drive();
}

// 具体产品类
public class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("Driving BMW...");
    }
}

public class Audi implements Car {
    @Override
    public void drive() {
        System.out.println("Driving Audi...");
    }
}

// 工厂类
public class CarFactory {
    public static Car createCar(String type) {
        switch (type.toLowerCase()) {
            case "bmw": return new BMW();
            case "audi": return new Audi();
            default: throw new IllegalArgumentException("Unknown car type");
        }
    }
}
现代 Java 实现:使用 Lambda 表达式

我们可以使用 Lambda 表达式 来简化工厂模式的实现,减少冗长的 if-elseswitch 语句,使得代码更简洁、灵活。

java 复制代码
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class CarFactory {
    private static final Map<String, Supplier<Car>> carRegistry = new HashMap<>();

    static {
        carRegistry.put("bmw", BMW::new);
        carRegistry.put("audi", Audi::new);
    }

    public static Car createCar(String type) {
        Supplier<Car> carSupplier = carRegistry.get(type.toLowerCase());
        if (carSupplier == null) {
            throw new IllegalArgumentException("Unknown car type");
        }
        return carSupplier.get();
    }
}
Spring 框架中的工厂模式

在 Spring 框架中,ApplicationContext 就是工厂模式的实现,它负责实例化并管理 Bean。

java 复制代码
// Spring 通过工厂模式实例化 Bean
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = context.getBean("car", Car.class);
car.drive();

3. 结构型设计模式

3.1 代理模式(Proxy Pattern)

经典实现

代理模式通过引入代理对象来控制对真实对象的访问。代理对象可以在调用目标对象之前或之后增加额外的逻辑,比如日志、权限控制等。

经典代码示例
java 复制代码
// 服务接口
public interface UserService {
    void createUser(String username);
}

// 真实服务类
public class RealUserService implements UserService {
    @Override
    public void createUser(String username) {
        System.out.println("Creating user: " + username);
    }
}

// 代理类
public class UserServiceProxy implements UserService {
    private final RealUserService realUserService = new RealUserService();

    @Override
    public void createUser(String username) {
        System.out.println("Logging: Start creating user");
        realUserService.createUser(username);
        System.out.println("Logging: End creating user");
    }
}
现代 Java 实现:使用 Java 8 的 StreamOptional

我们可以利用 Java 8 的 Optional 来避免 null 值的处理,并使用 Stream API 来简化数据的处理。

java 复制代码
public class UserServiceProxy implements UserService {
    private final RealUserService realUserService = new RealUserService();

    @Override
    public void createUser(String username) {
        Optional.of(username)
                .filter(name -> !name.isEmpty())
                .ifPresentOrElse(
                        name -> {
                            System.out.println("Logging: Start creating user");
                            realUserService.createUser(name);
                            System.out.println("Logging: End creating user");
                        },
                        () -> System.out.println("Invalid username")
                );
    }
}
Spring AOP 中的代理模式

Spring 的 AOP(面向切面编程)就是利用代理模式来增强目标方法的功能。Spring 使用 JDK 动态代理CGLIB 代理 来生成代理对象。

java 复制代码
@Service
public class OrderService {
    @Transactional
    public void createOrder() {
        // 事务管理由代理类处理
    }
}

4. 行为型设计模式

4.1 策略模式(Strategy Pattern)

经典实现

策略模式通过定义一系列算法并将每个算法封装到独立的策略类中,使得算法的选择和使用变得灵活。策略模式能够在运行时动态地改变策略。

经典代码示例
java 复制代码
public interface PaymentStrategy {
    void pay(int amount);
}

public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paying " + amount + " using Credit Card");
    }
}

public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paying " + amount + " using PayPal");
    }
}

public class PaymentContext {
    private PaymentStrategy strategy;

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

    public void executePayment(int amount) {
        strategy.pay(amount);
    }
}
现代 Java 实现:使用 Stream 进行策略选择

可以通过 Stream API 来简化策略的选择过程,让代码更加简洁和优雅。

java 复制代码
public class PaymentContext {
    private Map<String, PaymentStrategy> strategies = Map.of(
        "credit", new CreditCardPayment(),
        "paypal", new PayPalPayment()
    );

    public void executePayment(String paymentType, int amount) {
        Optional.ofNullable(strategies.get(paymentType))
                .ifPresentOrElse(
                        strategy -> strategy.pay(amount),
                        () -> System.out.println("Invalid payment method")
                );
    }
}
Spring 中的策略模式

Spring 中的 HandlerMapping 就是使用策略模式的一个例子,它通过不同的请求类型和处理器选择不同的处理策略。

java 复制代码
public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}

不同类型的 HandlerAdapter 处理不同的 Controller,如 SimpleControllerHandlerAdapter 处理 SimpleController


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

经典实现

模板方法模式通过定义一个算法的骨架,将某些步骤的实现延迟到子类中。这样,子类可以在保留算法结构的同时定制部分实现。

经典代码示例
java 复制代码
public abstract class DataProcessor {
    public void process() {
        readData();
        processData();
        writeData();
    }

    protected abstract void readData();
    protected abstract void processData();
    protected abstract void writeData();
}

public class CSVDataProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("Reading CSV data...");
    }

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

    @Override
    protected void writeData() {
        System.out.println("Writing CSV data...");
    }
}
现代 Java 实现:使用 Lambda 表达式和 Optional

我们可以结合 Lambda 表达式 来动态传入处理步骤,让模板方法的使用更加灵活。

java 复制代码
public abstract class DataProcessor {
    public void process() {
        processStep(this::readData, "Reading");
        processStep(this::processData, "Processing");
        processStep(this::writeData, "Writing");
    }

    private void processStep(Runnable step, String stepName) {
        System.out.println(stepName + " data...");
        step.run();
    }

    protected abstract void readData();
    protected abstract void processData();
    protected abstract void writeData();
}

6. 总结

通过结合现代 Java 特性,我们可以让经典的设计模式变得更加简洁和高效。 Lambda 表达式Stream API 为我们的设计模式实现提供了更灵活的方式,而 Optional 可以帮助我们避免空指针异常,使得代码更加健壮。

在实际的项目开发中,理解和运用设计模式能够大大提高代码的可维护性和可扩展性。希望本文的示例能够帮助你更好地理解设计模式,并在实际开发中灵活运用。

相关推荐
阿珊和她的猫3 小时前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
fouryears_234175 小时前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~6 小时前
C#---StopWatch类
开发语言·c#
桦说编程7 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
lifallen7 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研7 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
快乐的划水a7 小时前
组合模式及优化
c++·设计模式·组合模式
没有bug.的程序员8 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
甄超锋8 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
cui__OaO8 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习