设计模式----享元模式

享元模式

1.什么是享元模式

享元模式就像是一个池,可以把系统中需要用到的类给存入里面 但需要使用的时候就可以直接往里面拿,这样就可以节省内存和效率

并且同一种类型的对象可以不止存一个 因为他是分为内部状态和外部状态 外部状态相当于map的key 内部状态相当于value,这就代表着外部状态不能相同但内部状态可以,内部状态可以说同一种类型的类但key必须不同,用key来代表一个类在不同的使用场景的使用。

2.享元模式是做什么的

1、享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

2、在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

3.享元模式的应用场景

1、系统中有大量对象。

2、这些对象消耗大量内存。

3、这些对象的状态大部分可以外部化

4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。

5、系统不依赖于这些对象身份,这些对象是不可分辨的。

简单来说就是:1、系统有大量相似对象。 2、需要缓冲池的场景。

4.使用享元模式的好处

1.降低内存占用 : 减少在内存中创建对象的数量 , 节省了内存 , 提高了效率 ;

2.减少创建对象开销 : 创建对象时需要占用一定的开销 , 如 new 操作 ; 可能构造函数中有访问 文件 , 数据库 , 网络 等操作 , 也可以避免这些开销 ;

名词解释

细粒度对象 : 是内存中的数量庞大的对象 ; 实际使用的数量庞大的对象 ;

共享对象 : 多个细粒度对象共享的部分数据 ; 对象缓存池中存储的对象 ;

概念引入 : 区分内部状态外部状态的目的是为了维护享元模式的对象池 , 当用户想要使用某个对象时 , 如何确定对象池中的对象是否是用户想要调用的对象呢 , 这里就需要一些数据进行对比 , 数据一致 , 就说明是用户想要的对象 , 数据不一致 , 就需要创建新对象 , 放入对象池 ;

1. 内部状态 : 对象的内部状态不能作为对象对比的依据 , 所有对象的内部状态都是一样的数据

2. 外部状态 : 对象的外部状态每个都不一样 , 每个对象都有一个唯一 外部状态 值 , 类似于 身份证 , 哈希码 这一类的信息 ;

3. 身份标识 : 在线程池中 , 使用外部状态信息 , 唯一确定一个对象 , 作为对象的标识信息 ;

代码

父类接口的作用:在集合中只需要存入父类接口 实现了这个接口的子类都可以存入这个集合 并且在返回的时候也只需要返回父类接口类型 他的所有子类都可以通过强转来调用这个方法

接口

//接口的作用:
//在享元模式的工厂中 只需要返回这个接口的类型 那么只要实现了这个接口的类都可以接收
public interface Shape {
    void draw();
}

实现接口的子类

User

package bean;

public class Circle implements Shape{
    private String name;

    @Override
    public void draw() {
        System.out.println("Circle  draw");
    }
    
    public Circle(String name) {
        this.name = name;
    }

}

Circle

package bean;

public class User implements Shape{
    private String name;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void draw() {
        System.out.println("user draw");
    }
}

工厂

import java.util.HashMap;

//创建一个工厂,生成基于给定信息的实体类的对象。
public class FlyweightPattern {
    //存放的位置
    private static final HashMap<String, Shape> MAP = new HashMap<>();

    //在这里为了易于理解 我写两个方法  分别代表两个类的返回
    public static Shape getCircle (String name){
        //先看看 传入方法的外部状态在集合中是否存在
        Circle circle = (Circle) MAP.get(name);
        //在集合中不存在代表这个外部状态是第一次创建
        if(circle==null){
            //创建新的对象
            circle = new Circle(name);
            //把新创建的对象存入集合 方便下次使用的时候调用
            MAP.put(name, circle);
            System.out.println("Circle: " + name);
        }
        return circle;
    }

    public static Shape getUser(String name){
        //先看看 传入方法的外部状态在集合中是否存在
        User user = (User) MAP.get(name);
        //在集合中不存在代表这个外部状态是第一次创建
        if(user==null){
            //创建新的对象
            user = new User(name);
            //把新创建的对象存入集合 方便下次使用的时候调用
            MAP.put(name, user);
            System.out.println("User: " + name);
        }
        return user;
    }
}

测试

import bean.User;

public class Demo{
    private static final String colors[] =
            { "1", "3"};
    public static void main(String[] args) {
        //创建10次
        for (int i = 0; i < 7; i++) {
            System.out.println("----------第"+(i+1)+"次创建对象---------");
            User user = (User) FlyweightPattern.getUser(getRandomName());
            user.draw();
        }
    }

    //模拟用户创建对象
    private static String getRandomName() {
        //通过随机数来悬着集合中的名称  来创建对象
        return colors[(int)(Math.random()*colors.length)];
    }
}

测试结果

----------第1次创建对象---------
User: 1
user draw
----------第2次创建对象---------(这些就是在集合中已经存在的 就直接调用)
user draw
----------第3次创建对象---------
User: 3
user draw
----------第4次创建对象---------(这些就是在集合中已经存在的 就直接调用)
user draw
----------第5次创建对象---------(这些就是在集合中已经存在的 就直接调用)
user draw
----------第6次创建对象---------(这些就是在集合中已经存在的 就直接调用)
user draw
----------第7次创建对象---------(这些就是在集合中已经存在的 就直接调用)
user draw
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值