`

Ext中的享元模式(flyweight)

    博客分类:
  • Ext
阅读更多

今天看Ext的sample,不明白下面一段话:

  Ext.fly(node.ui.elNode).ghost('l', {
                callback: node.remove, scope: node, duration: .4
            });

 主要是对Ext.fly不甚明了,于是搜了一把,发现收获还不小,与大家共享之。

Ext.fly是Ext.Element.flyweight的简写,是Ext的Element类中对享元模式的应用,因Element类中的方法都是对DOM对象的操作,而DOM操作又是Ext的核心,所以如果太过于频繁的创建DOM节点的话会造成性能的下降,因而采用享元模式,享元模式以共享的方式高效地支持大量的细粒度对象,有关享元模式的详细资料,可以参见http://fengzl.iteye.com/blog/117129的blog。

在Ext的wiki中对Flyweight有一个简短的介绍,即‘Use sharing to support large numbers of fine-grained objects efficiently.  ’,有个哥们不懂,到论坛上发问,下面就是Ext的核心developer的回答:

 

Ext.Element wraps a lot of functionality around DOM element/node, for example functions like hide, show, all animation stuff, dimensions getting and setting function and a lot more.

Ext.Element keeps reference to DOM element it is wrapped around in dom property. Once you have an Ext.Element (e.g. you call Ext.get('some-id') it is an instance of Element class and you can work with it as such.

Now, imagine that you need to hide 1000 DOM nodes, you call 1000 times Ext.get('some-one-of-1000-id').hide() so you create 1000 instances of Element just to call one function: hide.

Ext.fly is one instance of Ext.Element with "replaceable" DOM node it is wrapped around. If you call 1000 times Ext.fly('some-one-of-1000-id').hide() you 1000 times replace dom property of one instance of Ext.Element.

Result: higher performance, lower memory usage.

You only need to keep in mind that you cannot keep Element returned by Ext.fly for later use as it's dom will sooner or later gets replaced by another one.

 

下面我们来看一下其实现(Ext.Element):


Ext.fly = El.fly;
/**
 * Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -
 * the dom node can be overwritten by other code.
 * @param {String/HTMLElement} el The dom node or id
 * @param {String} named (optional) Allows for creation of named reusable flyweights to
 *                                  prevent conflicts (e.g. internally Ext uses "_internal")
 * @static
 * @return {Element} The shared Element object (or null if no matching element was found)
 */
El.fly = function(el, named){
    named = named || '_global';
    el = Ext.getDom(el);
    if(!el){
        return null;
    }
    if(!El._flyweights[named]){
        El._flyweights[named] = new El.Flyweight();
    }
    El._flyweights[named].dom = el;
    return El._flyweights[named];
};
那么EI._flyweight又是什么呢? 
El._flyweights = {};
var flyFn = function(){};
flyFn.prototype = El.prototype;
var _cls = new flyFn();

// dom is optional
El.Flyweight = function(dom){
    this.dom = dom;
};

El.Flyweight.prototype = _cls;
El.Flyweight.prototype.isFlyweight = true;
这样,基本上明白什么是Ext.fly了吧?同时,也应该明白Ext.fly和Ext.get的区别了吧?

 

 

分享到:
评论
8 楼 li6151770 2009-02-03  
本来还有点理解fly,现在看你们的回答现在彻底不知道什么意思了。。。。。
7 楼 jateide 2008-09-24  
jljlpch 写道
jianfeng008cn 写道
equalto 写道
幸亏我本来明白,要不真的搞不明白了 ^_^

Element,不是来创建DOM的,这两个概念完全不同,DOM是浏览器自己的,Element是Ext的对象.
Element对象里面,有个属性dom,指向了实际存在于浏览器对象树里面的DOM元素,Ext用Element做中介,操作dom作很多操作,这里屏蔽了浏览器差异(起码这个是它的一个目标),也集成了许多的便利的函数,比如说getSize setSize child.

可以说,Element,就是Ext里面操作web元素的一个基本接口.

但是,有个问题是,每个Element都要和dom对应,也就是说,你如果要操作多少个web元素,就要有多少个Element对象实例.
那肯定是不行的.
flyweight,轻量级Element元素应运而生,它使得多个dom元素共享一个Flyweight对象(它完全继承了Element的方法),每次使用,都临时的修改dom属性,指向当前的web元素对象.
这样就节省了创建Element的开销.


个人理解,一家之言哈.



其实用静态方法可以避免这个问题,我感觉ext有点滥用享元模式,element中包含享元模式是合理的,但是在ext-lib等地方也调用这个方法就显得有点不地道了,只有对整个dom操作的逻辑了然于胸才明白这样调用产生的相互依赖不会造成冲突。


非常赞同。觉得有点滥用设计模式。

满瓶不晃,半瓶晃荡。自以为是
6 楼 jljlpch 2008-09-12  
jianfeng008cn 写道
equalto 写道
幸亏我本来明白,要不真的搞不明白了 ^_^

Element,不是来创建DOM的,这两个概念完全不同,DOM是浏览器自己的,Element是Ext的对象.
Element对象里面,有个属性dom,指向了实际存在于浏览器对象树里面的DOM元素,Ext用Element做中介,操作dom作很多操作,这里屏蔽了浏览器差异(起码这个是它的一个目标),也集成了许多的便利的函数,比如说getSize setSize child.

可以说,Element,就是Ext里面操作web元素的一个基本接口.

但是,有个问题是,每个Element都要和dom对应,也就是说,你如果要操作多少个web元素,就要有多少个Element对象实例.
那肯定是不行的.
flyweight,轻量级Element元素应运而生,它使得多个dom元素共享一个Flyweight对象(它完全继承了Element的方法),每次使用,都临时的修改dom属性,指向当前的web元素对象.
这样就节省了创建Element的开销.


个人理解,一家之言哈.



其实用静态方法可以避免这个问题,我感觉ext有点滥用享元模式,element中包含享元模式是合理的,但是在ext-lib等地方也调用这个方法就显得有点不地道了,只有对整个dom操作的逻辑了然于胸才明白这样调用产生的相互依赖不会造成冲突。


非常赞同。觉得有点滥用设计模式。
5 楼 equalto 2008-09-12  
jianfeng008cn 写道


其实用静态方法可以避免这个问题,我感觉ext有点滥用享元模式,element中包含享元模式是合理的,但是在ext-lib等地方也调用这个方法就显得有点不地道了,只有对整个dom操作的逻辑了然于胸才明白这样调用产生的相互依赖不会造成冲突。


能把代码看到lib,是很不错了,但是,再多看多想,你就会发现,没什么不地道的。
Ext自己的代码中,使用了flyweight的地方,我看不出来有什么大不了,Ext.fly函数的第二个参数name,已经可以说明作者的意图了,如果乱用一气,引起错误,那能怎么说呢?
——只能说做出这个事情的人傻。
我在用fly的时候,个别地方需要特别指定name,都用公司的简称作前缀。

btw,最后一句话,我很不明白,Element在我看来,是Ext对于页面元素的一个包装类,就是避免一些dom操作的麻烦。怎么又说那些的话。
4 楼 jianfeng008cn 2008-09-10  
equalto 写道
幸亏我本来明白,要不真的搞不明白了 ^_^

Element,不是来创建DOM的,这两个概念完全不同,DOM是浏览器自己的,Element是Ext的对象.
Element对象里面,有个属性dom,指向了实际存在于浏览器对象树里面的DOM元素,Ext用Element做中介,操作dom作很多操作,这里屏蔽了浏览器差异(起码这个是它的一个目标),也集成了许多的便利的函数,比如说getSize setSize child.

可以说,Element,就是Ext里面操作web元素的一个基本接口.

但是,有个问题是,每个Element都要和dom对应,也就是说,你如果要操作多少个web元素,就要有多少个Element对象实例.
那肯定是不行的.
flyweight,轻量级Element元素应运而生,它使得多个dom元素共享一个Flyweight对象(它完全继承了Element的方法),每次使用,都临时的修改dom属性,指向当前的web元素对象.
这样就节省了创建Element的开销.


个人理解,一家之言哈.



其实用静态方法可以避免这个问题,我感觉ext有点滥用享元模式,element中包含享元模式是合理的,但是在ext-lib等地方也调用这个方法就显得有点不地道了,只有对整个dom操作的逻辑了然于胸才明白这样调用产生的相互依赖不会造成冲突。
3 楼 KKFC 2008-07-29  
ext里面还有不少design pattern的东东的 -这是它比其他js lib来得精彩的地方之一

引用

设计模式和 Ext JS
开发人员应该会喜欢 Ext JS 经过深思熟虑的设计和实现。它的面向对象设计模式反映了对象之间的关系和交互。据设计者说,开发 Ext JS 时使用的设计模式在很大程度上受到 Head First Design Patterns 这本书(Eric Freeman 等著,参见 参考资料)的影响。查看 Ext JS 源代码,就会发现创建模式(包括 singleton 设计模式)、结构模式(包括 flyweight 设计模式)和行为模式(包括 observer 模式)。


IBM developerWorks 中国  >  Web development  > 用 Ext JS 构建 Ajax 应用程序
2 楼 hintcnuie 2008-07-28  
有点不太同意,主要集中于对DOM和BOM的理解上。一个html页面,就会产生一个DOM树,浏览器会负责实现这个DOM树,但不能说这个DOM就变成浏览器自己的了,只能说是浏览器负责维护这个DOM的实例。
1 楼 equalto 2008-07-22  
幸亏我本来明白,要不真的搞不明白了 ^_^

Element,不是来创建DOM的,这两个概念完全不同,DOM是浏览器自己的,Element是Ext的对象.
Element对象里面,有个属性dom,指向了实际存在于浏览器对象树里面的DOM元素,Ext用Element做中介,操作dom作很多操作,这里屏蔽了浏览器差异(起码这个是它的一个目标),也集成了许多的便利的函数,比如说getSize setSize child.

可以说,Element,就是Ext里面操作web元素的一个基本接口.

但是,有个问题是,每个Element都要和dom对应,也就是说,你如果要操作多少个web元素,就要有多少个Element对象实例.
那肯定是不行的.
flyweight,轻量级Element元素应运而生,它使得多个dom元素共享一个Flyweight对象(它完全继承了Element的方法),每次使用,都临时的修改dom属性,指向当前的web元素对象.
这样就节省了创建Element的开销.


个人理解,一家之言哈.

相关推荐

    享元模式flyweight

    享元模式(Flyweight Pattern)是一种结构型设计模式,它能有效地减少系统中对象的数量,从而降低内存消耗,提高性能。这种模式通过共享大量相似对象的内部状态来达到这一目标,而只保留对象的外部状态在外部管理。...

    c++-设计模式之享元模式(Flyweight)

    享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少创建大量小对象所带来的内存开销。通过共享对象,享元模式能够有效地支持大量细粒度的对象,减少内存使用并提高性能。它常用于需要大量重复对象的场景...

    设计模式(C#)之享元模式(Flyweight Pattern)

    享元模式是设计模式中的一种结构型模式,它主要通过共享已有对象来减少内存中对象的数量,从而提高系统性能。在C#编程中,享元模式尤其适用于那些创建大量相似对象且内存消耗较大的场景。本篇文章将深入探讨享元模式...

    学习php设计模式 php实现享元模式(flyweight)

    享元模式(Flyweight Pattern)是软件设计中的一种结构型设计模式,它通过共享技术来支持大量细粒度的对象,以此来降低内存中对象的数量。在PHP中实现享元模式,可以帮助我们优化程序性能,特别是在对象数目过多时,...

    设计模式学习笔记--Flyweight享元模式.docx

    享元模式的核心是Flyweight类,它是需要被共享的对象,通常包含两个部分:内在状态(Intrinsic State)和外在状态(Extrinsic State)。内在状态是指对象内部不变的部分,可以在多个对象之间共享;外在状态是随环境...

    设计模式的享元模式的例子

    享元模式是软件设计模式中的一种结构型模式,它的主要目的是通过共享大量细粒度对象来减少内存的使用,提高系统性能。在许多场景下,尤其是处理大量相似对象时,享元模式能显著减少内存开销。这个压缩包文件...

    C#面向对象设计模式纵横谈(12):Flyweight 享元模式(结构型模式) (Level 300)

    享元模式是面向对象设计中的一种结构型模式,它的主要目的是通过共享大量相似对象来减少内存的使用,提高系统的性能。在C#编程语言中,我们可以利用享元模式来优化那些具有大量实例但大部分状态可以共享的对象。在这...

    设计模式之享元模式

    享元模式是软件设计模式中的一种结构型模式,它的主要目的是为了提高性能,尤其是在大量对象创建时。享元模式通过共享已有对象来减少内存中对象的数量,从而达到降低内存消耗的效果。这种模式适用于那些轻量级对象,...

    总结JavaScript设计模式编程中的享元模式使用

    享元模式是软件工程中一种用于优化性能的设计模式,它通过共享相似对象的实例来减少内存使用或者计算的开销。在JavaScript编程中,尤其是处理DOM操作和大量相似对象时,享元模式的使用尤为关键。 享元模式的主要...

    C++设计模式之享元模式(Flyweight)

    C++设计模式之享元模式(Flyweight) C++设计模式之享元模式(Flyweight)是一种结构型设计模式,主要用于解决大量相似对象的创建和操作所带来的内存负载问题。该模式的主要设计目标是通过共享对象来减少内存负载,...

    享元模式代码示例

    在“Flyweight”这个文件中,我们可以预期找到的是一个关于享元模式的代码实现。这个文件可能包含了一个享元接口,若干个实现了该接口的具体享元类,以及一个享元工厂类。享元接口定义了对外暴露的方法,这些方法...

    C#设计模式之Flyweight

    在C#中实现享元模式,我们首先定义享元接口: ```csharp public interface IFlyweight { void Operation(string extrinsicState); } ``` 然后创建具体享元类: ```csharp public class ConcreteFlyweight : ...

    享元模式代码+文档

    在享元模式中,通常会有两个关键组件:享元工厂(Flyweight Factory)和客户端。享元工厂负责创建和管理享元对象,确保对同一享元对象的多次请求返回的是同一个实例。客户端则负责创建和维护不共享状态,当需要使用...

    Java设计模式之享元模式

    在Java中实现享元模式时,通常会结合使用`Flyweight`接口和`Concrete Flyweight`类,以及一个`FlyweightFactory`类或方法。`FlyweightFactory`通常维护一个享元对象池,当客户端请求一个享元对象时,工厂首先检查...

    享元模式,内含可运行代码和解释

    享元模式是一种经典的设计模式,属于结构型模式,它的核心思想是通过共享已经存在的对象来减少内存中的对象数量,从而提高系统性能。在许多场景下,特别是计算机编程中,我们可能会遇到大量的相似对象,比如在图形...

    C++设计模式课件13_Flyweight_享元模式.pdf

    享元模式(Flyweight Pattern)是设计模式中的一种优化模式,主要用于减少创建大量相似对象所需的内存消耗。在C++程序设计中,当系统中存在大量的相同或相似的对象时,使用享元模式可以有效地降低内存占用,提高系统...

    第15章_享元模式.ppt

    在享元模式中可以共享的相同内容称为内部状态(Intrinsic State),而那些需要外部...在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。

    享元模式的分析以及实际应用.docx

    在软件工程中,尤其是在处理大量相似对象时,享元模式能够显著提高系统的性能。享元模式通过共享那些可以共享的内部状态,使得相同的对象只需要被创建一次,从而避免了大量的内存开销。 在享元模式中,有以下几个...

Global site tag (gtag.js) - Google Analytics