java中装饰模式

目录

一 装饰模式案例说明

1.1 说明

1.2 代码

1.2.1 定义数据服务接口

1.2.2 定义基础数据库服务实现

1.2.3  日志装饰器

1.2.4 缓存装饰器

1.2.5 主程序调用

1.3 装饰模式的特点


一 装饰模式案例说明

1.1 说明

本案例是:数据查询增加缓存,使用到了装饰模式

1.装饰器链构建

new CachingDecorator(new LoggingDecorator(new DatabaseService()))

2.顺序是:缓存装饰器包裹日志装饰器,日志装饰器包裹基础数据库服务

3.流程

  1. 第一次查询 (user_123):

    • 进入缓存装饰器:缓存中没有,继续向下

    • 进入日志装饰器:记录开始日志

    • 进入数据库服务:执行实际查询

    • 返回日志装饰器:记录完成日志

    • 返回缓存装饰器:缓存结果

    • 最终返回结果给主程序

  2. 第二次查询 (user_123):

    • 缓存装饰器发现缓存中存在,直接返回

    • 不会触发日志和数据库查询

1.2 代码

1.2.1 定义数据服务接口

public interface DataService {
    String fetchData(String userId);
}

1.2.2 定义基础数据库服务实现

public class DatabaseService implements DataService {
    @Override
    public String fetchData(String userId) {
        // Simulate fetching data from a database
        return "db中数据00: " + userId;
    }
}

1.2.3  日志装饰器

public class LoggingDecorator  implements DataService {
    private final DataService wrappedService;
    public LoggingDecorator(DataService wrappedService) {
        this.wrappedService = wrappedService;
    }

    @Override
    public String fetchData(String userId) {
        System.out.println("查询db中内容: " + userId);
        String result = wrappedService.fetchData(userId);
        System.out.println("logging查询db: " + result);
        return result;
    }
}

1.2.4 缓存装饰器

public class CachingDecorator implements DataService {
    private final DataService wrappedService;
    private final Map cache = new HashMap<>();

    public CachingDecorator(DataService wrappedService) {
        this.wrappedService = wrappedService;
    }

    @Override
    public String fetchData(String userId) {
        if (cache.containsKey(userId)) {
            System.out.println("查询缓存获取内容: " + userId);
            return cache.get(userId);
        } else {
            String result = wrappedService.fetchData(userId);
            cache.put(userId, result);
            return result;
        }
    }
}

1.2.5 主程序调用

public class TestZs {
    public static void main(String[] args) {
        DataService service = new CachingDecorator(new LoggingDecorator(new DatabaseService()));
        String result = service.fetchData("user_123");
        System.out.println("main方法显示结果:"+result);
        System.out.println("====================");
        // Fetching again to demonstrate caching
        result = service.fetchData("user_123");
        System.out.println(result);
    }
}

结果:

java中装饰模式_第1张图片

1.3 装饰模式的特点

关键点说明
装饰器顺序很重要:

如果把缓存装饰器放在最内层,日志每次都会记录

当前顺序确保了缓存命中时不会产生日志

线程安全:

使用 ConcurrentHashMap 保证缓存操作的线程安全

扩展性:

可以轻松添加其他装饰器(如性能监控、权限检查等)

透明性:

客户端代码不需要知道具体实现细节

这种设计模式非常适合需要动态添加功能的场景,同时保持了代码的整洁和可维护性

你可能感兴趣的:(java,设计模式,java,开发语言)