黑马程序员技术交流社区

标题: 关于享元模式的理解 [打印本页]

作者: 任传敏    时间: 2012-6-24 22:27
标题: 关于享元模式的理解
看张老师的高新技术视频讲享元模式的思想,是把对象不同的属性设计成方法的参数,作为外部状态。我又在百度百科中看到的解释,是把物件共享的状态作为外部数据,当需要时再把它传递个享元,所以我有点迷惑,到底这个外部状态和外部数据有什么联系和不同?请高人详解一下!
作者: Fc10232    时间: 2012-6-24 22:40
小件事物  经常需要这个事物, 使用一次创建一次 一定会造成浪费,所以把这个小件事物搁置在一边,当另外一个人来使用时这个事物时,就不需要重新创建,而是直接获取
作者: 任传敏    时间: 2012-6-24 22:56
Fc10232 发表于 2012-6-24 22:40
小件事物  经常需要这个事物, 使用一次创建一次 一定会造成浪费,所以把这个小件事物搁置在一边,当另外一 ...

不是我想要的答案!
作者: 任传敏    时间: 2012-6-24 22:57
Fc10232 发表于 2012-6-24 22:40
小件事物  经常需要这个事物, 使用一次创建一次 一定会造成浪费,所以把这个小件事物搁置在一边,当另外一 ...

不是我想要的答案!
作者: 邓杰    时间: 2012-6-25 12:40
当一些对象较小且使用频率比较高的时候;可以采用享元模式:把这些小的对象的共性抽离出来封装成为一个单独的对象;而每个对象在不同的环境下所需要表现出的特点通过传递参数来完成:
例:abc...z每一个字符均为一个对象;如果用这此字母写一篇论文;那不是需要new出很多个对象;因为这些对象大多重复的使用;所以就把这26个字母分别封装成为了26个对象;然后把这26个对象所以要出现的位置通过他们的显示方法display()来完成;而具体要出现在哪个地方则通过传递参数的形式来完成display(int x ,int y);这样就可以实现创建很少的对象来完成很大的工程;
这也是为什么Integer i1=3; Integer i2=3; (i1==i3)true; 而Integet i3=139; Integet i4=139;(i3==i4)false;
char c1='a';//证明char也有一个自动装箱动作;也用了享元模式;
  char c2='a';
  System.out.println(c1==c2);
如果有很多小的对象 它们有很多相同的属性(内部状态);就把它们变成同一个对象;而那些不同的属性(外部状态)就作为方法的参数;
通俗点讲:
内部状态:这些对象的共有属性;比如字母"A"他的内部状态就包括它对应的二进制数值为“97(十进制的值)”(具体是不是97我记不清了,你应该明白我的意思),还有他外观就是"A"这个样子;
而外部状态就是用这个字母组成了字符串:如String str=“AAAA”这里其实只有一个对象“A”;只这个对象它出现在了不同的位置上;"AAAA"中的第一个“A”它的外部属性就应该是A.display(0,0)第一个0表示他出现在第一行;第二个0表示这个对象A出现在第一列;依此类推;第二个A就应当是A.display(0,1); 这里的这A出现在不同的行与不同的列就是这个对象的外部状态;因为在创建对象的时候;你根本不可能知道会是谁在调用它;让它在做什么事;这些不能确定的状态就只有以参数的形式让调用者去设值;
而不管出现在哪个位置他都是以A的外观;以A对应的值“97”出现。这些不会改变的属性就是他的内部状态;

作者: oracleserver    时间: 2012-6-25 14:08
享元模式的结构
  享元模式采用一个共享来避免大量拥有相同内容对象的开销。这种开销最常见、最直观的就是内存的损耗。享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。
  一个内蕴状态是存储在享元对象内部的,并且是不会随环境的改变而有所不同。因此,一个享元可以具有内蕴状态并可以共享。
  一个外蕴状态是随环境的改变而改变的、不可以共享的。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态不可以影响享元对象的内蕴状态,它们是相互独立的。

  享元模式可以分成单纯享元模式和复合享元模式两种形式。
单纯享元模式  
  在单纯的享元模式中,所有的享元对象都是可以共享的。

  单纯享元模式所涉及到的角色如下:
         抽象享元(Flyweight)角色 :给出一个抽象接口,以规定出所有具体享元角色需要实现的方法。
         具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定出的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
        享元工厂(FlyweightFactory)角色 :本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。

作者: 张华廷    时间: 2012-6-25 14:18

享元模式:采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。



class PersonMenuMuch implements Menu
    {
         private Map MenuList = new HashMap();
         public PersonMenuMuch(){}
         //增加一个新的单纯享元对象
         public void add(String key , Menu menu)
         {
          MenuList.put(key , menu);
         }
        //两个无为的方法
         public synchronized void setPersonMenu(String person , List list)
         { }
         public List findPersonMenu(String person, List list)
         {
          List nothing = null ;
          return nothing ;
         }
    }
    在工厂方法中添加一个方法,实现重载。
    public Menu factory(String[] dish)
     {
          PersonMenuMuch menu = new PersonMenuMuch();
          String key = null ;
          for(int i=0 ; i<dish.length ; i++)
          {
               key = dish[i];
               menu.add(key , this.factory(key));//调用了单纯享元角色的工厂方法
          }
          return menu ;
     }





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2