23种设计模式之享元模式

发布于:2024-12-07 ⋅ 阅读:(144) ⋅ 点赞:(0)

1. 简介

享元模式(Flyweight Pattern)是一种结构型设计模式。它主要用于减少创建对象的数量,以减少内存占用和提高性能。该模式通过共享已经存在的对象来达到这个目的,这些共享对象被称为享元对象。

  • 结构组成
    • 享元工厂(Flyweight Factory):这是享元模式的核心部分,负责创建和管理享元对象。它维护一个享元对象的池(通常是一个集合,如HashMap),当客户端请求一个享元对象时,享元工厂首先检查对象池中是否已经存在所需的对象。如果存在,就直接返回这个对象;如果不存在,则创建一个新的享元对象,将其添加到对象池中,然后再返回给客户端。
    • 享元对象(Flyweight):这些是可以被共享的对象。享元对象通常包含内部状态,内部状态是可以被共享的,不会因为对象的共享而改变。例如,在一个文本编辑器中,字符的字体、字号等属性可以作为内部状态,因为这些属性在多个字符之间可能是相同的,并且不会因为字符的共享而改变。
    • 外部状态(Extrinsic State):与享元对象的内部状态相对应,外部状态是不能被共享的,它随着环境或者客户端的使用而变化。在文本编辑器的例子中,字符在文档中的位置就是外部状态,因为每个字符的位置是不同的,不能被共享。外部状态通常是通过方法参数等方式传递给享元对象,让享元对象根据外部状态来执行相应的操作。

2. 代码

2.1 Employee (享元对象的抽象)

public interface Employee {
    public void report();
}

2.2 Manager (享元对象)

public class Manager implements Employee{
    private String department;
    private String noteContent;

    public Manager(String department) {
        this.department = department;
    }

    public String getNoteContent() {
        return noteContent;
    }

    public void setNoteContent(String noteContent) {
        this.noteContent = noteContent;
    }

    @Override
    public void report() {
        System.out.println("经理" + department + "报告:" + noteContent);
    }
}

2.3 ManagementFactory (享元工厂)

public class ManagementFactory {

    private static final Map<String, Employee> EMPLOYEE_MAP = new HashMap<>();

    public static Employee getManager(String department) {
        Manager manager = (Manager)EMPLOYEE_MAP.get(department);
        if (manager == null) {
            manager = new Manager(department);
            System.out.println("Creating new manager for " + department);
            manager.setNoteContent("Note content for " + department);
            EMPLOYEE_MAP.put(department, manager);
        }
        return manager;
    }
}

2.4 Test (测试)

public class Test {

    private static final String departments[] = {"广告", "营销", "业务", "市场"};
    public static void main(String[] args) {
        for(String department : departments){
            Employee manager = ManagementFactory.getManager(department);
            manager.report();
        }
    }
}

2.4 运行结果

Creating new manager for 广告
经理广告报告:Note content for 广告
Creating new manager for 营销
经理营销报告:Note content for 营销
Creating new manager for 业务
经理业务报告:Note content for 业务
Creating new manager for 市场
经理市场报告:Note content for 市场

3. 使用场景

  • 图形系统:在图形系统中,很多图形可能具有相同的颜色、形状等内部属性,通过享元模式可以共享这些图形对象,减少对象的创建数量,提高系统性能。
  • 游戏开发:在游戏中,例如游戏场景中有大量相同类型的道具或者角色,这些对象可能只有位置(外部状态)不同,而其他属性(内部状态)相同,享元模式可以用于管理这些对象,降低内存占用。
  • 字符串常量池:在 Java 中,字符串常量池就是享元模式的一个应用。当创建一个字符串字面量时,Java 会首先检查字符串常量池中是否已经存在相同的字符串。如果存在,就直接返回这个字符串的引用;如果不存在,则创建一个新的字符串并添加到常量池中。

4. 优缺点

  • 优点
    • 减少内存占用:通过共享对象,避免了大量相似对象的重复创建,显著减少了内存的使用量,特别是在处理大量具有相同部分的对象时效果明显。
    • 提高性能:对象的创建和销毁是比较消耗资源的操作,享元模式减少了这些操作的次数,从而提高了系统的性能。
  • 缺点
    • 增加复杂性:享元模式的实现需要引入享元工厂来管理享元对象,并且要区分内部状态和外部状态,这增加了代码的复杂性和设计的难度。
    • 需要考虑状态管理:外部状态的传递和管理可能会比较复杂,需要谨慎处理,否则可能会导致逻辑混乱或者错误。

5. 总结

享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。先在工厂获取,获取不到再进行创建,放工厂里面。


网站公告

今日签到

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