zoukankan      html  css  js  c++  java
  • Java设计模式-享元模式

    介绍:享元模式意思是说系统中含有很多相同的对象,这时候没有必要用这么多的相同的对象,既大量消耗内存又没有用,这个对象只要一个就可以了,大家共享一个对象,享元模式主要减少了对象的创建,以减少内存和提高性能为目的。享元模式试图重用已有对象,找到可以用的对象就用,如果没有找到再进行创建。

    提到享元模式,就要提到工厂模式,他们经常一起出现。在对象池应用。在对象池中放入对象,在下一次用的时候先到池子中查找是否有这个对象,没有再创建.

    通常使用HashMap来存储这些对象,每个对象用一个标识来区别,String应用到了享元模式,创建的String对象会在常量池中。用户创建String对象,jvm先到常量池中查找是否有此对象,有就直接返回当前对象的地址值赋值给创建的对象,没有再创建。这里说一下String,由于他是final关键字修饰的类,所以决定了他的不可变性,注意是引用不可变,引用指向的内容是可以改变的,就比如创建一个StringBuffer对象,

    final StringBuffer a=new StringBuffer("immutable");
    执行如下语句将报告编译期错误:

    a=new StringBuffer("");
    但是,执行如下语句则可以通过编译:

    a.append(" broken!");

    public class StringTest {
        public static void main(String[] args) {
            String a = "abc";
            String b = "abc";
            System.out.println(a == b);
        }
    }
    

    我们知道==比较的是地址值,以上代码的运行结果是true。

    实例:

    创建一个实体类Phone:

    package demo_flyweight;
    
    public class Phone {
        
        public String sign;
        public String model;
        public String modelnumber;
    
        public Phone(String sign, String model, String modelnumber) {
            this.sign = sign;
            this.model = model;
            this.modelnumber = modelnumber;
        }
    
        public Phone() {
        }
    
        public String getSign() {
            return sign;
        }
    
        public void setSign(String sign) {
            this.sign = sign;
        }
    
        public String getModel() {
            return model;
        }
    
        public void setModel(String model) {
            this.model = model;
        }
    
        public String getModelnumber() {
            return modelnumber;
        }
    
        public void setModelnumber(String modelnumber) {
            this.modelnumber = modelnumber;
        }
        
    }
    

    Iphone类:

    package demo_flyweight;
    
    public class Iphone extends Phone {
    
        public String model;
    
        @Override
        public String getModel() {
            return model;
        }
    
        @Override
        public void setModel(String model) {
            this.model = model;
        }
    }
    

    创建一个工厂类,运用单例模式,生成对象,包括一个对象池,一个获取对象的方法

    package demo_flyweight;
    
    /*创建一个对象池,向池子中放入对象,用户创建对象的时候会先进行判断是否存在*/
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class PhoneFactory {
    
        private static Map<String, Iphone> objectPool;
        private static PhoneFactory phoneFactory;
    
        public static PhoneFactory getInstance() {
            if (phoneFactory == null) {
                phoneFactory = new PhoneFactory();
            }
            return phoneFactory;
        }
    
        private PhoneFactory() {
            objectPool = new HashMap<String, Iphone>();
        }
    
        public static Iphone getPhone(String model) {
            Iphone iphone = objectPool.get(model);
            if (iphone == null) {
                iphone = new Iphone();
                iphone.setModel(model);
                objectPool.put(model, iphone);
            }
            return iphone;
        }
    }
    

    主要的方法是getPhone,当用户调用此方法想要获取对象的时候,程序会先到对象池中找是否有这个对象,,判断是否有,如果没有就创建,创建之后还要把这个对象放入对象池中,方便后面使用,最后返回此对象

    测试类:

    package demo_flyweight;
    
    /*测试类*/
    
    public class Test {
    
        public static void main(String[] args) {
            PhoneFactory phoneFactory = PhoneFactory.getInstance();
            Iphone i1 = PhoneFactory.getPhone("iphone1");
            Iphone i2 = PhoneFactory.getPhone("iphone2");
            Iphone i3 = PhoneFactory.getPhone("iphone2");
            Iphone i4 = PhoneFactory.getPhone("iphone3");
            Iphone i5 = PhoneFactory.getPhone("iphone3");
            System.out.println(i1.hashCode());
            System.out.println(i2.hashCode());
            System.out.println(i3.hashCode());
            System.out.println(i4.hashCode());
            System.out.println(i5.hashCode());
    
        }
    }
    

    创建对象,设置他们的标识,测试输出他们的hash值,每个对象对应的哈希值应该是唯一的

    输出:

    150145122
    533361599
    533361599
    611651815
    611651815

    从输出结果可以看出,我们虽然new了5个对象,其实只创建了3个

    优缺点:

    享元模式在数据库连接池和线程池中应用还是很广的,提高了系统运行的速度,也大量节约了资源。

    享元模式可以极大地减少系统中对象的数量。但是它可能会引起系统的逻辑更加复杂化。

    享元模式的核心在于享元工厂,它主要用来确保合理地共享使用享元对象。




  • 相关阅读:
    Leetcode951. Flip Equivalent Binary Trees翻转等价二叉树
    Leetcode938. Range Sum of BST二叉搜索树的范围和
    Leetcode962. Maximum Width最大宽度坡 Ramp
    STL容器-deque-双端队列
    Leetcode950. Reveal Cards In Increasing Order按递增顺序显示卡牌
    idea修改运行内存
    Web服务器进程连接数和请求连接数
    Vue问题总结
    Vue项目搭建过程
    去掉vue 中的代码规范检测(Eslint验证)
  • 原文地址:https://www.cnblogs.com/duzhentong/p/7816583.html
Copyright © 2011-2022 走看看