首页 > 其他分享 >能省一点是一点 - 享元模式(Flyweight Pattern)

能省一点是一点 - 享元模式(Flyweight Pattern)

时间:2024-12-27 14:29:30浏览次数:9  
标签:享元 Pattern 模式 AbstractGoChessPieces 能省 Flyweight black white

享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)是一种结构型设计模式,它主要用于减少创建大量细粒度对象所带来的内存占用问题。通过共享尽可能多的对象,即所谓的“享元”,来减少内存使用量和提高性能。这种设计模式特别适合于需要大量创建相同对象的情况。而且不要被享元这个名称迷惑,Flyweight的意思是轻量级的意思,更多的意思,这个模式是想告诉共享内存对象这个意思。

为什么会有这种设计模式
比如,当我们要构建的系统中有大量基本一样的元素的时候。
在这里插入图片描述
小时候我们玩过的像素风的游戏,大家可以看到实际上里面的各种场景就是有大量的基础元素拼装出来的。有很多完全一样的像素块,那对这些像素块,我们不需要每次用的时候都创建新的像素块对象。因为新建新的对象,需要消耗堆内存,而且这种消耗是没有意义的。

享元模式(Flyweight Pattern)概述

当一个软件需要创建大量的对象的时候,就会导致内存消耗过多,系统性能下降。而享元模式就是为了解决这个问题而出现的设计模式。

享元模式(Flyweight Pattern)的核心思想: 如果一个对象实例创建之后不可变的话,反复创建这种实例就变得没有必要,直接向客户端返回一个共享的实例就可以了,这样既节省了内存,还避免了创建对象的过程,提升运行效率。

享元模式包含的角色:

享元模式主要包含以下四种角色

  • 抽象享元(Flyweight)角色:是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
  • 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
  • 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
  • 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检查系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
    在这里插入图片描述

享元模式应用场景

应用场景其实是围绕着享元模式的核心设计思想,减少对象的创建展开的。大致有下面几种:

  1. 软件设计中有大量相似的对象
  2. 缓存场景
  3. 需要多次重复使用某一个对象的时候

talk is cheap, show you my code

在这里插入图片描述
我们设计围棋的时候,会发现,白棋和黑棋会有很多,但是它们都是一样的。所以我们通过利用享元模式来设计创建围棋中的棋子。

围棋棋子 Go chess pieces

public class GoChessPiecesFactory {
    public static Map<String, AbstractGoChessPieces> map = new HashMap<>();

    public static AbstractGoChessPieces getAbstractGoChessPieces(String color) {
        if (map.containsKey(color)) {
            return map.get(color);
        }else {
            if (color.equals("black")) {
                AbstractGoChessPieces black = new BlackGoChessPieces();
                map.put("black", black);
            }
            if (color.equals("white")) {
                AbstractGoChessPieces white = new WhiteGoChessPieces();
                map.put("white", white);
            }
        }
        return map.getOrDefault(color, null);
    }
}

abstract class  AbstractGoChessPieces {
    String color;

    public abstract void display();

}

class BlackGoChessPieces extends AbstractGoChessPieces {

    @Override
    public void display() {
        System.out.println("black");
    }
}

class WhiteGoChessPieces extends AbstractGoChessPieces {

    @Override
    public void display() {
        System.out.println("white");
    }
}

public class Test4 {
    public static void main(String[] args) {
        AbstractGoChessPieces black = GoChessPiecesFactory.getAbstractGoChessPieces("black");
        AbstractGoChessPieces black1 = GoChessPiecesFactory.getAbstractGoChessPieces("black");
        AbstractGoChessPieces black2 = GoChessPiecesFactory.getAbstractGoChessPieces("black");
        AbstractGoChessPieces white = GoChessPiecesFactory.getAbstractGoChessPieces("white");
        AbstractGoChessPieces white1 = GoChessPiecesFactory.getAbstractGoChessPieces("white");
        System.out.println(black == black1);
        System.out.println(black1 == black2);
        System.out.println(white == white1);

        black.display();
        white.display();
    }

}

输出结果

true
true
true
black
white

代码解释:

  1. AbstractGoChessPieces 抽象类 : 定义了一个抽象类 AbstractGoChessPieces,表示围棋棋子的基本属性和行为。
  2. BlackGoChessPieces 类 :继承自 AbstractGoChessPieces,表示黑色棋子。
  3. WhiteGoChessPieces 类 : 继承自 AbstractGoChessPieces,表示白色棋子。
  4. GoChessPiecesFactory 类 :工厂类 GoChessPiecesFactory 负责创建并缓存 AbstractGoChessPieces 的实例。

