当前位置:首页 > 科技  > 软件

一文彻底搞明白享元模式

来源: 责编: 时间:2024-05-17 17:47:09 277观看
导读本篇讲解Java设计模式中的享元模式,分为定义、模式应用前案例、结构、模式应用后案例、适用场景、模式可能存在的困惑和本质探讨7个部分。定义享元模式指的是运用共享技术有效地支持大量细粒度的对象。在新的分类方式

本篇讲解Java设计模式中的享元模式,分为定义、模式应用前案例、结构、模式应用后案例、适用场景、模式可能存在的困惑和本质探讨7个部分。Sdk28资讯网——每日最新资讯28at.com

定义

享元模式指的是运用共享技术有效地支持大量细粒度的对象。Sdk28资讯网——每日最新资讯28at.com

在新的分类方式中,享元模式被划分至类的属性相关类别中,其应对类的不同对象可以共享内部状态(可共享的属性)的要求。Sdk28资讯网——每日最新资讯28at.com

Sdk28资讯网——每日最新资讯28at.com

模式应用前案例

在享元模式中,我们来看一个文本编辑器的案例。对于文本编辑器来说,可以包括添加文本、显示文本、清空文本等操作。对于其中的文本,都有自身的文本样式。Sdk28资讯网——每日最新资讯28at.com

下面,先来看一下未使用享元模式的案例,代码实现如下。Sdk28资讯网——每日最新资讯28at.com

