a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 148|回复: 1

[基础知识] Java设计模式:Flyweight模式

[复制链接]
发表于 2012-8-4 12:37:27 | 显示全部楼层 |阅读模式
GOF:运用共享手艺有用地撑持年夜量细粒度的对象。 - [5 I, m% V, J
  诠释一下概念:也就是耸ё仝一个系统中如不美观有多个不异的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。好比说(这里引用GOF书中的例子)一个文本系统,每个字母定一个对象,那么巨细写字母一共就是52 个,那么就要界说 52个对象。如不美观有一个1M的文本,那么字母是何其的多,如不美观每个字母都界说一个对象那么内存早就爆了。那么如不美观若是每个字母都共享一个对象,那么就年夜年夜节约了资本。
& U. ~" P2 @  i1 u7 h1 V) v+ C  在Flyweight模式中,因为要发生各类各样的对象,所以在Flyweight(享元)模式中常呈现Factory 模式。Flyweight的内部状况是用来共享的,Flyweight factory负责维护一个对象存储池(Flyweight Pool)来存放内部状况的对象。Flyweight模式是一个提高轨范效率和机能的模式,会年夜年夜加速轨范的运行速度.应用场所良多,下面举个例子:
# S( g9 z) a0 u' `  b; C  先界说一个抽象的Flyweight类:   package Flyweight;
- F1 ~$ X* o2 n7 Wpublic abstract class Flyweight
- [) h- c4 G" U...
& b& a) j  o. ^{
1 D: @/ W. {! x: t4 R public abstract void operation();
9 Q8 j' w. R- U) P$ p  ~}//end abstract class Flyweight  在实现一个具体类:   package Flyweight;
+ r% S+ i& y& Hpublic class ConcreteFlyweight extends Flyweight) J& L0 C; h5 F/ W$ \2 s/ h1 ^2 _
...
0 k3 w1 c% p/ T* ^8 T' F5 @* o{
6 G% x, z( [* H$ t1 l# Z private String string;4 \9 u! d3 r5 J  i  ~
 public ConcreteFlyweight(String str)* K1 J8 Y* n5 R! ~
 ...
/ t5 q; w6 i& ~3 O$ N1 ?, y: b {
& q/ @4 B, m/ s+ b8 Y3 u- U  string = str;
3 L7 L# c4 y; K, N+ F3 D }//end ConcreteFlyweight(...)
9 @- b; D! j2 p1 G  a5 W' k. S6 _1 J public void operation()
$ k" x8 F1 U  @7 p ...
  C' K. j/ g* B/ V4 }* a% A {" l  ?% m8 Q, g& E* `
  System.out.println("Concrete---Flyweight : " + string);
! N- |2 B- p" z: c" R# K# R }//end operation()+ e! H! z3 a0 U$ g# H
}//end class ConcreteFlyweight  实现一个工场体例类:   package Flyweight;! s! B% r7 D4 x1 u3 `# b
import java.util.Hashtable;
  u3 v2 H; k* }public class FlyweightFactory
/ {8 A. [1 d) D' \  p.../ I3 A: w/ k9 K$ x( ^% ^: l! v
{
4 b7 T0 |5 a9 B( n private Hashtable flyweights = new Hashtable();//----------------------------1% y7 R1 E4 \+ p
 public FlyweightFactory() ...{}
6 i7 w2 {% e* v public Flyweight getFlyWeight(Object obj)2 j! G; }9 P$ j  X
 ...
( n- {  F  t8 Z4 m5 p {
8 I, w& {0 F' y  Flyweight flyweight = (Flyweight) flyweights.get(obj);//----------------22 @% L$ \- |9 S$ ], ?
  if(flyweight == null) ...{//---------------------------------------------------35 q( z: ~+ R$ B2 @0 h" q( P
   //发生新的ConcreteFlyweight7 A0 s& ?2 H; ^: M6 [( y2 `/ [
   flyweight = new ConcreteFlyweight((String)obj);
; o9 z9 Z8 t) L* L4 f& |, z' k, i   flyweights.put(obj, flyweight);//--------------------------------------5& x, U4 S1 j1 ^5 }# ?
  }* }% g* H1 k1 I) `! w$ p6 q
  return flyweight;//---------------------------------------------------------6
  t- J+ u9 K3 _8 C7 j: Q& u% ` }//end GetFlyWeight(...): \& }6 F" S7 c3 s! v4 ~
 public int getFlyweightSize()5 l6 K6 s; h9 y4 _0 p
 ...% i1 ]  ~" R; V# n! u
 {
3 T  w! d1 k1 q9 N1 L% A  return flyweights.size();+ P( Z  [" O: [- p4 h2 t* c
 }
, z7 L( Z, X7 k/ L$ s+ r}//end class FlyweightFactory
- X" ]( q: d6 F: y2 e  这个工场体例类很是关头,这里具体诠释一下:- e5 M; U6 `9 h. E. P
  在1处界说了一个Hashtable用来存储各个对象;在2处选出要实例化的对象,在6处将该对象返回,如不美观在Hashtable中没有要选择的对象,此时变量flyweight为null,发生一个新的flyweight存储在Hashtable中,并将该对象返回。
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:37:28 | 显示全部楼层

Java设计模式:Flyweight模式

</p>  最后看看Flyweight的挪用:   package Flyweight;. x( S- t5 N! ~. ^3 Y& |3 a
import java.util.Hashtable;
$ H( _& e8 a6 S/ ?) _) v. ]- upublic class FlyweightPattern ...{
7 N  q) x! D7 Z3 X* E( }6 G7 L FlyweightFactory factory = new FlyweightFactory(); ! d; r$ ^* `* V! u. o4 V# n6 y
 Flyweight fly1;
- E+ T2 a: I) _9 e. m7 g Flyweight fly2;
3 g0 |, F* K2 Y Flyweight fly3;( i0 K/ F; c5 W8 b" T; p  I, u
 Flyweight fly4;
) K2 Z& `" ?5 i9 U Flyweight fly5;
+ q# H+ r$ [/ f& h Flyweight fly6;
4 _2 \) s7 J% v  Z3 T: U /** *//** Creates a new instance of FlyweightPattern */0 I' p9 W! ?( Q, I& N- M
 public FlyweightPattern() ...{9 ?$ L  _5 j$ ^8 N- e
  fly1 = factory.getFlyWeight("Google");6 U0 L5 P' F" C7 u: b& m% Z4 {4 [
  fly2 = factory.getFlyWeight("Qutr");
* U4 j& D7 {$ \/ l& a0 x% b  fly3 = factory.getFlyWeight("Google");5 \3 \. p. ~- i. W, R8 M& G. K
  fly4 = factory.getFlyWeight("Google");
# X+ N+ S; \8 T0 Z: d  fly5 = factory.getFlyWeight("Google");
8 N) _; m1 Q  u; h" o/ N; u  u  fly6 = factory.getFlyWeight("Google");
' `: x+ ]: C4 Q' J. X }//end FlyweightPattern()
/ ~# d% Q' R% b8 s0 H, G/ {+ ] public void showFlyweight()
( U, N! z4 c; v1 E ...
) Q) g# B% u5 l) C7 K! V) ~ {
  {; T4 k& j( y3 q1 V  fly1.operation();
5 l7 g* r$ x8 R# }+ s2 J1 w4 B5 a4 T  fly2.operation();
0 i' g& A- {) D' ]- B  fly3.operation();' ~8 C2 h9 l7 i4 u- m) j0 v; \% |6 i5 w
  fly4.operation();
! z" A2 ]  S* D  fly5.operation();+ E2 A, O6 H8 ^' N! V9 F. t+ H% E
  fly6.operation();
% g; B9 |) e0 `* j) d4 w7 C  int objSize = factory.getFlyweightSize();
6 a# L# u/ Q8 ^; }  g2 y  System.out.println("objSize = " + objSize);+ s! o0 A7 p# N8 F( h$ d1 k/ Q
 }//end showFlyweight()
0 o+ o7 R7 N- j( D0 C public static void main(String[] args)) Y$ T+ K: J* N+ C& Y! q7 N
 ...
( E' q2 A; j* l% L1 f' Y( E {
) k  _  e9 r- g5 [  System.out.println("The FlyWeight Pattern!");1 `5 q. M7 M8 J" @) q' H0 c+ ?
  FlyweightPattern fp = new FlyweightPattern();$ t% C) O1 M$ |; [# T& p7 Q3 e
  fp.showFlyweight();  m" u4 l. A$ O5 j' e
 }//end main(...)
) S' Y# a+ y1 v% z( G: `}//end class FlyweightPattern  下面是运行结不美观:   Concrete---Flyweight : Google
, c% Z6 Z4 e. UConcrete---Flyweight : Qutr
( W$ [, A* V/ n$ xConcrete---Flyweight : Google3 C, e# D% N* G. H
Concrete---Flyweight : Google" x) V6 C6 Y* K0 V: ?+ G2 e! n" ^) d+ Z
Concrete---Flyweight : Google7 B( r* @4 v1 F1 ?# A1 P, c
Concrete---Flyweight : Google5 g7 `' m  U! X1 n% K- n* ~
objSize = 2 1 x: c5 V' w/ g1 p

: ?: ~& n. `' }* t( U  我们界说了6个对象,其中有5个是不异的,按照Flyweight模式的界说“Google”应该共享一个对象,在现实的对象数中我们可以看出现实的对象却是只有2个。# k, u5 p) g- o/ Q. {% e/ u
  下面给出一个简略单纯的UML图:  
( @8 l5 P( R7 Y% l$ e/ a0 P7 _9 e" U% u# i
  总结:( Q; E- Q6 t: w3 o- X. e
  Flyweight(享元)模式是如斯的主要,因为它能帮你在一个复杂的系统中年夜量的节约内存空间。在GOF的书中举了文本措置的例子,我感受很是适当。那么,在Java中String这个类型斗劲非凡,为什么呢,看下面的例子:   String a = "hello";
4 L( H7 n- c2 c9 cString b = "hello";+ [" i' B% f9 S& t* h' _( U' r
if(a == b)
- Q! [! r& \' D( ]* _" D; |+ Q9 q0 O9 L System.out.println("OK");
& B2 o' Q# C$ Q3 E6 T' u; Relse# z; r& ?- t  |8 J4 B/ H4 I$ v
 System.out.println("Error");  输出结不美观是:OK。稍有经验的人都可以看出if前提斗劲的昵嘟a和b的地址,也可以说是内存空间。那么Sting的实现是不是使用了Flyweight模式呢,不得而知,到此刻还没有研究过。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-4-29 18:29 , Processed in 0.196731 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表