津津乐道设计模式 - 享元模式详解(以影院座位举例让你快速掌握)

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

什么是享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在有效地共享对象以减少内存使用和提高性能。该模式通过将对象的部分状态进行共享,以避免创建过多的相似对象,从而节省内存空间。

在这里插入图片描述

享元模式适用场景

  • 当系统中存在大量相似对象时,可以使用享元模式来减少对象的数量,从而节省内存开销。
  • 当对象的大部分状态可以被外部状态替代时,可以将这些外部状态抽取出来共享,而将内部状态作为非共享状态。
  • 当需要对大量的细粒度对象进行操作时,使用享元模式可以减少对象的数量,提高系统性能。

常见的使用场景包括

  • 字符串池:在字符串处理中,常常使用字符串池来共享相同的字符串,以避免重复创建相同内容的字符串对象。
  • 连接池:数据库连接池和线程池是常见的享元模式应用。通过共享数据库连接或线程对象,可以避免频繁地创建和销毁对象,提高系统性能。
  • 缓存系统:在缓存系统中,可以使用享元模式来共享缓存对象,以避免重复创建相同的缓存项。
  • 图形绘制:在图形绘制中,可以使用享元模式来共享相同的图形对象,从而减少内存开销。

总之,享元模式通过共享对象的部分状态来节省内存空间和提高性能,适用于大量相似对象的场景,特别是当对象的内部状态较少且外部状态可被替代时。

生活案例

假设你是影院的管理者,需要管理和显示大量的座位信息。在这个场景中,可以使用享元模式来优化座位对象的创建和管理。
在这里插入图片描述

首先,我们可以创建一个座位类 Seat,该类包含座位的行号和列号等属性。然后,我们创建一个座位工厂类 SeatFactory,用于管理和共享座位对象。

在电影开始之前,当有观众购买座位并入场时,你可以根据座位的行号和列号从工厂中获取对应的座位对象。这样,即使有很多观众,但实际上只需要创建一次相同位置的座位对象,然后共享给多个观众使用,从而减少了对象的数量和内存占用。

当电影院当天关门结束营业后后,你可以清理座位工厂,释放座位对象。

通过使用享元模式,你可以在营业期间高效地管理和共享座位对象,避免了大量重复创建相同位置的座位对象,减少了内存开销,提高了系统性能。

这个生活场景中的座位管理就是享元模式的一个应用示例。通过共享相同的座位对象,我们可以有效地管理和优化座位信息,减少对象的数量,提高系统的效率。

案例代码

首先,创建座位类 Seat

public class Seat {
    private int row;
    private int column;

    public Seat(int row, int column) {
        this.row = row;
        this.column = column;
    }

    public int getRow() {
        return row;
    }

    public int getColumn() {
        return column;
    }
}

然后,创建座位工厂类 SeatFactory

import java.util.HashMap;
import java.util.Map;

public class SeatFactory {
    private static Map<String, Seat> seatMap = new HashMap<>();

    public static Seat getSeat(int row, int column) {
        String key = row + "-" + column;

        if (seatMap.containsKey(key)) {
            return seatMap.get(key);
        } else {
            Seat seat = new Seat(row, column);
            seatMap.put(key, seat);
            return seat;
        }
    }

    public static void clearSeats() {
        seatMap.clear();
    }
}

在使用场景中,生成和管理座位:

public static void main(String[] args) {
    // 生成座位并显示座位信息
    Seat seat1 = SeatFactory.getSeat(1, 1);
    Seat seat2 = SeatFactory.getSeat(1, 2);
    Seat seat3 = SeatFactory.getSeat(2, 1);
    Seat seat4 = SeatFactory.getSeat(2, 2);

    System.out.println(seat1.getRow() + "-" + seat1.getColumn());
    System.out.println(seat2.getRow() + "-" + seat2.getColumn());
    System.out.println(seat3.getRow() + "-" + seat3.getColumn());
    System.out.println(seat4.getRow() + "-" + seat4.getColumn());

    // 从工厂获取座位对象
    Seat seat5 = SeatFactory.getSeat(1, 1);
    Seat seat6 = SeatFactory.getSeat(1, 2);

    System.out.println(seat5.getRow() + "-" + seat5.getColumn());
    System.out.println(seat6.getRow() + "-" + seat6.getColumn());

    // 清理座位工厂
    SeatFactory.clearSeats();
}

在上述代码中,座位工厂类 SeatFactory 使用一个 HashMap 来管理座位对象,通过座位的行号和列号作为键,将座位对象作为值进行存储。当需要获取座位对象时,首先判断工厂中是否已经存在相同位置的座位对象,如果存在,则直接返回该对象;如果不存在,则创建一个新的座位对象,并将其添加到工厂中进行管理。

通过这种方式,我们可以在音乐会期间共享座位对象,避免了重复创建相同位置的座位对象,从而减少了对象的数量和内存占用。

注意:以上代码仅为示例,为了简化代码逻辑,未涉及多线程和线程安全性。在实际应用中,如果存在多个线程并发访问座位工厂,需要考虑线程安全性并进行适当的同步处理。

享元模式优缺点

享元模式的优点:

  • 减少内存占用:通过共享对象,减少了系统中的对象数量,从而降低了内存的占用。
  • 提高性能:由于减少了对象的创建和销毁,提高了系统的运行效率。
  • 简化对象管理:享元模式将共享对象的创建和管理集中在一个工厂类中,简化了对象的管理和维护过程。

享元模式的缺点:

  • 引入共享状态共享对象需要考虑线程安全性,特别是在多线程环境下访问共享对象时需要进行同步处理,这会增加系统的复杂性。
  • 不适用于所有情况:享元模式适用于有大量相似对象需要共享的场景,如果对象差异较大,共享的效果可能会降低,甚至无法使用享元模式。

结语

本章节主要介绍了享元模式、享元模式适用场景、享元模式的优缺点,并以影院座位的生活场景模拟享元模式的样例代码,如果本文对你有用,欢迎关注收藏评论,后续将陆续推出贴切生活的搞笑讲解方式带大家一起学编程~

样例代码:https://github.com/lhmyy521125/toher-designmode

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Micro麦可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值