【设计模式】享元模式

  |   0 评论   |   108 浏览

简介

可以减少对象的数量,通过共享技术使程序不用重复创建对象,属于结构型模式。

适用场景

1、用于底层开发,提升系统的性能
2、存在大量相似对象,可以进行缓冲

优点

1、减少对象的创建,降低内存中的对象数量,降低系统的内存,提高效率
2、减少资源占用,如时间、句柄等

缺点

1、需要关注内部、外部状态
2、需要关注线程安全问题
3、系统逻辑复杂化

扩展

内部状态:内部状态是不变的(与上下文无关),因此可以共享,如类内部变量。
外部状态:外部状态是可变的(依赖于上下文),因此不能共享,必须传入,如方法中的参数,根据传入的参数不同处理不同的逻辑。

代码示例

image.png
背景描述:公司员工年底要写总结,写过了之后就不用再写了。
员工接口

public interface Employee {
    void readSummary();
}

程序员

public class RDEmployee implements Employee{
    //属于内部状态
    private String department = "研发中心";
    private String name;
    //属于外部状态
    private String summaryContent;
    public void writeSummary(String content){
        summaryContent=content;
    }
    public RDEmployee(String name) {
        this.name = name;
        System.out.println("创建员工"+name);
    }
    public void readSummary() {
        System.out.println(summaryContent);
    }
}

员工工厂类

public class EmployeeFactory {
    public final static Map<String,Employee> EMPLOYEE_MAP = new HashMap<String, Employee>();
    public static Employee getEmployee(String name){
        RDEmployee employee = (RDEmployee)EMPLOYEE_MAP.get(name);
        if(null == employee){
            employee = new RDEmployee(name);
            employee.writeSummary(name+"员工写的总结内容为。。。");
            EMPLOYEE_MAP.put(name,employee);
        }
        return employee;
    }
}

测试类

public class FlyweightTest {
    private static final String[] names = {"zhangsan","lisi","wangwu","zhaoliu"};
    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            String name = names[(int)(Math.random() * names.length)];
            RDEmployee rdEmployee = (RDEmployee) EmployeeFactory.getEmployee(name);
            rdEmployee.readSummary();
        }

    }
}

输出结果

创建员工lisi
lisi员工写的总结内容为。。。
创建员工wangwu
wangwu员工写的总结内容为。。。
lisi员工写的总结内容为。。。
创建员工zhangsan
zhangsan员工写的总结内容为。。。
wangwu员工写的总结内容为。。。
zhangsan员工写的总结内容为。。。
lisi员工写的总结内容为。。。
wangwu员工写的总结内容为。。。
创建员工zhaoliu
zhaoliu员工写的总结内容为。。。
zhangsan员工写的总结内容为。。。

从结果中可以看出,员工只会创建一次。
上面示例源码

源码分析

jdk中应用

在Integer中也有享元模式的应用,

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

IntegerCache缓存了-128到127的数字,如果超过这个区间的值,那么会new一个Integer对象。

tomcat中应用

GenericKeyedObjectPool类中poolMap是用来存储ObjectDeque对象的:
image.png
image.png

也可以关注我的公众号:程序之声
图片
关注公众号,领取更多资源

本文为博主原创文章,未经博主允许不得转载。

评论

发表评论