`
flustar
  • 浏览: 96732 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

设计模式学习笔记(二十二)—FlyWeight享元模式

阅读更多

一、FlyWeight模式定义:

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

二、模式解说

也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory模式。Flyweight的内部状态是用来共享的,Flyweight factory负责维护一个对象存储池(Flyweight Pool)来存放内部状态的对象。Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度。

三、结构图

 

享元模式所涉及的角色有抽象享元角色、具体(单纯)享元角色、复合享元角色、享员工厂角色,以及客户端角色等。

抽象享元角色(Flyweight):此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口或抽象类。那些需要外蕴状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。

具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。

复合享元(UnsharableFlyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称做不可共享的享元对象。这个角色一般很少使用。

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

客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。

 

 

四、一个例子

 



import java.util.Hashtable;


/** 
 *
 * 
@author <a href="mailto:flustar2008@163.com">flustar</a>
 * 
@version 1.0 
 * Creation date: Jan 25, 2008 1:33:49 PM
 
*/

  
// "Flyweight"

  
abstract class Character
  {
    
protected char symbol;
    
protected int width;
    
protected int height;
    
protected int ascent;
    
protected int descent;
    
protected int pointSize;

    
public abstract void Display(int pointSize);
  }

  
// "ConcreteFlyweight"

  
class CharacterA extends Character
  {
    
// Constructor
    public CharacterA()
    {
      
this.symbol = 'A';
      
this.height = 100;
      
this.width = 120;
      
this.ascent = 70;
      
this.descent = 0;
    }

    
public  void Display(int pointSize)
    {
      
this.pointSize = pointSize;
     System.out.println(
this.symbol +
        
" (pointsize " + this.pointSize + ")");
    }
  }

  
// "ConcreteFlyweight"

  
class CharacterB extends Character
  {
    
// Constructor
    public CharacterB()
    {
      
this.symbol = 'B';
      
this.height = 100;
      
this.width = 140;
      
this.ascent = 72;
      
this.descent = 0;
    }

    
public  void Display(int pointSize)
    {
      
this.pointSize = pointSize;
     System.out.println(
this.symbol +
        
" (pointsize " + this.pointSize + ")");
    }

  }

  
//  C, D, E, etc.

  
// "ConcreteFlyweight"

  
class CharacterZ extends Character
  {
    
// Constructor
    public CharacterZ()
    {
      
this.symbol = 'Z';
      
this.height = 100;
      
this.width = 100;
      
this.ascent = 68;
      
this.descent = 0;
    }

    
public  void Display(int pointSize)
    {
      
this.pointSize = pointSize;
      System.out.println(
this.symbol +
        
" (pointsize " + this.pointSize + ")");
    }
  }
  
// "FlyweightFactory"

  
class CharacterFactory
  {
    
private Hashtable characters = new Hashtable();

    
public Character GetCharacter(char key)
    {
      
// Uses "lazy initialization"
      Character character = (Character)characters.get(key);
      
if (character == null)
      {
        
switch (key)
        {
          
case 'A': character = new CharacterA(); break;
          
case 'B': character = new CharacterB(); break;
            
//
          case 'Z': character = new CharacterZ(); break;
        }
        characters.put(key, character);
      }
      
return character;
    }
  }
// test application
  public class Test
  {
    
public static void main(String []args)
    {
      
// Build a document with text
      String document = "AAZZBBZB";
      
char[] chars = document.toCharArray();

      CharacterFactory f 
= new CharacterFactory();

      
// extrinsic state
      int pointSize = 10;

      
// For each character use a flyweight object
      for(char c : chars)
      {
        pointSize
++;
        Character character 
= f.GetCharacter(c);
        character.Display(pointSize);
      }
 
      
    }
  }


五、 适用性

Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用Flyweight模式。

1)  一个应用程序使用了大量的对象。

2)  完全由于使用大量的对象,造成很大的存储开销。

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

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

5)  应用程序不依赖对象标识。

六、优缺点

1)享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

2)享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

七、参考

    《设计模式可复用面向对象软件的基础》

    《Design Pattern Framework 2.0》

 

分享到:
评论

相关推荐

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

    享元模式是一种设计模式,属于构造型模式,其主要目的是减少对象的数量,通过共享大量相似对象的内部状态来节省内存。这种模式在处理大量细粒度对象时特别有用,能够有效地提高系统的性能。 享元模式的核心是...

    设计模式学习笔记总结

    这里我们聚焦于C#语言中的设计模式学习笔记,涵盖了多种经典的设计模式,如合成模式、桥梁模式、装饰模式、享元模式、门面模式、命令模式、工厂方法、策略模式、代理模式以及状态模式。下面将对这些模式逐一进行详细...

    设计模式学习笔记大全

    以上就是压缩包中的设计模式学习笔记涉及到的主要内容。通过对这些模式的理解和应用,开发者可以更好地解决软件设计中的问题,提升软件的质量和可维护性。每种模式都有其适用场景,理解其背后的意图和应用场景是关键...

    设计模式学习笔记

    6. 享元模式(Flyweight):在大量相似对象中,存储共享对象以减少内存使用。 7. 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。 行为型模式涉及对象之间的责任分配,包括: 1. 责任链模式...

    23中设计模式学习笔记.docx

    ### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...

    GoF 23种设计模式学习笔记

    "GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...

    《设计模式》学习笔记

    ### 设计模式学习笔记 #### 引言 设计模式(Design Patterns)是在软件设计领域内广泛应用的一种实践指南,它提供了一系列解决常见问题的方案。设计模式可以被理解为面向对象软件设计的经验总结,是对特定面向对象...

    300Java设计模式部分学习笔记

    7. 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。 行为型模式: 行为型模式关注的是对象之间的通信,用来描述对象之间怎样相互协作共同完成任务。笔记中涵盖了以下行为型模式: 1. ...

    23种面向对象设计模式

    文档中的“23种设计模式学习笔记.doc”可能包含了对这23种模式的详细解释和实例,而“设计模式之我爱我家.doc”可能从一个更生活化的角度来阐述设计模式的概念。“软件23种设计模式,超级经典的.pdf”可能是对这些...

    台湾人写的设计模式笔记

    常见的有:适配器(Adapter)、桥接(Bridge)、组合(Composite)、装饰(Decorator)、外观(Facade)、享元(Flyweight)、代理(Proxy)。例如,适配器模式允许不兼容的接口之间进行通信,而组合模式则允许我们构建树形结构来...

    设计模式的读书总结笔记

    2. 结构型模式:包括适配器模式(Adapter)、桥接模式(Bridge)、装饰模式(Decorator)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)和代理模式(Proxy)。它们处理对象之间的关系,如组合...

    《设计模式:可复用面向对象软件的基础》学习并理解 23 种设计模式

    - **享元模式**(Flyweight):运用共享技术有效地支持大量细粒度的对象。 - **代理模式**(Proxy):为其他对象提供一个代理以控制对这个对象的访问。 3. **行为型模式**:定义对象间的基本行为或者算法的通信...

    Java设计模式尚硅谷笔记

    10. 享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象。通过共享大量对象,减少内存消耗。 11. 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。在远程调用、权限控制等方面有...

    图解Java设计模式笔记总结word版本.rar

    - **结构型模式**:如适配器(Adapter)、桥接(Bridge)、组合(Composite)、装饰(Decorator)、外观(Facade)、代理(Proxy)和享元(Flyweight),它们关注如何组织类和对象,以形成更大的结构。 - **行为型...

    设计模式笔记总结 含C#示例代码 复习好帮手

    本篇文章是对一份设计模式学习资料的深入解读,这份资料包含了19种经典的设计模式,并提供了C#示例代码,适用于学习和复习。下面将逐一介绍这些设计模式及其核心概念。 #### 1. 简单工厂模式 (Simple Factory ...

    Head First 设计模式 扫描版

    包括适配器模式(Adapter)、装饰器模式(Decorator)、代理模式(Proxy)、桥接模式(Bridge)、组合模式(Composite)、外观模式(Facade)和享元模式(Flyweight)。这些模式有助于降低系统的复杂性,提高代码的...

    设计模式笔记设计模式笔记

    - 结构型模式:如适配器(Adapter)、桥接(Bridge)、组合(Composite)、装饰(Decorator)、外观(Facade)、享元(Flyweight)和代理(Proxy)。这些模式关注如何组合和组织类与对象,以达到更好的结构和解耦。...

    java23种设计模式,3套视频加1个ppt

    6. **享元模式(Flyweight)**:运用共享技术有效支持大量细粒度的对象。 7. **组合模式(Composite)**:将对象组合成树形结构以表示“部分-整体”的层次结构。 **行为型模式**: 1. **策略模式(Strategy)**:...

    《.NET设计模式》文档

    步步为营 .NET 设计模式学习笔记这个文件名暗示了文档可能采用逐步深入的方式,从基础概念开始,逐步引导读者理解每个模式的用途、实现方式以及在实际.NET项目中的应用。可能包含详细的代码示例,帮助读者通过实践来...

Global site tag (gtag.js) - Google Analytics