小白谈谈享元模式

概念

享元模式又称为轻量级模式,它是一种对象结构型模式。该模式主要用于减少创建对象的数量,通过调用已创建的对象实现共享一个单元,从而降低运行的成本,提高性能。

实现

简单地实现享元模式

public class fw1 {

    public static void main(String[] args) {

        String str1 = "ctb";
        String str2 = "ctb";
        String str3 = new String("ctb");
        String str4 = new String("ctb");

        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
        System.out.println(str3.intern() == str1);
        System.out.println(str3 == str4);
        System.out.println(str3.intern() == str4.intern());
    }
}

实验结果:
在这里插入图片描述
解释:第一个和第二个创建的时候为常量,所有他们都是指向常量池中的同一个对象,str3和str4是创建一个新的对象,他们的地址不同,所以指向的对象不同,当str3调用intern()方法时,指的是str3指向常量池的那一部分,所以第三个判断条件为真。这里常量池的设计就用了享元模式,每当调用"ctb"时,都是从常量池中找出来,而不是重新创建的。


样例二:我们都是学生时代的过来人,每次考完试,我们都会根据自己的名字和学号查看自己成绩,现在假定学生通过姓名,学号,科目查看自己单科成绩:
首先定义一个成绩单的接口:

/**
 * 定义成绩单的接口
 */
public interface Report {

    public void show(String subject);
}

具体实现这个成绩单:

public class SchoolReport implements Report {

    //定义成绩单属性-姓名
    private String name;

    //定义成绩单属性-学号
    private int id;

    //定义成绩单属性-成绩
    private static int score = new Random().nextInt(150);

    public SchoolReport(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public void show(String subject) {
        System.out.println("姓名:" + this.name + "  学号" + this.id + " " +subject + "成绩为:" + this.score);
    }
}

定义一个成绩系统用于查询成绩:

/**
 * 定义一个成绩系统用于查询成绩
 */
public class ReportSystem {

    public static Report queryReport(String name,int id){
        return new SchoolReport(name,id);
    }
}

学生端进行测试:ctb去查成绩了:

public class Student {

    public static void main(String[] args) {
        Report report = ReportSystem.queryReport("ctb",5);
        report.show("语文");
    }
}

实现结果:
在这里插入图片描述
分析:我们可以看出每个人在查看成绩的时候都会在查询成绩系统中重新new一个对象出来,所以当小明,小白等多个人都去查看ctb的成绩的时候,那么就会重复new出多个不同的对象,从而使得就一个ctb的成绩把整个学校的查询成绩系统给搞崩了。
因此我们对查询成绩系统进行修改,让他不用重新创建对象,第一次创建对象的时候,把他的成绩放入内存中,当第二次查询的时候,直接从内存中进行调用。
进一步优化查询成绩系统:

/**
 * 定义一个成绩系统用于查询成绩
 */
public class ReportSystem {

    //定义一个容器存放内存
    private static Map<String,Report> map = new ConcurrentHashMap<>();

    public static Report queryReport(String name, int id){

        //判断容器中是否包含已有数据
        if(ReportSystem.map.containsKey(name)){
            System.out.println("通过缓存实现");
            return ReportSystem.map.get(name);
        }

        Report report = new SchoolReport(name,id);
        System.out.println("创建对象实现");

        //放入容器中
        ReportSystem.map.put(name,report);

        return report;
    }
}

2个同学查询ctb成绩:

public class Student {

    public static void main(String[] args) {
        Report report = ReportSystem.queryReport("ctb",5);
        report.show("语文");

        Report report1 = ReportSystem.queryReport("ctb",5);
        report1.show("语文");
  
    }
}

实现结果:
在这里插入图片描述

优点:在一定程度上,减少了对象的创建,极大增强了系统的性能。

缺点:系统需要分离出内部状态和外部状态,使系统变得复杂。


本文的代码:https://pan.baidu.com/s/1ofkUpquobPA0qcj591cI7A
提取码:otot

发布了48 篇原创文章 · 获赞 0 · 访问量 661

猜你喜欢

转载自blog.csdn.net/weixin_44943485/article/details/105238393
今日推荐