总结

当代码实现中出现大量相同对象的时候,我们就可以考虑使用享元模式。这种设计模式通过共享对象,节约了内存空间,提升了系统性能。
优点:

  1. 减少内存中的对象数量
  2. 享元模式外部状态不影响内部状态
    缺点:
  3. 享元模式需要隔离出内外两种状态,会使得代码逻辑变得复杂一点

标签:享元,Pattern,模式,AbstractGoChessPieces,能省,Flyweight,black,white
From: https://blog.csdn.net/Zongkunxue/article/details/144753754

相关文章

  • More Effective C++之技术Techniques,Idioms,Patterns_条款25
    MoreEffectiveC++之技术Techniques,Idioms,Patterns条款25:将constructor和non-memberfunction虚化constructor虚化将Non-MemberFunctions的行为虚化    本章描述C++程序员常常遭遇的一些问题的解决办法,这些解法都已获得证明。本书把这样的解法称为techniques......
  • Agentic Design Patterns
    AgenticDesignPatternshttps://www.deeplearning.ai/the-batch/how-agents-can-improve-llm-performance/?ref=dl-staging-website.ghost.io Reflection:TheLLMexaminesitsownworktocomeupwithwaystoimproveit. ToolUse:TheLLMisgiventoolssuch......
  • C# 23种设计模式(5)命令模式(Command Pattern)
    一、命令模式介绍命令模式(CommandPattern)是一种行为设计模式,它将一个请求封装为一个对象,从而允许用户用不同的请求、队列请求、记录请求日志,以及支持可撤销的操作等。命令模式的主要目的是将请求的执行者和请求的接收者解耦,使得请求发送者和接收者之间不必直接交互。 命令......
  • 重要思想之《享元模式》
    实际就是缓冲思想,池化思想。比如线程池、数据库连接池、还有JDK里面也有。Integer里面toString使用享元数据finalstaticchar[]digits={'0','1','2','3','4','5','6','7','8',......
  • 鸿蒙动画开发04——共享元素转场动画
    1概  述在不同页面间,有使用相同的元素(例如有同一幅图)的场景,可以使用共享元素转场动画衔接。为了突出不同页面间相同元素的关联性,可为它们添加共享元素转场动画。如果相同元素在不同页面间的大小有明显差异,即可达到放大缩小视图的效果。例如:有两个页面,A页面只展示一张图片,......
  • IERG3080 Software Patterns
    IERG3080 Fall2024-Group ProjectDue: 23 Dec 2024Instructions:● This projecttakes30%ofthecoursetotal.●   Yourgroup needsto use VisualStudio to implementagame using WPF in C#described inthisspecification,andalsowrite......
  • web.xml 中 url-pattern 设置解析
    在web.xml中使用filter-mapping、servlet-mapping节点下的子节点url-pattern配置映射。Pattern匹配规则精确匹配配置和请求的URL完全相同。<servlet-mapping><servlet-name>indexServlet</servlet-name><url-pattern>/index</url-pattern></servlet-mapping......
  • 享元模式
    ​享元(Flyweight、Cache)模式属于结构型模式的一种。享元模式通过将对象的内部状态和外部状态分开,尽量共享内部状态来减少对象的创建。内部状态是对象可以共享的部分,而外部状态是对象特有的、依赖于环境的部分。享元模式旨在有效共享对象,避免重复创建相同内容的对象,减少内存开销,......
  • [Design Pattern] Encapsulate a network request lib - 4. API Template
    Whencompany'sAPIbecomehugeandalwayschanging,if request-busismaintainedbydevelopersmanually,it'snotonlytimeconsumingbutalsoerrorprone.Wecanintroducesomestandardautomationprocesstoresolvetheproblem. Examples:{......
  • [Design Pattern] Encapsulate a network request lib - 1. DIP: Dependence Inversio
    ThreelayersdesignLowlevelimplementationLayer:usinglowlevelimplementationtocompletebasicoperation.Forthenetworkrequest,wecanusethelibsuchasaxios,whichinternallyusing xhr,orwecanalsouse fetchdirectlyfromnode.jsreque......