a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 202|回复: 3

[基础知识] Java基础:Composite模式

[复制链接]
发表于 2012-8-4 12:37:27 | 显示全部楼层 |阅读模式
Composite定义:   将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.
( x3 S  Y5 |- P' A4 ~8 E# v7 ]  Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行 时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。
4 g* Q# i" p2 s: h% A7 B; [4 }/ y  所以Composite模式使用到Iterator模式,和Chain of Responsibility模式类似。; q: Q3 w' F$ z. {
  Composite好处:
7 a! r( {2 z! H; M  1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
+ \! \5 d; R$ e+ N  2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。
; P8 p4 F5 s! x  如何使用Composite?
5 i/ \; s6 S2 u' t. d$ p: @0 ]1 w0 l) ]  首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们(或称部件Component).
* X. ~# Q7 z% |! y  下面的代码是以抽象类定义,一般尽量用接口interface,
- ^: ^7 a, l* ^. v% C) V3 \+ a  public abstract class Equipment7 O% S  q5 r4 I
  {0 J; K) N& r# Q9 P4 I# M2 Q/ V
  private String name;
* Z. i! `9 j0 D  //实价2 Y' z& ]: }) R
  public abstract double netPrice();6 f, ?7 n* E2 q
  //折扣价格
, k5 S  H) D) o. N; o& z& x  public abstract double discountPrice();
6 c9 I% Z( s$ N3 Z6 i2 ]; U  //增加部件方法
+ h, v$ L  V& S! i  O1 O+ d7 h  public boolean add(Equipment equipment) { return false; }
% R' o4 t/ P  M  y: d. p7 ?  //删除部件方法4 g& ~& g8 a/ a5 Z
  public boolean remove(Equipment equipment) { return false; }
% Q9 F4 h8 T; w5 Y4 t; V( n2 @' v( K! N, p  E6 V
  //注意这里,这里就提供一种用于访问组合体类的部件方法。
回复

使用道具 举报

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

Java基础:Composite模式

</p>  public Iterator iter() { return null; }$ u# k0 u9 D* \. n3 b
  public Equipment(final String name) { this.name=name; }7 Z( ^- s" `5 w; Z3 Q0 z/ V/ p+ b9 U
  }/ U, Z9 c5 I! j4 X: k; l
  抽象类Equipment就是Component定义,代表着组合体类的对象们,Equipment中定义几个共同的方法。8 L, k6 Y4 o' {( A. S6 k
  public class Disk extends Equipment
- z: `( H# u9 c: H$ b  {
$ A: e: H& ^; d& ~  public Disk(String name) { super(name); }! ~5 f+ ^8 t8 d5 \: A8 C
  //定义Disk实价为1' L* D1 r) n6 Q, `- ?2 ]8 G$ P
  public double netPrice() { return 1; }8 ?  N2 x  p. ~
  //定义了disk折扣价格是0.5 对折。
