享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享大量细粒度对象来减少内存消耗。享元模式的核心思想是将多个相似的对象共享起来,从而避免对象的大量创建,节省内存资源。

场景说明

假设你正在开发一个绘图应用程序,用户可以在画布上绘制许多形状。每个形状都有相同的颜色和大小属性,但它们的位置不同。使用享元模式可以将相同属性的形状对象共享,从而减少内存消耗。

享元模式结构

  1. Flyweight(享元):定义了对象的内部状态,这些状态是可以共享的。
  2. ConcreteFlyweight(具体享元):实现Flyweight接口,并且将可共享的状态存储在内部。
  3. FlyweightFactory(享元工厂):负责创建和管理享元对象,确保享元对象的共享性。
  4. Client(客户端):维护对享元对象的引用,并且通过享元工厂来获取享元对象。

代码实现

下面是一个使用享元模式的Java示例,演示如何在绘图应用程序中使用享元模式来优化内存使用。

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

// 享元接口
interface Shape {
    void draw();
}

// 具体享元类:圆形
class Circle implements Shape {
    private String color;
    private int x;
    private int y;
    private int radius;

    public Circle(String color) {
        this.color = color;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    @Override
    public void draw() {
        System.out.println("Circle: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :" + radius);
    }
}

// 享元工厂类
class ShapeFactory {
    private static final Map<String, Shape> circleMap = new HashMap<>();

    public static Shape getCircle(String color) {
        Circle circle = (Circle) circleMap.get(color);

        if (circle == null) {
            circle = new Circle(color);
            circleMap.put(color, circle);
            System.out.println("Creating circle of color : " + color);
        }
        return circle;
    }
}

// 客户端代码
public class FlyweightPatternDemo {
    private static final String[] colors = {"Red", "Green", "Blue", "White", "Black"};

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
            circle.setX(getRandomX());
            circle.setY(getRandomY());
            circle.setRadius(100);
            circle.draw();
        }
    }

    private static String getRandomColor() {
        return colors[(int) (Math.random() * colors.length)];
    }

    private static int getRandomX() {
        return (int) (Math.random() * 100);
    }

    private static int getRandomY() {
        return (int) (Math.random() * 100);
    }
}

输出结果

plaintext 复制代码
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 36, y :56, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 23, y :34, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 45, y :66, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 88, y :96, radius :100
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 73, y :29, radius :100
Circle: Draw() [Color : Red, x : 12, y :10, radius :100
Circle: Draw() [Color : Green, x : 87, y :53, radius :100
...

代码解释

  • Shape接口 :定义了draw()方法,所有具体享元类都要实现这个接口。
  • Circle类 :是具体享元类,实现了Shape接口。Circle类中包含了一个color属性,它是内部状态并且可以共享,其他属性如xyradius是外部状态,由客户端设置。
  • ShapeFactory类 :是享元工厂类,负责创建和管理享元对象。它通过检查已存在的对象来确保相同颜色的Circle对象只创建一次,并在后续使用时进行共享。
  • FlyweightPatternDemo:是客户端代码,模拟了创建和绘制多个圆形对象的场景。通过享元工厂获取Circle对象,并设置外部状态进行绘制。

总结

享元模式通过共享对象来减少内存消耗,特别适用于大量细粒度对象的场景。然而,在使用享元模式时,需要注意区分对象的内部状态(共享部分)和外部状态(不共享部分),以确保对象的正确性和一致性。

相关推荐
AI科技星2 分钟前
科幻艺术书本封面:《全域数学》第一部·数术本源 第三卷 代数原本(P95-141)完整五级目录【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
风筝在晴天搁浅3 分钟前
LeetCode 92.反转链表Ⅱ
算法·leetcode·链表
王老师青少年编程17 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【贪心与二分判定】:数列分段 Section II
c++·算法·贪心·csp·信奥赛·二分判定·数列分段 section ii
Java小生不才31 分钟前
Spring AI文生音
java·人工智能·spring
凯尔萨厮34 分钟前
Springboot2.x+Thymeleaf项目创建
java
V搜xhliang024639 分钟前
OpenClaw科研全场景用法:从文献到实验室的完整自动化方案
运维·开发语言·人工智能·python·算法·microsoft·自动化
fish_xk1 小时前
map和set
java·开发语言
汉克老师1 小时前
GESP2025年3月认证C++五级( 第三部分编程题(2、原根判断))
c++·算法·模运算·gesp5级·gesp五级·原根·分解质因数
李崧正1 小时前
Java技术分享:Lambda表达式与函数式编程
java·开发语言·python
老了,不知天命1 小时前
鳶尾花項目JAVA
java·开发语言·机器学习