a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 123|回复: 0

[专业语言] Java认证:Java设计模式之Flyweight模式

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
Java认证:Java设计模式之Flyweight模式
4 b+ \" x0 k  P) u' q. @) dGOF:运用共享技术有效地支持大量细粒度的对象。
0 G5 J  R, [, S3 Y% I1 Q解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。比如说(这里引用GOF书中的例子)一个文本系统,每个字母定一个对象,那么大小写字母一共就是52 个,那么就要定义 52个对象。如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了。那么如果要是每个字母都共享一个对象,那么就大大节约了资源。
) g. Y9 {4 U2 l% B; A在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweight(享元)模式中常出现Factory 模式。Flyweight的内部状态是用来共享的,Flyweight factory负责维护一个对象存储池(Flyweight Pool)来存放内部状态的对象。Flyweight模式是一个提高程序效率和性能的模式,会大大加快程序的运行速度。应用场合很多,下面举个例子:
, h* D3 u6 x. o9 ?& ~先定义一个抽象的Flyweight类:  ( z# _% X8 I8 w5 V
package Flyweight;
; W. ?1 q3 K5 X4 T, m; Hpublic abstract class Flyweight
' p* L. a& [, M7 X/ U5 R...5 |6 u% E, ^; R+ ^
{8 Y7 E$ f4 C8 z, R% v! Z) W. U" E" F
public abstract void operation();+ V, M1 h. s/ n
}//end abstract class Flyweight: V+ H. G  m% n
在实现一个具体类:  
% c# S# g! T) d* Bpackage Flyweight;6 P3 _4 f  T6 ~( I. P7 o
public class ConcreteFlyweight extends Flyweight3 Z" X* T8 x7 \& I
...- P! L3 z$ D# O0 Q+ a8 k5 e) }
{. i: A# e3 b& l0 K7 n
private String string;( _$ c4 n, S/ B0 X9 p5 S+ u  s6 [
public ConcreteFlyweight(String str)# J, }  N) f0 x2 l
...
0 [3 v3 `* J' j: J* n. G{+ ?% i) w9 \( s) G' w! j& ?7 h
string = str;
0 b6 r4 \; J8 o6 H}//end ConcreteFlyweight(...)9 r/ c6 D( a" E4 t" V
public void operation()
; ~6 k7 X! n# P) P; |; S..., }! Z; j8 A1 m7 s# O
{
. E& O4 I' w, f. H1 FSystem.out.println("Concrete---Flyweight : " + string);
3 D: n" S5 w- }! Z}//end operation()
8 z- V: B2 w* V}//end class ConcreteFlyweight( u( \$ e' Q$ Y7 d5 K
实现一个工厂方法类:  9 p3 l9 X+ h4 S" M
package Flyweight;
0 V& {' n, J$ S2 Y- zimport java.util.Hashtable;
. N2 r9 G! a- qpublic class FlyweightFactory7 Z/ U6 x1 j) {+ n8 X6 C& Q
...
8 y" H1 |; p. e% o) d+ ^{
$ j5 `+ t1 B: H! Y! h7 V! Pprivate Hashtable flyweights = new Hashtable();//----------------------------1; V. x" A0 B0 ~7 v
public FlyweightFactory() ...{}
% g3 O) b* C2 H  bpublic Flyweight getFlyWeight(Object obj)
* o; H, A+ a$ e8 Y! K...! d3 G5 \/ k9 L  }* t, g
{5 n# M$ d3 P0 H4 D# L9 f  Q
Flyweight flyweight = (Flyweight) flyweights.get(obj);//----------------2' Y0 B1 c5 s$ E" I
if(flyweight == null) ...{//---------------------------------------------------3+ Y$ s; a' c- u; U! g* h
//产生新的ConcreteFlyweight( g# w8 L. h: x/ |+ U
flyweight = new ConcreteFlyweight((String)obj);
( n" {8 s/ O( i, u% I0 pflyweights.put(obj, flyweight);//--------------------------------------5
# ^& D. ~9 B; n6 k6 M6 {& @3 j8 i}
7 z: a5 F! d7 M5 p: Preturn flyweight;//---------------------------------------------------------6
% v3 e: w, w5 Y" L+ y4 L1 w}//end GetFlyWeight(...)3 a% K8 C2 V5 T, P1 w" g) Q8 B
public int getFlyweightSize()2 A; J- @( \& a" b. G$ P
...6 m6 ?1 j6 Q3 l' z; V
{
6 [/ \- q  Z9 |5 d: j$ U/ Dreturn flyweights.size();. r* r0 I; B1 G' w3 X$ S; f3 _5 I
}
: |8 f+ q1 ~* y* U' _}//end class FlyweightFactory
3 t6 I- o% |. ]: d这个工厂方法类非常关键,这里详细解释一下:+ k0 i  `! ?  A; r
在1处定义了一个Hashtable用来存储各个对象;在2处选出要实例化的对象,在6处将该对象返回,如果在Hashtable中没有要选择的对象,此时变量flyweight为null,产生一个新的flyweight存储在Hashtable中,并将该对象返回。% s& O9 i& z% M" ]
最后看看Flyweight的调用:  
+ E/ w; v5 Z" `3 ]+ L# X' v- u0 Ipackage Flyweight;( |& v% f+ Y8 |
import java.util.Hashtable;
) I0 A) z2 E  g1 w7 f/ N% Epublic class FlyweightPattern ...{
; i7 O' u) u5 Q; ?6 lFlyweightFactory factory = new FlyweightFactory();
% M' M2 p2 g) u: [% S) sFlyweight fly1;$ v7 @4 M: {& v+ }
Flyweight fly2;
/ n0 ]- [# t  zFlyweight fly3;. v+ s" t* l7 ?# w7 w) S( _
Flyweight fly4;
/ r* }. o9 m# [1 D8 A& ^' ^Flyweight fly5;" Q0 C' ]: L5 l" h
Flyweight fly6;6 T4 Y( h# ~8 ^
/** *//** Creates a new instance of FlyweightPattern */4 u& ]" d8 k) _% G  Q: w
public FlyweightPattern() ...{
( f7 ^( k8 Y- T2 |% Gfly1 = factory.getFlyWeight("Google");
! ?" Y* p6 l9 B6 K/ jfly2 = factory.getFlyWeight("Qutr");
" o' a( _7 {+ F5 g- t  X5 _fly3 = factory.getFlyWeight("Google");2 Q  d$ J+ @: z0 T: |
fly4 = factory.getFlyWeight("Google");
$ c1 M7 c' o! E8 |# {) efly5 = factory.getFlyWeight("Google");
4 }5 U1 E( Y! c2 \; L6 afly6 = factory.getFlyWeight("Google");* ^& w5 E1 W- C  }7 Q- R, P( O
}//end FlyweightPattern()$ E+ y; Z: X/ p; h* `9 f
public void showFlyweight()  O) k+ n# D0 J/ T# C/ l
...
# i; ?5 }" U8 z' i9 g7 k$ y  V{$ A7 k7 W/ {1 k3 f6 T8 X
fly1.operation();& E6 O: [- F" y: B* W" _# }- I
fly2.operation();4 O+ L" P  C3 T0 F# [# m! U
fly3.operation();
( X) D! F+ I! T9 p0 f- _fly4.operation();7 t: Z" {3 {0 s( f, Y
fly5.operation();
. V9 l! L  d; j. X5 ?9 Wfly6.operation();+ a8 I7 u, [& S- L! C6 U
int objSize = factory.getFlyweightSize();! |  A! N7 F9 t. x
System.out.println("objSize = " + objSize);* ]: d  p/ L8 `* d
}//end showFlyweight()
& N" p5 ~4 u/ {% M8 Rpublic static void main(String[] args)
' T# M# Z. d, c# n6 u' s...
; z, ?3 @; R; ?$ [: c2 n0 \{
; T# a' |# h7 W9 M8 cSystem.out.println("The FlyWeight Pattern!");
9 M  s  K8 c4 o; g/ FFlyweightPattern fp = new FlyweightPattern();7 d! u: q6 ?' y  U
fp.showFlyweight();  b9 o/ i8 g+ D# f) i
}//end main(...)+ @% \# g# N; U( n
}//end class FlyweightPattern+ R+ t# p5 ~- F# R  \( r  {
下面是运行结果:  
$ x; A  ?; V3 P& r2 tConcrete---Flyweight : Google* m! g- E% U# o# Z: k; t2 F
Concrete---Flyweight : Qutr
3 x! f) n% E( ]5 YConcrete---Flyweight : Google
& C. D8 ]: q  FConcrete---Flyweight : Google
1 Y; Y- R- q5 l. L! Y0 DConcrete---Flyweight : Google; p* L  i% E$ s
Concrete---Flyweight : Google5 N* a* c8 X# ?
objSize = 25 l2 j2 _9 r; w# B
我们定义了6个对象,其中有5个是相同的,按照Flyweight模式的定义“Google”应该共享一个对象,在实际的对象数中我们可以看出实际的对象却是只有2个。# Z! x( F; X1 m9 q
# Y5 N& _* d+ K8 R* \/ I6 J2 f
总结:
( Z  w" Q: M; Z: x% D8 ]Flyweight(享元)模式是如此的重要,因为它能帮你在一个复杂的系统中大量的节省内存空间。在GOF的书中举了文本处理的例子,我觉得非常恰当。那么,在Java中String这个类型比较特殊,为什么呢,看下面的例子:  ! m' O$ q8 A. p! a+ r9 H0 A
1 z4 }7 `" a6 Q
String a = "hello";
1 r  l$ r8 c# \) N7 ^: ~7 KString b = "hello";+ p& {* U3 N4 @- B
if(a == b)
( J2 S7 G$ b4 R3 x0 rSystem.out.println("OK");+ g" _+ q& z1 U! q" B( U$ |& J
else
7 v& @) ^1 o/ o6 E" x% HSystem.out.println("Error");# ?7 ]9 S( U% z, Z' A; |1 a% u+ K
输出结果是:OK。稍有经验的人都可以看出if条件比较的是两a和b的地址,也可以说是内存空间。那么Sting的实现是不是使用了Flyweight模式呢,不得而知,到现在还没有研究过。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 00:30 , Processed in 0.186599 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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