* O2 Y8 q' p2 G, L4 y6 Z3 b  public double discountPrice() { return 0.5; }
; A. h1 O) s" Z* g0 i. d3 h  }2 g3 V+ O7 F- _9 q( u" p. N$ [; q0 k' ?
  Disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( Primitive)。
" b& M6 F* `% W; A9 N  还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有'儿子',这是树形结构中通常的情况,应该比较容易理解。现在我们先要定义这个组合体:
5 ~* x, g% H# J" ~" d7 q) ]2 Z6 N9 O8 @  abstract class CompositeEquipment extends Equipment
2 K3 w. u; v8 W" @! i$ S  {# P+ F' k2 p  K+ {6 N1 h& N
  private int i=0;3 ~/ \' ^  M4 c! P* @" j1 I5 {
  //定义一个Vector 用来存放'儿子'
4 \. o- Y6 r* w6 N- s  private Lsit equipment=new ArrayList();
, Z$ [% Y6 E0 e7 g% q  public CompositeEquipment(String name) { super(name); }
3 U) B, q* W  P1 r  public boolean add(Equipment equipment) {
# @& s! ^3 Z. t" y+ h9 f! e7 S  this.equipment.add(equipment);; X( B7 ^0 Z5 D# i9 x8 T* F! _
  return true;
# J* ^0 N: d! P2 d  }
( j- r0 H, j, t- I  public double netPrice()  C, Y* G! ~" s+ Y
  {
' H, q1 B( n0 R* R  double netPrice=0.;
- z  s/ V( W4 B  Iterator iter=equipment.iterator();7 q4 _$ `1 ]6 g3 b
  for(iter.hasNext())  H! [  e7 i% ?* S8 j& U4 v4 F' l
  netPrice+=((Equipment)iter.next()).netPrice();( A' ]1 [4 l8 ?% u; R  C, F
  return netPrice;( O  X  I+ B5 J- _7 n
  }: _, Q9 x- I% N: T3 x
  public double discountPrice()% i) J; R" C: B" e- T! m# V( H) T
  {
8 s, l6 z5 K* p6 E  b& z9 R. J/ }- I  double discountPrice=0.;
8 o4 V4 x. l2 Z8 W  Iterator iter=equipment.iterator();
2 G+ J. p* t6 Y, X$ w4 E, |1 L1 [  for(iter.hasNext())
  O/ g% J  [/ j, p8 ~- ~  discountPrice+=((Equipment)iter.next()).discountPrice();
5 i" l) P; l& `) g; [6 r, D) |* k  return discountPrice;
/ [% e8 m* G5 }( f  }
( j& x* n& q3 l1 u5 m8 y- A  //注意这里,这里就提供用于访问自己组合体内的部件方法。
7 X1 R" V( ~9 P; y! ?5 s! n' T
" y+ u9 ]% ~+ x, s$ @  //上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元素.
回复 支持 反对

使用道具 举报

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

Java基础:Composite模式

</p>  public Iterator iter()- `" t1 p4 w8 A1 T/ w
  {+ q) `6 m0 `5 t8 t' D
  return equipment.iterator()" W6 ?& g- @/ X  W) Y2 K9 O2 C
  {& b5 j7 [$ l+ {# y5 L1 w, @
  //重载Iterator方法
: D2 M. S7 U( H. j; E5 f! j+ A3 f( B& x1 B# X3 t; f
  public boolean hasNext() { return i
回复 支持 反对

使用道具 举报

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

Java基础:Composite模式

</p>  //将一个10GB的硬盘装到 PC Chassis (将硬盘装到盘盒里)' {- L& h. z$ X( p9 d# g" p% a+ R2 C' K
  chassis.add(new Disk("10 GB"));$ |9 x9 H3 w( T$ @3 M5 ?) X2 ~5 H/ R
  //调用 netPrice()方法;
- ^! P' s9 c/ @$ K, Z  System.out.println("netPrice="+cabinet.netPrice());
/ `$ `8 }% @+ z3 Y  System.out.println("discountPrice="+cabinet.discountPrice());+ ?* f' r8 v2 s
  上面调用的方法netPrice()或discountPrice(),实际上Composite使用Iterator遍历了整个树形结构,寻找同样包含这个方法的对象并实现调用执行.& N+ H' l) _0 O/ n2 Q+ R8 I
  Composite是个很巧妙体现智慧的模式,在实际应用中,如果碰到树形结构,我们就可以尝试是否可以使用这个模式。) t3 r& s+ b( i7 [9 ?
  以论坛为例,一个版(forum)中有很多帖子(message),这些帖子有原始贴,有对原始贴的回应贴,是个典型的树形结构,那么当然可以使用Composite模式,那么我们进入Jive中看看,是如何实现的.
0 i% C( I3 ~* a  Jive解剖0 T3 A: ^5 l7 s% c6 G
  在Jive中 ForumThread是ForumMessages的容器container(组合体).也就是说,ForumThread类似我们上例中的 CompositeEquipment.它和messages的关系如图:
7 |* H, A/ H3 V3 H% @3 f  [thread], _. ]# `! }* a; x6 ]
  |- [message]
: Z# w" Z( m! s9 B; h  |- [message]& O: z. y) y/ n4 t
  |- [message]1 e# E3 C7 k/ L& D4 ^( C# e6 V
  |- [message]
6 e$ i* K: h6 N% y* p' B3 A- r) B  |- [message]
' D8 @* R! ?- W( [# k  我们在ForumThread看到如下代码:
" u, D2 ]$ z9 H! f# C  c/ k  public interface ForumThread {
& v7 `' Z, x2 o. Q- U7 @9 n/ s3 g( ~  ....2 t% g# ?& W/ x' I  L
  public void addMessage(ForumMessage parentMessage, ForumMessage newMessage). `  g4 h* R# o. |
  throws UnauthorizedException;; d" h3 k4 s5 d& [# |* e2 w
  public void deleteMessage(ForumMessage message)
# Y" x  H! g( ]" e, ?( w$ W  throws UnauthorizedException;0 P  V2 V5 E$ P' E. c1 K, r
  public Iterator messages();1 s* @6 G) N9 |& L8 U
  ..../ C% g  d0 J& B& o( f2 S0 e
  }' T3 I+ c+ a( i6 }( ~1 o  {8 W
  类似CompositeEquipment, 提供用于访问自己组合体内的部件方法: 增加 删除 遍历.
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 21:46 , Processed in 0.431897 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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