public class Text {//文本类private final String content;private final TextStyle style;public Text(String content, TextStyle style) {this.content = content;this.style = style;    }public void display() {        System.out.println("Text: " + this.content + ", Style: " + this.style);    }}public class TextStyle {//文本样式类private final String font;private final int size;private final String color;public TextStyle(String font, int size, String color) {this.font = font;this.size = size;this.color = color;    }@Overridepublic String toString() {return "Font: "+ this.font +", Size: "+ this.size +", Color: "+ this.color;    }}public class TextEditor {// 文本编辑器类    List<Text> textList;public TextEditor(){this.textList =new ArrayList<>();    }// 添加文本到编辑器中public void addText(Text text){this.textList.add(text);    }// 显示所有文本内容和样式信息public void displayAllTexts(){for(Text text : this.textList){            text.display();        }    }// 清空所有文本内容public void clearAllTexts(){this.textList.clear();        System.out.println("All texts cleared.");    }}

调用方代码如下。Sdk28资讯网——每日最新资讯28at.com

public class Client {//调用方代码public static void main(String[] args) {// 创建文本编辑器对象        TextEditor textEditor = new TextEditor();// 创建两个相同样式(Arial 12 Black)的文字片段并添加到编辑器中        TextStyle textStyle1 = new TextStyle("Arial", 12, "Black");        Text text1 = new Text("Hello World", textStyle1);        TextStyle textStyle2 = new TextStyle("Arial", 12, "Black");        Text text2 = new Text("Welcome to the world of programming!", textStyle2);        textEditor.addText(text1);        textEditor.addText(text2);// 显示所有文本内容和样式信息        System.out.println("Displaying all texts:");        textEditor.displayAllTexts();// 清空所有文本内容        System.out.println("/nClearing all texts:");        textEditor.clearAllTexts();    }}

在上述代码中,文本样式类是文本类中的属性。对于每一个文本,即便文本样式相同,代码中也会创建新的文本样式类。Sdk28资讯网——每日最新资讯28at.com

直观感觉上,就会觉得此处是否可以复用呢?对于此种场景,就适合使用享元模式来进行处理。Sdk28资讯网——每日最新资讯28at.com

结构

Sdk28资讯网——每日最新资讯28at.com

享元模式的示例代码实现如下。Sdk28资讯网——每日最新资讯28at.com

public interface Flyweight {void Operation(int extrinsicstate);}public class ConereteFlyweight implements Flyweight {@Overridepublic void Operation(int extrinsicstate) {        System.out.println("共享的具体Flyweight:" +extrinsicstate);    }}public class UnsharedConereteFlyweight implements Flyweight{@Overridepublic void Operation(int extrinsicstate) {        System.out.println("不共享的具体Flyweight:" +extrinsicstate);    }}public class FlyweightFactory {private static final Map<String, Flyweight> flyweights = new HashMap<>();public FlyweightFactory() {        flyweights.put("A", new ConereteFlyweight());        flyweights.put("B", new ConereteFlyweight());        flyweights.put("C", new ConereteFlyweight());    }public Flyweight getFlyweight(String key) {return flyweights.get(key);    }}public class Client {public static void main(String[] args) {int extrinsicstate = 1;       FlyweightFactory factory = new FlyweightFactory();       Flyweight fa = factory.getFlyweight("A");       fa.Operation(extrinsicstate);       Flyweight fb = factory.getFlyweight("B");       fb.Operation(extrinsicstate);       Flyweight fc = factory.getFlyweight("C");       fc.Operation(extrinsicstate);       UnsharedConereteFlyweight uf = new UnsharedConereteFlyweight();       uf.Operation(extrinsicstate);    }}

可以发现,在享元模式下,先将类的属性分成两种类别,一类是多个对象可以共享的状态,另一类是多个对象私有的状态。Sdk28资讯网——每日最新资讯28at.com

然后,通过接口或继承实现的一个类家族实现上述两种类别,即图中的Flyweight及具体实现类。Sdk28资讯网——每日最新资讯28at.com

此外,提供一个FlyweightFactory支撑类,这个类的作用就是负责创建一些包含共享状态的对象,然后缓存起来。Sdk28资讯网——每日最新资讯28at.com

当调用方需要用到时,就可以通过FlyweightFactory来获取到共享的状态。同时,那些不能共享的状态(或属性),也可以通过UnsharedConcreteFlyweight类来创建。Sdk28资讯网——每日最新资讯28at.com

模式应用后案例

上述文本编辑器的案例,在使用享元模式后的代码实现如下。Sdk28资讯网——每日最新资讯28at.com

public class Text {//文本类private final String content;private final TextStyle style;public Text(String content, TextStyle style) {this.content = content;this.style = style;    }public void display() {        System.out.println("Text: " + this.content + ", Style: " + this.style);    }}public class TextStyle {//文本样式类private final String font;private final int size;private final String color;public TextStyle(String font, int size, String color) {this.font = font;this.size = size;this.color = color;    }@Overridepublic String toString() {return "Font: "+ this.font +", Size: "+ this.size +", Color: "+ this.color;    }}

文本Text类中的TextStyle属性可以共享,content属性不能共享。因此,可以创建一个TextFactory类来共享TextStyle。Sdk28资讯网——每日最新资讯28at.com

public class TextFactory {//享元工厂类private static final HashMap<String, TextStyle> stylesMap = new HashMap<>();public static TextStyle getTextStyle(String font,int size,String color){        stylesMap.putIfAbsent(font+size+color,new TextStyle(font,size,color));return stylesMap.get(font+size+color);    }}

享元工厂类有了之后,文本编辑器类代码如下。Sdk28资讯网——每日最新资讯28at.com

public class TextEditor {//文本编辑器类    List<Text> textList;public TextEditor(){this.textList =new ArrayList<>();    }// 添加文本到编辑器中public void addText(String content, String font, int size, String color){        TextStyle sharedStyle = TextFactory.getTextStyle(font, size, color);this.textList.add(new Text(content, sharedStyle));    }// 显示所有文本内容和样式信息public void displayAllTexts(){for(Text text : this.textList){            text.display();        }    }// 清空所有文本内容public void clearAllTexts(){this.textList.clear();        System.out.println("All texts cleared.");    }}

调用方代码如下。Sdk28资讯网——每日最新资讯28at.com

public class Client {//调用方代码public static void main(String[] args) {// 创建文本编辑器对象        TextEditor editor = new TextEditor();// 使用编辑器添加相同样式(Arial 12 Black)的文字片段        editor.addText("Hello World", "Arial", 12, "Black");        editor.addText("Welcome to the world of programming!", "Arial", 12,"Black");// 显示所有文本内容和样式信息        System.out.println("Displaying all texts:");        editor.displayAllTexts();    }}

上述代码中,在需要用到TextStyle的地方,通过享元工厂类获取,而不是直接通过new方式创建,这样所有文本类都可以共享一个TextStyle对象,这就是享元模式发挥作用的地方。Sdk28资讯网——每日最新资讯28at.com

适用场景

当程序中需要创建大量对象,并且这些对象共享一部分内部状态,为了节省内存空间,就可以考虑使用享元模式。Sdk28资讯网——每日最新资讯28at.com

比如,在Java语言中,Integer、String等类,由于不同对象可能共享相同的字面量,因此其内部都应用了享元模式。Sdk28资讯网——每日最新资讯28at.com

模式可能存在的困惑

困惑1:享元模式中,经常提到的内部状态与外部状态,是什么含义?Sdk28资讯网——每日最新资讯28at.com

一个类中可以包含多个属性,其中可以被多个对象共享的状态或属性成为“内部状态”,而每个对象独有的属性或状态则成为“外部状态”。Sdk28资讯网——每日最新资讯28at.com

困惑2:结构图中的Client与FlyweightFactory类有交互,但是案例中的TextEditor类中有使用TextFactory类,Client类并没有使用?Sdk28资讯网——每日最新资讯28at.com

在应用设计模式时,有时候不能按照设计模式标准结构来生搬硬套。关键在于理解设计模式的核心思想之后能够灵活运用。Sdk28资讯网——每日最新资讯28at.com

案例中的TextEditor其实相当于结构中的Client。Text类相当于Flyweight类,而TextStyle类Text类中的共享状态。案例的结构与结构中的结构并不完全相同,但是对于享元模式中的共享思想运用是一致的。Sdk28资讯网——每日最新资讯28at.com

困惑3:享元模式相当于是为了对象的复用,以节省存储空间。在日常编程中,像对象池、线程池、连接池等技术也是为了对象的复用,那么区别在哪里呢?Sdk28资讯网——每日最新资讯28at.com

主要区别在于时间观上的不同。对于对象池、线程池、连接池等技术来说,在同一时刻,一个共享的对象只能用于一个调用方。只有该对象使用完毕重新放在池子之后,其他调用方才能使用。Sdk28资讯网——每日最新资讯28at.com

而对于享元模式来说,同一时刻,可以被许多调用方同时共享复用,不需要在时间上错开使用。Sdk28资讯网——每日最新资讯28at.com

本质

享元模式的本质是对类中属性更细粒度的控制。在享元模式中,是通过状态是否共享来分类的。Sdk28资讯网——每日最新资讯28at.com

通过分类,就可以采取不同的操作。在享元模式中,通过状态是否共享这种分类方式,就可以用来节省存储空间,并且节省空间的同时其实也可以节省对象创建的时间。Sdk28资讯网——每日最新资讯28at.com

这里值得提醒一下,时间和空间并不是在任何场景下都是一组矛盾关系,如空间增加可以减少时间,空间变少时间就会加长等。在享元模式中,是对象复杂度的降低导致了空间和时间都在某种程度上都有所减少。Sdk28资讯网——每日最新资讯28at.com

当然,对于类中属性也可能有其他分类方式,如本质属性和偶然属性的划分等。享元模式仅仅是处理这些分类方式中的一种特例。Sdk28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-88926-0.html一文彻底搞明白享元模式

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Spring Boot 内嵌 Web 容器启动原理,惊爆你的眼球!

下一篇: 一篇文章彻底理解 Java 的 Suppressed exceptions 机制

标签:
  • 热门焦点
  • 一加Ace2 Pro真机揭晓 钛空灰配色质感拉满

