【设计模式】3W 学习法全面解析 7 大结构型模式:Java 实战 + 开源框架应用

发布于:2025-03-20 ⋅ 阅读:(7) ⋅ 点赞:(0)

3W 学习法总结结构型模式(附 Java 代码实战及开源框架应用)

结构型模式 主要关注 类与对象的组合,确保不同组件之间能够高效协作,提高系统的灵活性和可维护性。本文采用 3W 学习法(What、Why、How),深入分析 七大结构型模式(适配器、桥接、装饰器、组合、外观、享元、代理),并结合 Java 代码实战开源框架中的应用,帮助你高效掌握这些模式的实战技巧。


1. 适配器模式(Adapter)

✅ What:适配器模式是什么?

适配器模式 通过 转换接口 使原本不兼容的类能够一起工作。

🤔 Why:为什么要使用适配器模式?

  • 解决接口不兼容问题,让新旧代码无缝衔接。
  • 复用已有代码,避免修改原始代码。

🚀 How:如何实现适配器模式?(Java 代码实战)

// 目标接口
interface Target {
    void request();
}

// 需要适配的类
class Adaptee {
    void specificRequest() {
        System.out.println("Adaptee 特定请求");
    }
}

// 适配器
class Adapter implements Target {
    private Adaptee adaptee = new Adaptee();

    public void request() {
        adaptee.specificRequest();
    }
}

// 客户端调用
public class AdapterDemo {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.request(); // 输出: Adaptee 特定请求
    }
}

📌 在开源框架中的应用:

  • Spring HandlerAdapter:适配不同类型的 Controller(如 RequestMappingHandlerAdapter)。
  • java.io.InputStreamReader:将 InputStream 适配为 Reader

2. 桥接模式(Bridge)

✅ What:桥接模式是什么?

桥接模式 通过 分离抽象部分和实现部分,让它们可以独立变化。

🤔 Why:为什么要使用桥接模式?

  • 降低耦合:抽象和实现独立演化,不受对方影响。
  • 增强扩展性:适用于 多个维度变化 的场景。

🚀 How:如何实现桥接模式?(Java 代码实战)

// 实现接口
interface Implementor {
    void operationImpl();
}

// 具体实现A
class ConcreteImplementorA implements Implementor {
    public void operationImpl() {
        System.out.println("具体实现A的操作");
    }
}

// 抽象类
abstract class Abstraction {
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    abstract void operation();
}

// 具体抽象类
class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    public void operation() {
        implementor.operationImpl();
    }
}

// 客户端调用
public class BridgeDemo {
    public static void main(String[] args) {
        Implementor impl = new ConcreteImplementorA();
        Abstraction abstraction = new RefinedAbstraction(impl);
        abstraction.operation(); // 输出: 具体实现A的操作
    }
}

📌 在开源框架中的应用:

  • JDBC 驱动java.sql.DriverManager 通过桥接不同数据库的驱动。
  • Slf4j + Logback/Log4j:日志框架使用桥接模式适配不同日志实现。

3. 装饰器模式(Decorator)

✅ What:装饰器模式是什么?

装饰器模式 通过 动态添加新功能,而不修改原有对象。

🤔 Why:为什么要使用装饰器模式?

  • 符合开闭原则:可扩展对象功能,避免修改原始代码。
  • 支持功能叠加:适用于 多个额外行为 组合的场景。

🚀 How:如何实现装饰器模式?(Java 代码实战)

// 抽象组件
interface Component {
    void operation();
}

// 具体组件
class ConcreteComponent implements Component {
    public void operation() {
        System.out.println("基本功能");
    }
}

// 装饰器
abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

// 具体装饰器A
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        System.out.println("附加功能A");
    }
}

// 客户端调用
public class DecoratorDemo {
    public static void main(String[] args) {
        Component component = new ConcreteDecoratorA(new ConcreteComponent());
        component.operation();
        // 输出:
        // 基本功能
        // 附加功能A
    }
}

📌 在开源框架中的应用:

  • Spring BeanPostProcessor:可动态增强 Bean 的功能。
  • BufferedInputStream:装饰 InputStream,提供缓冲能力。

4. 组合模式(Composite)

✅ What:组合模式是什么?

组合模式 允许 树形结构的对象 统一处理。

🤔 Why:为什么要使用组合模式?

  • 统一对象处理方式:无论是单个对象还是组合对象,均可一致调用。
  • 适用于层级结构:如 文件系统、组织架构 等。

🚀 How:如何实现组合模式?(Java 代码实战)

// 抽象组件
interface Component {
    void operation();
}

// 叶子节点
class Leaf implements Component {
    public void operation() {
        System.out.println("执行叶子节点操作");
    }
}

// 组合节点
class Composite implements Component {
    private List<Component> children = new ArrayList<>();

    public void add(Component component) {
        children.add(component);
    }

    public void operation() {
        for (Component child : children) {
            child.operation();
        }
    }
}

// 客户端调用
public class CompositeDemo {
    public static void main(String[] args) {
        Composite root = new Composite();
        root.add(new Leaf());
        root.add(new Leaf());

        Composite branch = new Composite();
        branch.add(new Leaf());
        root.add(branch);

        root.operation();
    }
}

📌 在开源框架中的应用:

  • Spring Security:权限规则采用组合模式组织权限节点。
  • GUI 组件:Swing 的 JComponent 使用组合模式。

确实,结构型模式共有 7 种,前面只介绍了 4 种,缺少了 外观模式(Facade)、享元模式(Flyweight)、代理模式(Proxy)。下面继续补充它们的 3W 学习法解析、Java 实战代码及在开源框架中的应用


5. 外观模式(Facade)

✅ What:外观模式是什么?

