Java设计模式-享元模式

享元模式

1.享元模式含义

享元模式,运用共享技术有效地支持大量细粒度的对象。

其实享元模式很好理解,就是共享元数据的意思。比如一个小狗类对象,里面的属性有头,耳朵,眼睛,毛色这几个属性,然后需要实例化几个小狗对象出来,但是这几个小狗对象的头、耳朵、眼睛属性值都是相同的,只有毛色是不一样的,那么这种情况下这几个小狗属性就可以共用一个bean的头、耳朵、眼睛属性,然后再各自重新实现自己的不同的毛色属性值。这样的共用基础元数据的模式,就叫享元模式。

2.代码示例

下面以用户登录网站的代码作为示例讲解享元模式

2.1User类

java 复制代码
public class User {
    private String name;

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

    public String getName() {
        return name;
    }
}

2.2WebSite类

WebSite是网站抽象类,定义了一个展示当前登录用户的抽象方法

java 复制代码
public abstract class WebSite {
    public abstract void user(User user);
}

2.3ConcreteWebSite类

ConcreteWebSite是WebSite的具体实现类

java 复制代码
public class ConcreteWebSite extends WebSite{
    private String name;

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

    @Override
    public void user(User user) {
        System.out.println("网站分类:" + name + "用户:" + user.getName());
    }
}

2.4WebSiteFactory类

WebSiteFactory类是WebSIte的工厂类,负责为客户端生成WebSite子类对象

java 复制代码
public class WebSiteFactory {
    private Map<String, WebSite> webSiteMap = new HashMap<>();

    public WebSite getWebSiteCategory(String name){
        if (!webSiteMap.containsKey(name)) {
            webSiteMap.put(name, new ConcreteWebSite(name));
        }
        return webSiteMap.get(name);
    }

    public int getWebSiteCount(){
        return webSiteMap.size();
    }
}

2.5测试类

java 复制代码
public class MainApp {
    public static void main(String[] args) {
        WebSiteFactory factory = new WebSiteFactory();

        WebSite bilibili = factory.getWebSiteCategory("哔哩哔哩");
        bilibili.user(new User("秋秋"));

        WebSite bilibili2 = factory.getWebSiteCategory("哔哩哔哩");
        bilibili2.user(new User("张三"));

        WebSite bilibili3 = factory.getWebSiteCategory("哔哩哔哩");
        bilibili3.user(new User("李四"));

        WebSite csdn = factory.getWebSiteCategory("CSDN");
        csdn.user(new User("王五"));

        WebSite csdn1 = factory.getWebSiteCategory("CSDN");
        csdn1.user(new User("领克03"));

        System.out.println("网站实例对象个数为:" + factory.getWebSiteCount());
    }
}

运行结果

网站分类:哔哩哔哩用户:秋秋

网站分类:哔哩哔哩用户:张三

网站分类:哔哩哔哩用户:李四

网站分类:CSDN用户:王五

网站分类:CSDN用户:领克03

网站实例对象个数为:2

从运行结果可以看出,一共有3五个用户登录了网站,但是最终网站的实例对象个数仅为2,也就是说,登录哔哩哔哩网站的用户共享了哔哩哔哩网站实例对象,登录CSDN网站的用户共享了CSDN网站实例对象。这就是享元模式,五个用户,分别共享了两个网站的实例对象。

如果没有使用享元模式,那么五个对象登录网站,就要实例化五个网站对象,但是如果真的实例化五个网站对象的话,就是浪费内存空间了,因为这五个网站对象完全一模一样,仅仅是登录的用户名称不一样,改为享元模式,用户共享网站实例对象,这样就可以节省很大的内存开销了。

3.总结

享元模式里面涉及到两个概念,内部状态与外部状态

  • 内部状态:内部状态就是在享元对象内部,并且不会岁环境改变而改变的部分,比如ConcreteWebSite类中的name属性,可以认为是内部状态,虽然它的值也会被改变,但是相对来说,被改变的几率比较小,可以认为是内部状态
  • 外部状态:外部状态跟内部状态相反,它是随着环境的改变而改变。不可以共享的状态就是外部状态,比如ConcreteWebSite类的User对象

如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用享元模式,还有救赎对象的大多数状态可以为外部状态。

如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

相关推荐
憧憬成为java架构高手的小白1 小时前
LangGraph4j 实战(下)
java
天诰2 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
这个昵称不容易5 小时前
SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在
java·springboot·毕设
计算机毕设定制辅导-无忧学长6 小时前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
文丑颜不良啊7 小时前
LeetCode2221~2240题目解析
java·leetcode
秋饼7 小时前
Computer Use Agent Java 落地实战:感知-行动循环、执行器与安全围栏生产级实现
java·ai·技术分享·后端开发
心若自由何处是束缚9 小时前
适配器模式:从原理到实战的完整指南
设计模式·适配器模式
文丑颜不良啊9 小时前
LeetCode2161~2180题目解析
java·leetcode
文丑颜不良啊11 小时前
LeetCode2141~2160题目解析
java·leetcode
LabVIEW开发11 小时前
LabVIEW 连接板:28 个端子怎么排,优先级怎么定
java·算法·labview