笨蛋学设计模式结构型模式-享元模式【13】

这篇具有很好参考价值的文章主要介绍了笨蛋学设计模式结构型模式-享元模式【13】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

7.7享元模式

7.7.1概念

​ 享元模式是通过共享对象减少内存使用,来提高程序性能。在此模式中,分为内部状态和外部状态,其中相似的对象被存储在享元对象内部,并对于所有享元对象都是相同的,且状态通常是不变的。只在需要时内部共享,而不是每次创建新的对象。而外部状态是享元对象依赖的,可能变化的部分。这部分状态不存储在享元对象内部,而是在使用享元对象时传递给对象。

7.7.2场景

​ 在棋类游戏中,棋子可以看作是享元对象,因为棋子与棋子之间有着相同的属性和方法,例如在颜色、大小、移动规则上都有着相同的特质。因此在棋类游戏中,可以使用享元模式来共享相同的棋子对象,避免创建大量的棋子对象,从而提高游戏性能。

7.7.3优势 / 劣势

  • 减少内存消耗:通过共享公共状态,减少创建对象的数量
  • 提升性能:通过共享对象来减少内存中对象的数量,可以减少垃圾回收的频率

  • 线程安全问题:享元模式的对象可能会导致线程安全问题,需要采取一定的措施
  • 适用场景有限:享元模式存在大量相似对象的场景,若不适用,则会导致性能下降,代码复杂度增加

7.7.4享元模式可分为

  • 享元接口Flyweight:所有具体享元类的共享接口,通常包含对外部状态的操作
  • 具体享元类ConcreteFlyweight:继承Flyweight类或实现享元接口,包含内部状态
  • 享元工厂类FlyweightFactory:创建并管理享元对象,当用户请求时,提供已创建的实例或者创建一个
  • 客户端Client:维护外部状态,在使用享元对象时,将外部状态传递给享元对象

7.7.5享元模式

package com.technologystatck.designpattern.mode.flyweight;

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

public class Flyweight {
    public static void main(String[] args) {

        //实例化享元工厂对象
        FlyweightFactory factory = new FlyweightFactory();

        //获取或创建享元对象,并传递外部状态
        Flyweights flyweightA = factory.getFlyweight("A");
        flyweightA.operation("External State A");

        Flyweights flyweightB = factory.getFlyweight("B");
        flyweightB.operation("External State B");

        Flyweights flyweightC = factory.getFlyweight("A");
        flyweightC.operation("External State C");
    }
}
//创建享元接口
interface Flyweights {
    //操作外部状态
    void operation(String extrinsicState);
}

//实现具体享元类,存储内部状态
class ConcreteFlyweight implements Flyweights{

    //内部状态
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String extrinsicState) {
        System.out.println("Intrinsic State: "+intrinsicState+",External State: "+extrinsicState);
    }
}

//创建享元工厂类,创建并管理Flyweight对象,
//当用户请求一个Flyweight时,享元工厂会提供一个已经创建的实例或创建一个
class FlyweightFactory{
    private Map<String,Flyweights> flyweights=new HashMap<>();

    public Flyweights getFlyweight(String key){
        //若没有享元对象时,就将传进来的key值创建一个
        if(!flyweights.containsKey(key)){
            flyweights.put(key,new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }

}

7.7.6实战

7.7.6.1题目描述

​ 在一个图形编辑器中,用户可以绘制不同类型的图形,包括圆形(CIRCLE)、矩形(RECTANGLE)、三角形(TRIANGLE)等。现在,请你实现一个图形绘制程序,要求能够共享相同类型的图形对象,以减少内存占用。

7.7.6.2输入描述

输入包含多行,每行表示一个绘制命令。每个命令包括两部分:

图形类型(Circle、Rectangle 或 Triangle)

绘制的坐标位置(两个整数,分别表示 x 和 y)

7.7.6.3输出描述

对于每个绘制命令,输出相应图形被绘制的位置信息。如果图形是首次绘制,输出 “drawn at”,否则输出 “shared at”。文章来源地址https://www.toymoban.com/news/detail-816480.html

7.7.6.4代码
package com.technologystatck.designpattern.mode.flyweight;

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

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //创建工厂实例
        GraphicFactory graphicFactory = new GraphicFactory();
        while(scanner.hasNext()){
            String command = scanner.nextLine();
            //定义一个静态方法
            proessCommand(graphicFactory,command);
        }
    }
    public static void proessCommand(GraphicFactory graphicFactory,String command){
        //定义数组存放类型变量
        String[] parts = command.split(" ");
        DrawType drawType=DrawType.valueOf(parts[0]);
        int x=Integer.parseInt(parts[1]);
        int y=Integer.parseInt(parts[2]);

        //
        Graphic graphic=graphicFactory.getGraphic(drawType);
        graphic.draw(new ConcretePosition(x,y));
        ((ConcreteGraphic) graphic).setFirstTime(false);
    }
}

//使用枚举创建图形类型
enum DrawType{
    CIRCLE,RECTANGLE,TRIANGLE;
}

//创建坐标类
class ConcretePosition{
    //内部状态
    private int x;
    private int y;

