zoukankan      html  css  js  c++  java
  • GoF23种设计模式之结构型模式之享元模式

    一、概述 

            运用共享技术有效地支持大量细粒度的对象。

    二、适用性

    1.当一个应用程序使用了大量的对象的时候。

    2.由于使用大量的独享而造成很大的存储开销的时候。

    3.对象的大多数状态都可变为外部状态的时候。

    4.如果删除对象的外部状态,那么可以用相对较少的共享独享取代很对组对象的时候。

    5.应用程序不依赖于对象标识的时候。由于享元模式对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

    三、参与者

    1.Flyweight:描述一个接口,通过这个接口Flyweight可以接受和作用于对象外部状态。

    2.ConcreteFlyweight:实现Flyweight接口,并为内部状态(如果有)增加存储空间。

    3.UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但并不强制共享。在Flyweight对象结构的某些层次上,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。

    4.FlyweightFactory:创建并管理Flyweight对象。确保合理地共享Flyweight对象。当用户请求一个Flyweight对象时,FlyweightFactory提供一个已经创建好的的实例或者创建一个新的实例给它。

    四、类图


    五、示例

    Flyweight

    package cn.lynn.flyweight;
    
    public interface IPerson {
        
        public void say(int num);
    
    }
    
    ConcreteFlyweight
    package cn.lynn.flyweight;
    
    public class PersonImpl implements IPerson {
    
        @Override
        public void say(int num) {
            System.out.println("报数:" + num);
        }
    
    }
    
    FlyweightFactory
    package cn.lynn.flyweight;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class PersonCache {
    
        private static Map<String, PersonImpl> personPool = new HashMap<String, PersonImpl>();
        
        public PersonCache(String key) {
            personPool.put(key, new PersonImpl());
        }
        
        public static IPerson getPerson(String key) {
            if(personPool.get(key) == null) {
                personPool.put(key, new PersonImpl());
            }
            return personPool.get(key);
        }
        public static int getSize() {
            return personPool.size();
        }
    }
    
    Client
    package cn.lynn.flyweight;
    
    public class Client {
    
        public static void main(String[] args) {
            IPerson p1 = PersonCache.getPerson("张三");
            p1.say(1);
            
            IPerson p2 = PersonCache.getPerson("张三");
            System.out.println("p1和p2是同一个人吗?" + ((p1 == p2) ? "是" : "不是"));
            
            IPerson p3 = PersonCache.getPerson("李四");
            p3.say(2);
            
            IPerson p4 = PersonCache.getPerson("王五");
            p4.say(3);
            
            IPerson p5 = PersonCache.getPerson("赵六");
            p5.say(4);
            
            System.out.println("现有人数:" + PersonCache.getSize());
        }
    
    }

    Result

    报数:1
    p1和p2是同一个人吗?是
    报数:2
    报数:3
    报数:4
    现有人数:4
  • 相关阅读:
    QML控件设置style样式
    QML:ListElement: cannot use script for property value
    内存更换乌龙事件
    服务器的寿命到底有多长
    这些年渠道管理系统上发生的那些事
    IT囧事之误删测试环境的生产库
    旁观一个软件产品的终结
    一根网线引发的血案
    论代码规范命名的重要性
    服务器故障之内存损坏
  • 原文地址:https://www.cnblogs.com/innosight/p/3271154.html
Copyright © 2011-2022 走看看