`

android 设计模式-享元模式

 
阅读更多

享元(FlyWeight)模式,原意是“轻量级”模式,它用来解决大量相同对象被多次实例化,从而导致内存被大量占用的情况。在有的时候我们要多次使用某个类中的公有实例方法,我们通常的做法是,先new一个该类的实例,然后再调用该类的这个方法,调用完毕后这个类也就变成垃圾。这种调用方式如果出现的频率很高,会在对象生成和内存占用上付出很大的代价,享元模式尽可能多地节省对象的生成次数,让多个对象共用一个缓存中的对象。
享元模式中关键要理解“内蕴状态”(Internal State)和“外蕴状态”(External State)这两个概念。
    内蕴状态:存储在享元对象内部,不随着环境改变,要以被诸多对象共享。
    外蕴状态:一般由客户端指定,并传入享元对象内部,它随着环境进行变化。
   
举例:
    1、QQ好友管理器:管理并显示每一个好友发来的消息。在聊天的过程中,与一个好友之间的通信联系只通过一个享元对象实现消息的发送与接收,而不是每次发送接收消息都生成一个新的对象。
   2、网吧管理软件:在网吧管理软件中,客户机软件向服务器软件发出请求(如:举手、上线解屏、下线锁屏......),服务器软件也会向客户机发出指令(如:远程关机,远程监视......),不管客户端与服务器端发生多少次交互,在服务器端每个客户端只保留一个对象实例,服务器与每个客户端之间通信就是通过该对象来实现的。


结构图:


抽象享元(Flyweight):为具体享元规定出需要实现的公共接口。

具体享元(ConcreteFlyweight):实现抽象享元角色所规定的接口。如果有“内蕴状态”的话,将“内蕴状态”声明为成员变量,从而使享元对象拥用固定的“内蕴状态”。

享元工厂(FlyweightFactory):负责创建和管理享元角色,保证享元对象可以被共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有符合要求的享元对象。如果已经有了,享元工厂就应当提供这个现有享元对象;如果系统中没有适当的享元对象,享元工厂角色就应当创建一个合适的享元对象。

客户端(Client):维护一个对所有享元对象的引用。提供与管理享元对象的“外蕴状态”。

结构图的示意代码:
    //抽象享元
    abstract class FlyWeight
    {
        //传入外蕴状态
        public abstract void Operation(string extrinsicState);
        //显示内蕴状态和外蕴状态
        public abstract void Show();
    }
    //具体享元A
    class ConcreteFlyWeightA : FlyWeight
    {
       //内蕴状态变量
        private string intrinsicState = "FlyWeightA";
        //外蕴状态变量
        private string extrinsicState ;
        public override void Operation(string extrinsicState)
        {
            this.extrinsicState = extrinsicState;
        }
        public override void Show()
        {
            Console.WriteLine(this.intrinsicState+"\t"+this.extrinsicState);
        }
    }
    //具体享元B
    class ConcreteFlyWeightB : FlyWeight
    {
        //内蕴状态变量
        private string intrinsicState = "FlyWeightB";
        //外蕴状态变量
        private string extrinsicState;
        public override void Operation(string extrinsicState)
        {
            this.extrinsicState = extrinsicState;
        }
        public override void Show()
        {
            Console.WriteLine(this.intrinsicState + "\t" + this.extrinsicState);
        }
    }
    //享元工厂,管理享元对象
    class FlyWeightFactory
    {
        //保存享元对象
        private Hashtable t = new Hashtable();
        public FlyWeightFactory()
        {
            t.Add("A", new ConcreteFlyWeightA());
            t.Add("B",new ConcreteFlyWeightB());
        }
        //根据传入的内蕴状态,构造或返回享元对象,
        public FlyWeight GetFlyWeight(string key)
        {
            if (t.ContainsKey(key))
            {
                return (FlyWeight)t[key];
            }
            return null;
        }
    }
    class Class1
    {
      
        public static void Main(string[] args)
        {
            FlyWeightFactory f = new FlyWeightFactory();
            //这里会根据传入的关键字A,返回享元对象A
            FlyWeight fw1 = f.GetFlyWeight("A");
            fw1.Operation("A's Extinsic State");
            fw1.Show();
            //这里会根据传入的关键字B,返回享元对象B
            FlyWeight fw2 = f.GetFlyWeight("B");
            fw2.Operation("B's Extinsic State");
            fw2.Show();
           //这里会根据传入的关键字A,返回享元对象A
            FlyWeight fw3 = f.GetFlyWeight("A");
            fw3.Operation("Another A's Extinsic State");
            fw3.Show();
        }
    }

 

享元模式是一种针对大量细粒度对象有效使用的一种模式。Android中的Message、Parcel和TypedArray都利用了享元模式。以Message为例,类图如下:

clip_image002
    其中Message通过next成员变量保有对下一个Message的引用,从而构成了一个Message链表。Message Pool就通过该链表的表头管理着所有闲置的Message,一个Message在使用完后可以通过recycle()方法进入Message Pool,并在需要时通过obtain静态方法从Message Pool获取。实现代码如下:
public final class Message implements Parcelable {
    ......
    // sometimes we store linked lists of these things
    /*package*/ Message next;
    private static final Object sPoolSync = new Object();
    private static Message sPool;
    private static int sPoolSize = 0;
    private static final int MAX_POOL_SIZE = 10;
    /**
     * Return a new Message instance from the global pool. Allows us to
     * avoid allocating new objects in many cases.
     */
    public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }
    ......
    public void recycle() {
        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                clearForRecycle();
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }
    ......
    /*package*/ void clearForRecycle() {
        what = 0;
        arg1 = 0;
        arg2 = 0;
        obj = null;
        replyTo = null;
        when = 0;
        target = null;
        callback = null;
        data = null;

分享到:
评论
1 楼 onlyxing 2012-04-18  
这种模式好用吗 能讲的通俗一点吗

相关推荐

    Android设计模式(详细讲解了10个Android设计模式)

    详细讲解了组合模式、观察者模式、单例模式、模板方法模式、备忘录模式、享元模式、命令模式、工厂方法模式、适配器模式 原型模式等10个Android设计模式,和CSDN上其他讲Android设计模式的文章完全不同。讲解详细,...

    Android源码设计模式解析与实战

    本书专门介绍Android源代码的设计模式,共26章,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。主要内容为:优化代码的首步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...

    Android 源码设计模式解析与实战

    本书专门介绍Android源代码的设计模式,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。本书的主要内容为:优化代码的第一步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...

    Android源码设计模式解析与实战PDF

    本书专门介绍Android源代码的设计模式,共26章,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。主要内容为:优化代码的首步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...

    《Android 源码设计模式解析与实战》

    本书专门介绍Android源代码的设计模式,共26章,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。主要内容为:优化代码的首步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...

    何红辉关爱民-Android源码设计模式解析与实战(带书签第2版).pdf

    本书专门介绍Android源代码的设计模式,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。本书的主要内容为:优化代码的第 一步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...

    何红辉关爱民-Android源码设计模式解析与实战(带书签高清第2版).pdf

    本书专门介绍Android源代码的设计模式,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。本书的主要内容为:优化代码的第一步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...

    DesignPattern:23种设计模式,Android原始设计模式分析-android

    设计模式系列23种设计模式设计模式是一套被反复使用,多数人知道的,经过分类编目的,代码设计经验的总结。使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性。本文将介绍23种设计模式。创建型...

    Android代码-ExamplesOfDesignPatterns

    ExamplesOfDesignPatterns 序言 各种设计模式的Uml图、分析与代码实现,主要在...享元模式 建造者模式 适配器模式 单例模式 命令模式 状态模式 桥接模式 工厂模式 XMind文件截图 一些模式的截图 交流群:695853826

    android学习资料

    Android设计模式 Android开发指南 android的PPT Android开发教程 GoogleAndroid_code 深入理解Android:卷I的样章 Android-framework详细分析 Android_binder Android_Sensor android+多线程编程 android中文乱码...

    Android设计模式之代理模式Proxy浅显易懂的详细说明

    代理模式也是平时比较常用的设计模式之一,代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身.在日常生活中也是很常见的.例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A...

    leetcode安卓-android-LearningNotes:android-LearningNotes

    享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六部分 有任何问题欢迎联系: 欢迎...

    leetcode下载-Android_AutoTest:Android_AutoTest

    [DesignPattern(设计模式)] 工厂方法模式 抽象工厂模式 状态模式 解释器模式 命令模式 备忘录模式 迭代器模式 模板方法模式 访问者模式 中介者模式 组合模式 装饰模式 享元模式 桥接模式 第二部分 [JavaSE(Java基础)...

    leetcode下载-android-:android学习分享

    享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六部分 有任何问题欢迎联系: 欢迎...

    leetcode下载-Android-:安卓知识点

    享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六部分 有任何问题欢迎联系: 拒绝...

    Android电子相册设计报告.doc

    1 1.1Android平台背景 1 1.2安卓电子相册市场需求 1 1.3安卓电子相册功能需求 1 2 软件总体设计 2 2.1电子相册功能设计 2 2.2电子相册软件流程图 2 2.3电子相册UI设计 3 3 关键技术分析 5 4 软件详细设计 5 4.1 获取...

    leetcode下载-AndroidLearningNotes:Android学习笔记

    享元模式 桥接模式 第二部分 第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 第四部分 第五部分 第六部分 有任何问题欢迎联系: 欢迎关注我的知乎...

    leetcode下载-AndroidLearn:java,android学习知识收集

    leetcode下载 ...享元模式 桥接模式 ##第二部分 ##第三部分 链表 字符串 树 图 查找 《剑指Offer》 《程序员面试金典》 《LeetCode》 《程序员代码面试指南(左程云)》 ##第四部分 ##第五部分 ##第六部分

Global site tag (gtag.js) - Google Analytics