当前位置: 首页 > news >正文

智能优化网站广西网站开发建设

智能优化网站,广西网站开发建设,搞定设计,设计公司品牌介绍面向对象的代价 面向对象很好地解决了系统抽象性的问题#xff0c;同时在大多数情况下#xff0c;也不会损及系统的性能。但是#xff0c;在 某些特殊的应用中下#xff0c;由于对象的数量太大#xff0c;采用面向对象会给系统带来难以承受的内存开销。比如: 图形应用…面向对象的代价     面向对象很好地解决了系统抽象性的问题同时在大多数情况下也不会损及系统的性能。但是在 某些特殊的应用中下由于对象的数量太大采用面向对象会给系统带来难以承受的内存开销。比如: 图形应用中的图元等对象、字处理应用中的字符对象等。                                  动机(Motivate):     采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中从而带来很高的运行时代价--------主要指内存需求方面的代价。     如何在避免大量细粒度对象问题的同时让外部客户程序仍然能够透明地使用面向对象的方式来进行操作 意图(Intent):     运用共享技术有效地支持大量细粒度的对象。  -------《设计模式》GOF  结构(Struct):                    适用性    当以下所有的条件都满足时可以考虑使用享元模式 1、   一个系统有大量的对象。 2、   这些对象耗费大量的内存。 3、   这些对象的状态中的大部分都可以外部化。 4、   这些对象可以按照内蕴状态分成很多的组当把外蕴对象从对象中剔除时每一个组都可以仅用一个对象代替。 5、   软件系统不依赖于这些对象的身份换言之这些对象可以是不可分辨的。 满足以上的这些条件的系统可以使用享元对象。最后使用享元模式需要维护一个记录了系统已有的所有享元的表而这需要耗费资源。因此应当在有足够多的享元实例可供共享时才值得使用享元模式。 生活中的例子     享元模式使用共享技术有效地支持大量细粒度的对象。公共交换电话网PSTN是享元的一个例子。有一些资源例如拨号音发生器、振铃发生器和拨号接收器是必须由所有用户共享的。当一个用户拿起听筒打电话时他不需要知道使用了多少资源。对于用户而言所有的事情就是有拨号音拨打号码拨通电话。                       代码实现     Flyweight在拳击比赛中指最轻量级即“蝇量级”这里翻译为“享元”可以理解为共享元对象细粒度对象的意思。提到Flyweight模式都会一般都会用编辑器例子来说明这里也不例外但我会尝试着通过重构来看待Flyweight模式。考虑这样一个字处理软件它需要处理的对象可能有单个的字符由字符组成的段落以及整篇文档根据面向对象的设计思想和Composite模式不管是字符还是段落文档都应该作为单个的对象去看待这里只考虑单个的字符不考虑段落及文档等对象于是可以很容易的得到下面的结构图                      1 // Charactor  2 public abstract class Charactor  3 {  4     //Fields  5     protected char _symbol;  6   7     protected int _width;  8   9     protected int _height; 10  11     protected int _ascent; 12  13     protected int _descent; 14  15     protected int _pointSize; 16  17     //Method 18     public abstract void Display(); 19 } 20  21 // CharactorA 22 public class CharactorA : Charactor 23 {  24     // Constructor  25     public CharactorA() 26     { 27       this._symbol  A; 28       this._height  100; 29       this._width  120; 30       this._ascent  70; 31       this._descent  0; 32       this._pointSize  12; 33     } 34  35     //Method 36     public override void Display() 37     { 38         Console.WriteLine(this._symbol); 39     } 40 } 41  42 // CharactorB 43 public class CharactorB : Charactor 44 { 45     // Constructor  46     public CharactorB() 47     { 48         this._symbol  B; 49         this._height  100; 50         this._width  140; 51         this._ascent  72; 52         this._descent  0; 53         this._pointSize  10; 54     } 55  56     //Method 57     public override void Display() 58     { 59         Console.WriteLine(this._symbol); 60     } 61 } 62  63 // CharactorC 64 public class CharactorC : Charactor 65 { 66     // Constructor  67     public CharactorC() 68     { 69         this._symbol  C; 70         this._height  100; 71         this._width  160; 72         this._ascent  74; 73         this._descent  0; 74         this._pointSize  14; 75     } 76  77     //Method 78     public override void Display() 79     { 80         Console.WriteLine(this._symbol); 81     } 82 } 好了现在看到的这段代码可以说是很好地符合了面向对象的思想但是同时我们也为此付出了沉重的代价那就是性能上的开销可以想象在一篇文档中字符的数量远不止几百个这么简单可能上千上万内存中就同时存在了上千上万个Charactor对象这样的内存开销是可想而知的。进一步分析可以发现虽然我们需要的Charactor实例非常多这些实例之间只不过是状态不同而已也就是说这些实例的状态数量是很少的。所以我们并不需要这么多的独立的Charactor实例而只需要为每一种Charactor状态创建一个实例让整个字符处理软件共享这些实例就可以了。看这样一幅示意图                           现在我们看到的ABC三个字符是共享的也就是说如果文档中任何地方需要这三个字符只需要使用共享的这三个实例就可以了。然而我们发现单纯的这样共享也是有问题的。虽然文档中的用到了很多的A字符虽然字符的symbol等是相同的它可以共享但是它们的pointSize却是不相同的即字符在文档中中的大小是不相同的这个状态不可以共享。为解决这个问题首先我们将不可共享的状态从类里面剔除出去即去掉pointSize这个状态只是暂时的J类结构图如下所示          1 // Charactor  2 public abstract class Charactor  3 {  4     //Fields  5     protected char _symbol;  6   7     protected int _width;  8   9     protected int _height; 10  11     protected int _ascent; 12  13     protected int _descent; 14  15     //Method 16     public abstract void Display(); 17 } 18  19 // CharactorA 20 public class CharactorA : Charactor 21 { 22     // Constructor  23     public CharactorA() 24     { 25         this._symbol  A; 26         this._height  100; 27         this._width  120; 28         this._ascent  70; 29         this._descent  0; 30     } 31  32     //Method 33     public override void Display() 34     { 35         Console.WriteLine(this._symbol); 36     } 37 } 38  39 // CharactorB 40 public class CharactorB : Charactor 41 { 42     // Constructor  43     public CharactorB() 44     { 45         this._symbol  B; 46         this._height  100; 47         this._width  140; 48         this._ascent  72; 49         this._descent  0; 50     } 51  52     //Method 53     public override void Display() 54     { 55         Console.WriteLine(this._symbol); 56     } 57 } 58  59 // CharactorC 60 public class CharactorC : Charactor 61 { 62     // Constructor  63     public CharactorC() 64     { 65         this._symbol  C; 66         this._height  100; 67         this._width  160; 68         this._ascent  74; 69         this._descent  0; 70     } 71  72     //Method 73     public override void Display() 74     { 75         Console.WriteLine(this._symbol); 76     } 77 } 好现在类里面剩下的状态都可以共享了下面我们要做的工作就是控制Charactor类的创建过程即如果已经存在了“A”字符这样的实例就不需要再创建直接返回实例如果没有则创建一个新的实例。如果把这项工作交给Charactor类即Charactor类在负责它自身职责的同时也要负责管理Charactor实例的管理工作这在一定程度上有可能违背类的单一职责原则因此需要一个单独的类来做这项工作引入CharactorFactory类结构图如下            1 // CharactorFactory  2 public class CharactorFactory  3 {  4     // Fields  5     private Hashtable charactors  new Hashtable();  6   7     // Constructor   8     public CharactorFactory()  9     { 10         charactors.Add(A, new CharactorA()); 11         charactors.Add(B, new CharactorB()); 12         charactors.Add(C, new CharactorC()); 13     } 14         15     // Method 16     public Charactor GetCharactor(string key) 17     { 18         Charactor charactor  charactors[key] as Charactor; 19  20         if (charactor  null) 21         { 22             switch (key) 23             { 24                 case A: charactor  new CharactorA(); break; 25                 case B: charactor  new CharactorB(); break;  26                 case C: charactor  new CharactorC(); break; 27                 // 28             } 29             charactors.Add(key, charactor); 30         } 31         return charactor; 32     } 33 } 到这里已经完全解决了可以共享的状态这里很丑陋的一个地方是出现了switch语句但这可以通过别的办法消除为了简单期间我们先保持这种写法。下面的工作就是处理刚才被我们剔除出去的那些不可共享的状态因为虽然将那些状态移除了但是Charactor对象仍然需要这些状态被我们剥离后这些对象根本就无法工作所以需要将这些状态外部化。首先会想到一种比较简单的解决方案就是对于不能共享的那些状态不需要去在Charactor类中设置而直接在客户程序代码中进行设置类结构图如下                1 public class Program  2 {  3     public static void Main()  4     {  5         Charactor ca  new CharactorA();  6         Charactor cb  new CharactorB();  7         Charactor cc  new CharactorC();  8   9         //显示字符 10  11         //设置字符的大小ChangeSize(); 12     } 13  14     public void ChangeSize() 15     { 16         //在这里设置字符的大小 17     } 18 } 按照这样的实现思路可以发现如果有多个客户端程序使用的话会出现大量的重复性的逻辑用重构的术语来说是出现了代码的坏味道不利于代码的复用和维护另外把这些状态和行为移到客户程序里面破坏了封装性的原则。再次转变我们的实现思路可以确定的是这些状态仍然属于Charactor对象所以它还是应该出现在Charactor类中对于不同的状态可以采取在客户程序中通过参数化的方式传入。类结构图如下           1 // Charactor   2 public abstract class Charactor   3 {   4     //Fields   5     protected char _symbol;   6    7     protected int _width;   8    9     protected int _height;  10   11     protected int _ascent;  12   13     protected int _descent;  14   15     protected int _pointSize;  16   17     //Method  18     public abstract void SetPointSize(int size);  19     public abstract void Display();  20 }  21   22 // CharactorA  23 public class CharactorA : Charactor  24 {  25     // Constructor   26     public CharactorA()  27     {  28         this._symbol  A;  29         this._height  100;  30         this._width  120;  31         this._ascent  70;  32         this._descent  0;  33     }  34   35     //Method  36     public override void SetPointSize(int size)  37     {  38         this._pointSize  size;  39     }  40   41     public override void Display()  42     {  43         Console.WriteLine(this._symbol   44           pointsize:  this._pointSize);  45     }  46 }  47   48 // CharactorB  49 public class CharactorB : Charactor  50 {  51     // Constructor   52     public CharactorB()  53     {  54         this._symbol  B;  55         this._height  100;  56         this._width  140;  57         this._ascent  72;  58         this._descent  0;  59     }  60   61     //Method  62     public override void SetPointSize(int size)  63     {  64         this._pointSize  size;  65     }  66   67     public override void Display()  68     {  69         Console.WriteLine(this._symbol   70           pointsize:  this._pointSize);  71     }  72 }  73   74 // CharactorC  75 public class CharactorC : Charactor  76 {  77     // Constructor   78     public CharactorC()  79     {  80         this._symbol  C;  81         this._height  100;  82         this._width  160;  83         this._ascent  74;  84         this._descent  0;  85     }  86   87     //Method  88     public override void SetPointSize(int size)  89     {  90         this._pointSize  size;  91     }  92   93     public override void Display()  94     {  95         Console.WriteLine(this._symbol   96           pointsize:  this._pointSize);  97     }  98 }  99  100 // CharactorFactory 101 public class CharactorFactory 102 { 103     // Fields 104     private Hashtable charactors  new Hashtable(); 105  106     // Constructor  107     public CharactorFactory() 108     { 109         charactors.Add(A, new CharactorA()); 110         charactors.Add(B, new CharactorB()); 111         charactors.Add(C, new CharactorC()); 112     } 113         114     // Method 115     public Charactor GetCharactor(string key) 116     { 117         Charactor charactor  charactors[key] as Charactor; 118  119         if (charactor  null) 120         { 121             switch (key) 122             { 123                 case A: charactor  new CharactorA(); break; 124                 case B: charactor  new CharactorB(); break;  125                 case C: charactor  new CharactorC(); break; 126                 // 127             } 128             charactors.Add(key, charactor); 129         } 130         return charactor; 131     } 132 } 133  134 public class Program 135 { 136     public static void Main() 137     { 138         CharactorFactory factory  new CharactorFactory(); 139  140         // Charactor A 141         CharactorA ca  (CharactorA)factory.GetCharactor(A); 142         ca.SetPointSize(12); 143         ca.Display(); 144          145         // Charactor B 146         CharactorB cb  (CharactorB)factory.GetCharactor(B); 147         ca.SetPointSize(10); 148         ca.Display(); 149  150         // Charactor C 151         CharactorC cc  (CharactorC)factory.GetCharactor(C); 152         ca.SetPointSize(14); 153         ca.Display(); 154     } 155 } 可以看到这样的实现明显优于第一种实现思路。好了到这里我们就到到了通过Flyweight模式实现了优化资源的这样一个目的。在这个过程中还有如下几点需要说明 1引入CharactorFactory是个关键在这里创建对象已经不是new一个Charactor对象那么简单而必须用工厂方法封装起来。 2在这个例子中把Charactor对象作为Flyweight对象是否准确值的考虑这里只是为了说明Flyweight模式至于在实际应用中哪些对象需要作为Flyweight对象是要经过很好的计算得知而绝不是凭空臆想。 3区分内外部状态很重要这是享元对象能做到享元的关键所在。 到这里其实我们的讨论还没有结束。有人可能会提出如下问题享元对象Charactor 在这个系统中相对于每一个内部状态而言它是唯一的这跟单件模式有什么区别呢这个问题已经很好回答了那就是单件类是不能直接被实例化的而享元类是可 以被实例化的。事实上在这里面真正被设计为单件的应该是享元工厂不是享元类因为如果创建很多个享元工厂的实例那我们所做的一切努力都是白费的并 没有减少对象的个数。修改后的类结构图如下            1 // CharactorFactory  2 public class CharactorFactory  3 {  4     // Fields  5     private Hashtable charactors  new Hashtable();  6   7     private CharactorFactory instance;  8     // Constructor   9     private CharactorFactory() 10     { 11         charactors.Add(A, new CharactorA()); 12         charactors.Add(B, new CharactorB()); 13         charactors.Add(C, new CharactorC()); 14     } 15      16     // Property 17     public CharactorFactory Instance 18     { 19         get  20         { 21             if (instance ! null) 22             { 23                 instance  new CharactorFactory(); 24             } 25             return instance; 26         } 27     } 28  29     // Method 30     public Charactor GetCharactor(string key) 31     { 32         Charactor charactor  charactors[key] as Charactor; 33  34         if (charactor  null) 35         { 36             switch (key) 37             { 38                 case A: charactor  new CharactorA(); break; 39                 case B: charactor  new CharactorB(); break;  40                 case C: charactor  new CharactorC(); break; 41                 // 42             } 43             charactors.Add(key, charactor); 44         } 45         return charactor; 46     } 47 } .NET框架中的应用     Flyweight更多时候的时候一种底层的设计模式在我们的实际应用程序中使用的并不是很多。在.NET中的String类型其实就是运用了Flyweight模式。可以想象如果每次执行string s1 “abcd”操作都创建一个新的字符串对象的话内存的开销会很大。所以.NET中如果第一次创建了这样的一个字符串对象s1下次再创建相同的字符串s2时只是把它的引用指向“abcd”这样就实现了“abcd”在内存中的共享。可以通过下面一个简单的程序来演示s1和s2的引用是否一致 1 public class Program  2 {  3     public static void Main(string[] args)  4     {  5         string s1  abcd;  6         string s2  abcd;  7   8         Console.WriteLine(Object.ReferenceEquals(s1,s2));  9  10         Console.ReadLine(); 11     } 12 } Flyweight实现要点 1面向对象很好的解决了抽象性的问题但是作为一个运行在机器中的程序实体我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题一般不触及面向对象的抽象性问题。 2Flyweight采用对象共享的做法来降低系统中对象的个数从而降低细粒度对象给系统带来的内存压力。在具体实现方面要注意对象状态的处理。 3享元模式的优点在于它大幅度地降低内存中对象的数量。但是它做到这一点所付出的代价也是很高的享元模式使得系统更加复杂。为了使对象可以共享需要将一些状态外部化这使得程序的逻辑复杂化。另外它将享元对象的状态外部化而读取外部状态使得运行时间稍微变长。
http://www.pierceye.com/news/892223/

