享元模式

享元模式(Flyweight Pattern)是池技术的重要实现方式,其定义如下:Use sharing to
support large numbers of fine-grained objects efficiently.(使用共享对象可有效地支持大量的细
粒度的对象。)
享元模式的定义为我们提出了两个要求:细粒度的对象和共享对象。我们知道分配太多
的对象到应用程序中将有损程序的性能,同时还容易造成内存溢出,那怎么避免呢?就是享
元模式提到的共享技术。我们先来了解一下对象的内部状态和外部状态。
要求细粒度对象,那么不可避免地使得对象数量多且性质相近,那我们就将这些对象的
信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic)。
● 内部状态
内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境改变而改变,
如我们例子中的id、postAddress等,它们可以作为一个对象的动态附加信息,不必直接储存
在具体某个对象中,属于可以共享的部分。
● 外部状态
外部状态是对象得以依赖的一个标记,是随环境改变而改变的、不可以共享的状态,如
我们例子中的考试科目+考试地点复合字符串,它是一批对象的统一标识,是唯一的一个索
引值。

● 内存泄漏
无意识的代码缺陷,导致内存泄漏,JVM不能获得连续的内存空间。
● 对象太多
代码写得很烂,产生的对象太多,内存被耗尽。现在的情况是没有内存泄漏,那只有一
种原因——代码太差把内存耗尽。

● 考试科目,选择框。
● 考试地点,选择框,根据科目不同,列表不同。
● 准考证邮寄地址,输入框。
还有其他一堆信息,我们以这三者作为代表来讲解。信息填写完毕后,点击确认,报名
就结束了。简单程序的业务逻辑也确实是这样,为什么出现Crash情况呢?那肯定是和压力
有关系!
我们先把这个过程的静态类图画出来,如图

很简单的工厂方法模式,表现层通过工厂方法模式创建对象,然后传递给业务层和持久
层,最终保存到数据库中,为什么要使用工厂方法模式而不用直接new一个对象呢?因为是
在框架下编程,必须有一个对象工厂(ObjectFactory,Spring也有对象工厂)。

package FlyweightP;

public class SignInfo {
    //报名人员的ID
    private String id;
    //考试地点
    private String location;
    //考试科目
    private String subject;
    //邮寄地址
    private String postAddress;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getLocation() {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getPostAddress() {
        return postAddress;
    }
    public void setPostAddress(String postAddress) {
        this.postAddress = postAddress;
    }
}
package FlyweightP;

public class SignInfoFactory {
    public static SignInfo getSignInfo(){
        return new SignInfo();
    }
}
package FlyweightP;

public class Client {
    public static void main(String[] args) {
        SignInfo signInfo = SignInfoFactory.getSignInfo();
    }
}

我们自己来设计一个共
享对象池,需要实现如下两个功能。
● 容器定义
我们要定义一个池容器,在这个容器中容纳哪些对象。
● 提供客户端访问的接口
我们要提供一个接口供客户端访问,池中有可用对象时,可以直接从池中获得,否则建
立一个新的对象,并放置到池中。

package FlyweightP;

public class SignInfoPool extends SignInfo {
    //定义一个对象池提取的key值
    private String key;
    public SignInfoPool(String key){
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
package FlyweightP;

public class Client {
    public static void main(String[] args) {
      //  SignInfo signInfo = SignInfoFactory.getSignInfo();
        //初始化对象池
        for(int i=0;i<4;i++){
            String subject = "科目" + i;
//初始化地址
            for(int j=0;j<30;j++){
                String key = subject + "考试地点"+j;
                SignInfoFactory.getSignInfo(key);
            }
        }
        SignInfo signInfo = SignInfoFactory.getSignInfo("科目1考试地点1");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值