一起来学设计模式之享元模式

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 前言目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~本节给大家讲一下设计模式中的享元模式,并结合实际业务场景给大家讲解如何使用~本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~享元模式享元模式是一种结构型设计模式,其主要目的是通过共享尽可能多的对象来减少内存使用和对象创建的数量。其核心思想是尽可能地共享对象,以减少内存的使用。

前言

目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~

本节给大家讲一下设计模式中的享元模式,并结合实际业务场景给大家讲解如何使用~

本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~

享元模式

享元模式是一种结构型设计模式,其主要目的是通过共享尽可能多的对象来减少内存使用对象创建的数量。其核心思想是尽可能地共享对象,以减少内存的使用。

享元模式中,我们将对象分为两类:内部状态外部状态内部状态是指对象不随着外部环境的变化而变化的状态,而外部状态是指对象随着外部环境的变化而变化的状态。享元模式的重点是共享内部状态,而外部状态则通过参数传递。

// 享元工厂类
class ShapeFactory {
    private static final Map<String, Shape> shapes = new HashMap<>();
    // 获取具体形状
    public static Shape getShape(String color) {
        Shape shape = shapes.get(color);
        if (shape == null) {
            shape = new Circle(color);
            shapes.put(color, shape);
            System.out.println("Creating circle of color : " + color);
        }
        return shape;
    }
}
// 形状接口
interface Shape {
    void draw();
}
// 具体形状类
class Circle implements Shape {
    private String color;
    public Circle(String color) {
        this.color = color;
    }
    @Override
    public void draw() {
        System.out.println("Drawing circle of color : " + color);
    }
}
// 客户端类
public class Client {
    private static final String[] colors = { "Red", "Green", "Blue" };
    public static void main(String[] args) {
        for (int i = 0; i < 20; ++i) {
            Circle circle = (Circle) ShapeFactory.getShape(getRandomColor());
            circle.draw();
        }
    }
    private static String getRandomColor() {
        return colors[(int) (Math.random() * colors.length)];
    }
}

在上面的代码中,我们首先定义了一个Shape接口和一个具体的形状类 Circle。然后,我们创建了一个享元工厂类 ShapeFactory,并在其中维护了一个 Map 对象,用于存储不同颜色的圆形对象。当客户端请求一个圆形对象时,我们首先检查该颜色的圆形对象是否已经存在于 Map 对象中。如果存在,我们直接返回该圆形对象;如果不存在,我们创建一个新的圆形对象,并将其添加到 Map 对象中以备后续使用。

最后,我们在客户端类Client中演示了如何使用享元模式创建不同颜色的圆形对象。在这个例子中,我们模拟了创建20个圆形对象的场景,但实际上只创建了3个不同颜色的圆形对象,大大减少了内存的使用。

最佳实践

电商平台中,商品是非常重要的元素之一,每个商品都有自己的属性和信息,比如商品名称、价格、描述、图片等等。但是在一些场景下,会存在大量相同属性的商品实例,这些实例会占用很多内存资源,降低系统性能。

这个时候就可以使用享元模式,将相同的属性提取出来,共享使用,减少内存占用,提高系统性能。

假设一个商品的属性有:名称、价格、描述和图片,我们先定义一个Product接口:


public interface Product {
    void showInfo();
}

然后定义具体的商品类ConcreteProduct

public class ConcreteProduct implements Product {
    private String name;
    private double price;
    private String description;
    private String image;
    public ConcreteProduct(String name, double price, String description, String image) {
        this.name = name;
        this.price = price;
        this.description = description;
        this.image = image;
    }
    @Override
    public void showInfo() {
        System.out.println("名称:" + name);
        System.out.println("价格:" + price);
        System.out.println("描述:" + description);
        System.out.println("图片:" + image);
    }
}

在这个例子中,ConcreteProduct类包含了所有商品的属性。

为了使用享元模式,我们需要将相同属性的商品实例共享使用,可以使用一个工厂类ProductFactory来管理商品实例。

public class ProductFactory {
    private static final Map<String, Product> products = new HashMap<>();
    public static Product getProduct(String name, double price, String description, String image) {
        String key = name + price + description + image;
        if (products.containsKey(key)) {
            return products.get(key);
        } else {
            Product product = new ConcreteProduct(name, price, description, image);
            products.put(key, product);
            return product;
        }
    }
}

在工厂类中,我们使用一个Map来存储已经创建的商品实例,如果有相同属性的商品需要创建,则直接返回已有的实例,否则创建一个新的实例并添加到Map中。

最后,我们来测试一下:

public class Client {
    public static void main(String[] args) {
        Product p1 = ProductFactory.getProduct("iphone13", 7999.0, "128GB", "iphone13.png");
        Product p2 = ProductFactory.getProduct("iphone13", 7999.0, "128GB", "iphone13.png");
        Product p3 = ProductFactory.getProduct("MacBook Pro", 9999.0, "16GB", "macbook-pro.png");
        p1.showInfo();
        p2.showInfo();
        p3.showInfo();
        System.out.println("p1 == p2:" + (p1 == p2)); // true
    }
}

输出:

//        名称:iphone13
//        价格:7999.0
//        描述:128GB
//        图片:iphone13.png
//        名称:iphone13
//        价格:7999.0
//        描述:128GB
//        图片:iphone13.png
//        名称:MacBook Pro
//        价格:9999.0
//        描述:16GB
//        图片:macbook-pro.png
//        p1 == p2:true

享元模式的优点包括:

  • 节省内存空间:享元模式能够共享一些内部状态,从而减少对象的数量,节省内存空间。
  • 提高性能:由于减少了对象的数量,也减少了对象的创建和销毁的开销,提高了系统的性能。
  • 支持大量细粒度对象的复用:享元模式可以用于细粒度对象的复用,这些对象通常是由于数量庞大,造成系统的性能问题,通过享元模式,可以极大的减少对象的数量,提高系统的性能。
  • 提高系统可扩展性:通过享元模式的拆分,可以分离内部状态和外部状态,从而提高系统的可扩展性。

总之,享元模式能够在一定程度上提高系统的性能可扩展性,特别适合处理大量细粒度对象的情况。

结束语

设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲代理模式~

本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~

相关文章

项目源码(源码已更新 欢迎star⭐️)

Kafka 专题学习

项目源码(源码已更新 欢迎star⭐️)

ElasticSearch 专题学习

项目源码(源码已更新 欢迎star⭐️)

往期并发编程内容推荐

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

博客(阅读体验较佳)

















相关文章
|
4月前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
88 4
|
4月前
|
设计模式
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
|
2天前
|
设计模式 Java
Java设计模式-享元模式(12)
Java设计模式-享元模式(12)
|
1月前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
2月前
|
设计模式 存储 JavaScript
js设计模式【详解】—— 享元模式
js设计模式【详解】—— 享元模式
43 6
|
3月前
|
设计模式 缓存 Java
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
|
3月前
|
设计模式 存储 Java
Java设计模式之享元模式详解
Java设计模式之享元模式详解
|
3月前
|
设计模式
享元模式-大话设计模式
享元模式-大话设计模式
|
4月前
|
设计模式 Go
[设计模式 Go实现] 结构型~享元模式
[设计模式 Go实现] 结构型~享元模式
|
4月前
|
设计模式 Java 开发者
【搞懂设计模式】享元模式:共享节约,皆大欢喜!
【搞懂设计模式】享元模式:共享节约,皆大欢喜!
78 0