相关文章:

  • 怎么做加盟网站海南网站搭建外包
  • 没有网站可以做落地页网站体验方案
  • 重庆便宜做网站的网站内容注意事项
  • 温岭手机网站建设企业网站建设遵循的原则
  • 美丽乡村 村级网站建设wordpress地图主题
  • 做双语网站多少钱建立设计网站富阳
  • 为什么有网网站打不开怎么回事网站怎样添加友情链接
  • 中国五码一级做爰网站wordpress去掉评论注册
  • 网站备案修改域名贵阳仿站定制模板建站
  • 渭南 网站集约化建设淘宝网站开发技术名称
  • 临沂做网站费用wordpress新浪微博图床插件
  • 游戏网站建设收费明细WordPress 中英文翻译
  • 如何建设一个企业网站wordpress底部导航代码
  • 公司网站页面设计思路互联网家装公司
  • 网站文字源码网上购物商城源代码
  • 彩票网站做一级代理犯法吗购物网站开发设计类图
  • 固镇做网站多少钱乐清网络公司哪家好
  • 绿色农业网站模板做网站有什么比较好看的动效
  • 百度aipage智能建站系统wordpress打印代码
  • 深圳招聘官网深圳搜索引擎优化推广便宜
  • 创建网站大约9377传奇
  • 单页面网站可以做自适应网站吗建筑设计培训
  • 做海报可以在哪些网站下载素材一键生成装修效果图app
  • 福田区住房和建设局官方网站wordpress仿凡客商城主题
  • 做下载网站用什么程序好深圳公司注册服务
  • 猎头网站模板济源专业网站建设(制作网站)
  • kotlin做网站单页应用网站
  • 邢台网站改版开发长沙教育网站开发
  • 网站开发人员必备技能网站背景图片自动切换
  • 企业网站建立策划书有网站吗给一个