首页 > 文章列表 > 怎么使用Java享元设计模式优化对象创建提高性能和效率

怎么使用Java享元设计模式优化对象创建提高性能和效率

java
108 2023-05-20

怎么使用Java享元设计模式优化对象创建提高性能和效率

介绍

Java中的享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享尽可能多的对象来减少内存占用和提高性能.

Java享元模式通常包含以下4种角色

  • 享元工厂(Flyweight Factory):负责创建和管理享元对象.

  • 具体享元(Concrete Flyweight):实现享元接口并存储与共享状态相关的内部状态.

  • 抽象享元(Flyweight):定义享元对象需要实现的接口或抽象类.

  • 非共享状态(Unshared State):储存享元对象的非共享状态.

注意:抽象享元和非共享状态角色是可选的,可以省略它们将其功能合并到其他角色中

当客户端请求创建或访问一个享元对象时,享元工厂会检查是否已经创建了该对象.如果已经创建,则返回现有对象的引用;如果尚未创建,则创建新的对象并返回其引用.这样客户端可以共享现有对象,而不必创建新的对象,从而减少内存占用和提高性能.

实现

以电商中的商品信息为例,在电商中,每个商品都有一个名称,价格,库存等属性.通常情况下,每个商品都需要单独创建一个对象,这样会导致内存占用增加,而且如果多次购买相同的商品,系统会创建多个相同的对象,浪费资源.

抽象享元

public interface Product {

    String getName();

    double getPrice();

    int getStock();

}

具体享元

public class ConcreteProduct implements Product{

    private String name;

    private double price;

    private int stock;

    public ConcreteProduct(String name, double price, int stock) {

        this.name = name;

        this.price = price;

        this.stock = stock;

    }

    @Override

    public String getName() {

        return name;

    }

    @Override

    public double getPrice() {

        return price;

    }

    @Override

    public int getStock() {

        return stock;

    }

}

享元工厂

public class ProductFactory {

    private static Map<String, Product> productMap = new HashMap<>();

    public static Product getProduct(String name, double price, int stock) {

        String key = name + "_" + price;

        Product res = productMap.get(key);

        if (Objects.isNull(res)) {

            // 如果缓存池内不存在,就创建新对象放置到缓存池

            res = new ConcreteProduct(name, price, stock);

            productMap.put(key, res);

        }

        return res;

    }

}

测试

public class Demo {

    public static void main(String[] args) {

        Product p1 = ProductFactory.getProduct("iPhone 14 Plus", 8899, 1);

        Product p2 = ProductFactory.getProduct("iPhone 14 Plus", 8899, 1);

        System.out.println(p1 == p2);

    }

}

在上面示例代码中,首先创建一个商品接口Product,其中包含了商品的名称,价格,库存等属性.然后创建具体的商品类ConcreteProduct,实现Product接口,并定义共享的内部状态name,price,和stock.接下来我们创建商品工厂ProductFactory,用于创建和管理共享的商品对象,在这个工厂中,我们使用HashMap来储存共享的商品对象,每当客户端需要购买一个商品时,我们先检查是否已经创建了该商品对象,如果已经创建,则返回现有对象的引用,如果未创建,则创建新的对象储存到HashMap并返回其引用.

总结

优点

  • 减少对象的创建,节省内存空间,提高系统性能.

  • 通过共享对象,可以使得系统中的相同对象在内存中只存在一份,从而减少内存的开销.

  • 提高系统的可扩展性,如果需要增加新的对象,只需要在工厂中创建即可,不需要修改原有代码.

  • 提高系统的安全性,共享对象是只读的,不会被修改.

缺点

  • 可能会使得系统变得过于复杂,增加了代码的复杂性.

  • 需要额外的工作来维护共享对象的一致性,比如需要考虑线程安全等问题.

  • 可能会因为共享对象的存在而降低程序的灵活性,比如无法对共享对象进行个性化设置.

应用场景

  • 当系统中存在大量相同或相似的对象时,可以考虑使用享元模式来减少内存开销.

  • 当需要缓存对象并且可以复用时,也可以考虑使用享元模式.

  • 在多线程环境下,可以使用享元模式来实现对象的共享,提高程序的并发性能.

  • 在游戏开发中,可以使用享元模式来管理游戏中的角色等对象.