    终于,在经过了几波预热之后,一加Ace2 Pro的外观真机图在网上出现了。还是博主数码闲聊站曝光的,这次的外观设计还是延续了一加11的方案,只是细节上有了调整,例如新加入了钛空灰
  • 石头自清洁扫拖机器人G10S评测:多年黑科技集大成之作 懒人终极福音

    科技圈经常能看到一个词叫“缝合怪”,用来形容那些把好多功能或者外观结合在一起的产品,通常这样的词是贬义词,但如果真的是产品缝合的好、缝合的实用的话,那它就成了中性词,今
  • 《英雄联盟》夏季赛总决赛今日开打!JDG对阵LNG首发名单来了 Knight:准备三连冠

    8月5日消息,今日17:00,《英雄联盟》2023LPL夏季赛总决赛将正式开打,由JDG对阵LNG。对两支队伍来说,这场比赛不仅要争夺夏季赛冠军,更要决定谁才是LPL赛区一
  • K6:面向开发人员的现代负载测试工具

    K6 是一个开源负载测试工具,可以轻松编写、运行和分析性能测试。它建立在 Go 和 JavaScript 之上,它被设计为功能强大、可扩展且易于使用。k6 可用于测试各种应用程序,包括 Web
  • 得物效率前端微应用推进过程与思考

    一、背景效率工程随着业务的发展,组织规模的扩大,越来越多的企业开始意识到协作效率对于企业团队的重要性,甚至是决定其在某个行业竞争中突围的关键,是企业长久生存的根本。得物
  • 2023年,我眼中的字节跳动

    此时此刻(2023年7月),字节跳动从未上市,也从未公布过任何官方的上市计划;但是这并不妨碍它成为中国最受关注的互联网公司之一。从2016-17年的抖音强势崛起,到2018年的&ldquo;头腾
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 当家的盒马,加速谋生

    来源 | 价值星球Planet作者 | 归去来自己&ldquo;当家&rdquo;的盒马,开始加速谋生了。据盒马官微消息,盒马计划今年开放生鲜供应链,将其生鲜商品送往食堂。目前,盒马在上海已经与
  • Meta盲目扩张致超万人被裁,重金押注元宇宙而前景未明

    图片来源:图虫创意日前,Meta创始人兼CEO 马克&middot;扎克伯发布公开信,宣布Meta计划裁员超11000人,占其员工总数13%。他公开承认了自己的预判失误:&ldquo;不仅
Top