享元模式

基本介绍

1.享元模式,又称蝇量模式:

2.运用共享技术实现大量细粒度对象的复用

 

应用

1.享元模式是池技术的重要实现方式

2.池技术:String 常量池、数据库连接池、缓冲池

3.常用于系统底层开发,解决系统的性能问题:如数据库连接池,池中是创建好的连接对象,若池中有符合需求的对象时直接用,避免重新创建;若池中没有符合需求的,则创建一个

 

要求

1.细粒度、共享对象

2..将对象的信息分为两个部分

(1)内部状态:指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变的状态

(2)外部状态:指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态

 

角色

1.FlyWeight:抽象的享元角色,产品的抽象类,定义了对象的外部状态和内部状态的接口或实现

2.ConcreteFlyWeight:具体的享元角色,产品的实现类,实现了抽象角色定义的相关业务

3.UnSharedConcreteFlyWeight:不可共享的角色,一般不会出现在享元工厂中

4.FlyWeightFactory:享元工厂类,内部提供一个池容器,储存ConcreteFlyWeight,同时提供从池中存取数据的操作

 

事项

1.享:共享,元:对象

2.应用场景:系统中有大量对象,这些对象消耗大量内存,并且对象的状态大部分可以外部化时

3.一般用 HashMap / HashTable 存储 ConcreteFlyWeight,key作为唯一标识码判断 ConcreteFlyWeight

4.优点

(1)解决重复对象的内存浪费的问题,减少了对象的创建,降低了程序内存的占用,提高效率

(2)提高了系统的复杂度,需要分离出内部状态和外部状态

5.缺点

(1)提高了系统的复杂度,需要分离出内部状态和外部状态。而外部状态具有固化特性,不应该随着内部状态的改变而改变

 

JDK 中的 Integer

public class Flyweight {

    public static void main(String[] args) {
        Integer a = Integer.valueOf(127);
        Integer b = new Integer(127);
        Integer c = Integer.valueOf(127);

        System.out.println(a.equals(b));//true:a、b比较大小
        System.out.println(a == b);//false:a是从池中取出的对象,b是直接new
        System.out.println(a == c);//true:a、c都是从池中取出的对象
        System.out.println(b == c);//false:c是从池中取出的对象,b是直接new

        Integer d = Integer.valueOf(128);
        Integer e = Integer.valueOf(128);
        Integer f = new Integer(128);

        System.out.println(d.equals(e));//true:d、e比较大小
        System.out.println(d == e);//false:d、e超出范围,各自new一个对象
        System.out.println(d == f);//false:d、f各自new一个对象
        System.out.println(e == f);//false:e、f各自new一个对象

        /*
        public static Integer valueOf(int i) {
            //IntegerCache是池,若i在池的范围内(-128<= i <= 127),从池取出
            if (i >= Integer.IntegerCache.low && i <= Integer.IntegerCache.high)
                return Integer.IntegerCache.cache[i + (-Integer.IntegerCache.low)];
            //若i超出池的范围,则new一个,并装箱返回,但不会加入池中
            return new Integer(i);
        }
         */
    }
}

 

代码示例

import java.util.HashMap;

public class Flyweight {//客户端

    public static void main(String[] args) {
        WebSiteFactory webSiteFactory = new WebSiteFactory();
        User sina = new User("新浪");
        User huawei = new User("华为");
        User amazon = new User("亚马逊");
        WebSite portal = webSiteFactory.getWebSiteCategory("门户类");
        WebSite enterprise = webSiteFactory.getWebSiteCategory("企业类");
        WebSite sale = webSiteFactory.getWebSiteCategory("销售类");
        portal.use(sina);
        enterprise.use(huawei);
        sale.use(amazon);
        System.out.println("网站类型总数:" + webSiteFactory.getWebSiteCount());
    }
}

class WebSiteFactory {//享元工厂类
    private HashMap<String, ConcreteWebSite> pool = new HashMap<>();//充当池的作用

    //根据网站的类型,在池中返回一个网站
    public WebSite getWebSiteCategory(String type) {
        if (!pool.containsKey(type)) {
            //若池中没有该类型的网站,在池中创建一个网站,并返回
            pool.put(type, new ConcreteWebSite(type));
        }
        return pool.get(type);
    }

    //获取池中有多少个网站类型
    public int getWebSiteCount() {
        return pool.size();
    }
}


abstract class WebSite {//抽象享元角色

    public abstract void use(User user);
}

class ConcreteWebSite extends WebSite {//具体的享元角色
    private String type;//内部状态

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

    @Override
    public void use(User user) {
        System.out.println("网站形式:" + type + ",用户:" + user.name);
    }

}

class User {//不可共享角色
    public String name;//外部状态

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

 

posted @ 2022-03-10 17:44  半条咸鱼  阅读(460)  评论(0编辑  收藏  举报