外观模式(Facade) 通过 提供一个统一的接口,简化子系统的复杂操作,降低系统耦合性。

🤔 Why:为什么要使用外观模式?

  • 降低复杂性,隐藏子系统细节,使调用者只需与一个简单接口交互。
  • 解耦代码,避免高层代码直接依赖多个复杂子系统。

🚀 How:如何实现外观模式?(Java 代码实战)

// 子系统A
class SubsystemA {
    void operationA() {
        System.out.println("子系统 A 操作");
    }
}

// 子系统B
class SubsystemB {
    void operationB() {
        System.out.println("子系统 B 操作");
    }
}

// 外观类(Facade)
class Facade {
    private SubsystemA subsystemA = new SubsystemA();
    private SubsystemB subsystemB = new SubsystemB();

    void operation() {
        subsystemA.operationA();
        subsystemB.operationB();
    }
}

// 客户端调用
public class FacadeDemo {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.operation();
        // 输出:
        // 子系统 A 操作
        // 子系统 B 操作
    }
}

📌 在开源框架中的应用:

  • Spring JdbcTemplate:封装了数据库操作,简化 JDBC 使用。
  • HttpClient:简化底层 HTTP 请求的复杂性。

6. 享元模式(Flyweight)

✅ What:享元模式是什么?

享元模式(Flyweight) 通过 共享对象 来减少内存占用,提高性能。

🤔 Why:为什么要使用享元模式?

  • 减少内存开销,适用于 大量相似对象 场景。
  • 提升系统性能,避免重复创建对象。

🚀 How:如何实现享元模式?(Java 代码实战)

import java.util.HashMap;
import java.util.Map;

// 享元接口
interface Flyweight {
    void operation(String extrinsicState);
}

// 具体享元
class ConcreteFlyweight implements Flyweight {
    private final String intrinsicState;

    ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    public void operation(String extrinsicState) {
        System.out.println("享元对象:" + intrinsicState + ",外部状态:" + extrinsicState);
    }
}

// 享元工厂
class FlyweightFactory {
    private static final Map<String, Flyweight> pool = new HashMap<>();

    static Flyweight getFlyweight(String key) {
        if (!pool.containsKey(key)) {
            pool.put(key, new ConcreteFlyweight(key));
        }
        return pool.get(key);
    }
}

// 客户端调用
public class FlyweightDemo {
    public static void main(String[] args) {
        Flyweight fw1 = FlyweightFactory.getFlyweight("A");
        Flyweight fw2 = FlyweightFactory.getFlyweight("A");
        Flyweight fw3 = FlyweightFactory.getFlyweight("B");

        fw1.operation("X");
        fw2.operation("Y");
        fw3.operation("Z");

        System.out.println(fw1 == fw2); // 输出: true(共享同一个对象)
    }
}

📌 在开源框架中的应用:

  • Integer.valueOf(int):JDK 享元模式,缓存 -128 ~ 127 的 Integer 对象。
  • 线程池(Thread Pool):复用线程对象,减少资源消耗。

7. 代理模式(Proxy)

✅ What:代理模式是什么?

代理模式(Proxy) 通过 控制访问目标对象,增加额外行为(如权限控制、懒加载、缓存等)。

🤔 Why:为什么要使用代理模式?

  • 增强功能(如日志、事务、权限)。
  • 控制对象访问(如远程代理、虚拟代理)。

🚀 How:如何实现代理模式?(Java 代码实战)

静态代理
// 接口
interface Service {
    void operation();
}

// 真实对象
class RealService implements Service {
    public void operation() {
        System.out.println("真实业务逻辑");
    }
}

// 代理类
class ProxyService implements Service {
    private RealService realService = new RealService();

    public void operation() {
        System.out.println("前置增强逻辑");
        realService.operation();
        System.out.println("后置增强逻辑");
    }
}

// 客户端调用
public class StaticProxyDemo {
    public static void main(String[] args) {
        Service service = new ProxyService();
        service.operation();
        // 输出:
        // 前置增强逻辑
        // 真实业务逻辑
        // 后置增强逻辑
    }
}
动态代理(JDK 动态代理)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {
    private Object target;

    DynamicProxyHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置增强逻辑");
        Object result = method.invoke(target, args);
        System.out.println("后置增强逻辑");
        return result;
    }
}

// 客户端调用
public class DynamicProxyDemo {
    public static void main(String[] args) {
        Service realService = new RealService();
        Service proxy = (Service) Proxy.newProxyInstance(
            realService.getClass().getClassLoader(),
            realService.getClass().getInterfaces(),
            new DynamicProxyHandler(realService)
        );

        proxy.operation();
        // 输出:
        // 前置增强逻辑
        // 真实业务逻辑
        // 后置增强逻辑
    }
}

📌 在开源框架中的应用:

  • Spring AOP:代理模式增强 Bean 功能,如事务、日志、权限控制。
  • MyBatis Mapper:动态代理生成 SQL 查询接口的实现类。

总结

设计模式 主要作用 适用场景
适配器模式 让不兼容的接口协同工作 HandlerAdapterInputStreamReader
桥接模式 分离抽象和实现,解耦 JDBC 驱动、日志框架
装饰器模式 动态增强对象功能 BufferedInputStreamBeanPostProcessor
组合模式 统一树形结构处理 Spring Security 权限管理、GUI 组件
外观模式 简化系统调用 JdbcTemplateHttpClient
享元模式 共享对象减少内存消耗 Integer.valueOf(int)、线程池
代理模式 控制访问目标对象,增强功能 AOP、MyBatis 动态代理

掌握这 7 大结构型模式,让你的代码 更清晰、可扩展、性能更优!🚀


网站公告

今日签到

点亮在社区的每一天
去签到