    public ConcretePosition() {
    }

    public ConcretePosition(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

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

    public int getY() {
        return y;
    }

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

//创建图像享元接口
interface Graphic{
    //外部状态
    void draw(ConcretePosition concretePosition);
}

//创建具体图形实现类
class ConcreteGraphic implements Graphic{

    //内部状态
    private DrawType drawType;

    public ConcreteGraphic(DrawType drawType) {
        this.drawType = drawType;
    }

    //检查是否是第一次绘制该图形
    private Boolean isFirstTime=true;

    public Boolean getFirstTime() {
        return isFirstTime;
    }

    public void setFirstTime(Boolean firstTime) {
        isFirstTime = firstTime;
    }

    //描绘图形方法
    @Override
    public void draw(ConcretePosition concretePosition) {
        System.out.println(drawType+(isFirstTime ? "drawn":"shared")+" at ("+
                concretePosition.getX()+" , "+concretePosition.getY()+")");
    }
}

//创建享元图形工厂
class GraphicFactory{
    private Map<DrawType,Graphic> graphicEditors=new HashMap<>();

    //检查是否已创建对象
    public Graphic getGraphic(DrawType drawType){
        //若时第一次创建,就实例化一个新对象,否则就返回已经创建的对象。
        if(!graphicEditors.containsKey(drawType)){
            graphicEditors.put(drawType,new ConcreteGraphic(drawType));
        }
        return graphicEditors.get(drawType);
    }
}

8.1.7总结

  • 享元模式

  • 优点:通过减少创建对象的数量以此来减少内存消耗,提高程序的性能
  • 总结:分为外部状态和内部状态,内部状态主要是大量相似的对象,外部状态是变化较大的对象
  • 场景:用于包含大量相似对象,且对象的内部状态可以共享,外部状态变化较大时

到了这里,关于笨蛋学设计模式结构型模式-享元模式【13】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 笨蛋学设计模式结构型模式-适配器模式【7】

    7.1.1概念 ​ 适配器模式是指将一个类的接口转换成客户端所期望的另一种接口,从而使原本因接口不匹配而无法一起工作的两个类,能够在一起工作。基本上也就是通过增加一个中间层来解决,而适配器扮演的角色恰恰就是这个中间层。 7.1.2场景 ​ 在我们生活中可以看见的

    2024年01月18日
    浏览(37)
  • 设计模式结构型——享元模式

    目录 什么是享元模式 享元模式的实现 享元模式角色 享元模式类图 享元模式代码实现 享元模式的特点 优点 缺点 使用场景 注意事项         享元模式(Flyweight Pattern)是一种结构型设计模式,享元模式中的“享元”指被共享的单元,享元模式通过复用对象,以达到节省

    2024年02月16日
    浏览(47)
  • 【设计模式-3.3】结构型——享元模式

    说明:说明:本文介绍设计模式中结构型设计模式中的,享元模式; 在一些闯关类的游戏,如超级玛丽、坦克大战里面,游戏的背景每一个关卡都不相同,但仔细观察可以发现,其都是用一些基础图标组成的,背景的变化实际上就是改变了其基础图标的位置。 如坦克大战,

    2024年01月16日
    浏览(50)
  • 设计模式之享元模式【结构型模式】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博

    2024年01月25日
    浏览(46)
  • 设计模式(十二):结构型之享元模式

    设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式(七):结构型之适配器模式 设计模式(八):结构型之装

    2024年02月08日
    浏览(56)
  • [设计模式 Go实现] 结构型~享元模式

    享元模式从对象中剥离出不发生改变且多个实例需要的重复数据,独立出一个享元,使多个对象共享,从而节省内存以及减少对象数量。 flyweight.go flyweight_test.go

    2024年01月16日
    浏览(37)
  • 【十】设计模式~~~结构型模式~~~享元模式(Java)

    【学习难度:★★★★☆,使用频率:★☆☆☆☆】         面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。 享元模式正是为解决这一类问题

    2024年02月08日
    浏览(50)
  • 【结构型设计模式】C#设计模式之享元模式

    享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过尽可能共享对象来减少内存使用和提高性能。它将对象分为两种类型:内部状态(Intrinsic State)和外部状态(Extrinsic State)。内部状态是可以共享的,而外部状态是独立于享元对象的,并且在使用时需要注入。 使用

    2024年02月13日
    浏览(39)
  • 【设计模式】第13节:结构型模式之“享元模式”

    所谓“享元”,顾名思义就是被共享的单元。享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。 实现:通过工厂模式,在工厂类中,通过一个Map或者List来缓存已经创建好的享元对象,以达到复用的目的。把实例的共享状态和不共享状态分开。 以下是画

    2024年02月08日
    浏览(41)
  • 【Java 设计模式】结构型之享元模式

    享元模式(Flyweight Pattern)是一种结构型设计模式,它旨在减少对象的数量以节省内存和提高性能。享元模式通过共享大量相似对象的状态,使得这些对象可以共享,而不需要在每个对象中都存储相同的数据。在本文中,我们将深入研究Java中享元模式的定义、结构、使用场景

    2024年01月22日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包