从Java类库看设计模式 4

当初Java刚刚推出来的时候,AWT可是一个比较热的话题,虽然现在有被Swing取代的趋势。但是我一直都觉得AWT也有其优势,至少它使用的本地代码就要比Swing快上许多,而且,可以为用户提供熟悉的本地操作系统 界面。如果在Windows XP中运行基于AWT的程序的话,XP中绚烂多变的界面Theme可以轻易应用到AWT程序中,而Swing就不行了,因为AWT所调用的是本带代码,使用的是本地的窗体控件。当然,Swing也有其好处,不可一概而论。

   简单来讲,AWT提供对程序员的是对窗体界面系统的抽象,而在内部实现中,针对每一种操作系统,分别有不同实现,这就是同位体(Peer)的概念。当程 序员调用AWT对象时,调用被转发到对象所对应的一个Peer上,在由Peer调用本地对象方法,完成对象的显示。例如,如果你使用AWT创建了一个 Menu类的实例,那么在程序运行时会创建一个菜单同位体的实例,而由创建的同位体的来实际执行菜单的现实和管理。不同的系统,有不同的同位体实 现,Solaris JDK将产生一个Motif菜单的同位体,Windows下的JDK将产生一个Windows的菜单的同位体,等等。同位体的使用,使得交叉平台窗口工具 的开发变得极为迅速,因为同位体的使用可以避免重新实现本地窗口控件中已经包含的方法。

  图六:AWT中的组件和其对等体

  

   实际上,从设计的角度来看,这是一个抽象和实现分离的过程--AWT是抽象,同位体是实现,抽象和实现各自成为一个对象体系,它们由一个桥连接起来,可 以各自发展各自的对象层次,而不必顾虑另一方面。这就是Bridge模式所提供的思想。Bridge模式更可以提供在各个不同的实现中动态的进行切换,而 不必从新编译程序。

  通常,Bridge模式和AbstractFactory模式一起工作,由AbstractFactory来创建一 个具体实现的对象体系。特殊的,当只有一个实现的时候,可以将Implementor抽象类去掉。这样,在抽象和实现之间建立起了一一对应的关系,但这并 不损害Bridge模式的内涵。这被称为退化了的Bridge模式。

  很多时候,Abstraction层次和Implementor层 次之间的方法都不是一一对应的,也就是说,在Abstraction和Implementor之不是简单的的消息转发。通常,我们会将 Abstraction作为一个抽象类(而不是接口)来实现。在Implementor层次中定义底层的,或者称之为原子方法,而在 Abstraction层次中定义一些中高层的基于原子方法的抽象方法。这样,就能更为清晰的划分Abstraction和Implementor,类的 结构也更为清晰。

  图七:Bridge模式对系统的划分

  

   下面,我们来看一个Bridge模式的具体应用。考虑这样的一个问题,需要生成一份报告,但是报告的格式并没有确定,可能是HTML文件,也可能是纯 ASCII文本。报告本身也可能分为很多种,财务报表,货物报表,等等问题很简单,用继承也较容易实现,因为相互之间的组合关系并不是很多。但是,我们现 在需要用Bridge的观点来看问题。

  在Bridge模式中,使用一个Report类来描叙一个报告的抽象,用一个Reporter类 来描叙Report的实现,它的子类有HTMLReporter和ASCIIReporter,用来分别实现HTML格式和ASCII格式的报告。在 Report层次下面,有具体的一个StockListReport子类,用来表示货物清单报告。

  1   public abstract class Report
  2
  3   {
  4
  5   Reporter reporter;
  6
  7    public Report(Reporter reporter) {
  8
  9    this .reporter = reporter;
10
11   }
12
13    // 抽象类使用桥接对象的方法来实现一个任务
14
15    public void addReportItem(Object item){
16
17   reporter.addLine(item.toString());
18
19   }
20
21    public void addReportItems(List items){
22
23   Iterator iterator = items.iterator();
24
25    while ( iterator.hasNext() )
26
27   {
28
29   reporter.addLine(iterator.next().toString());
30
31   }
32
33   }
34
35    public String report(){
36
37    return reporter.getReport();
38
39   }
40
41   }
42
43    public class StockListReport extends Report{
44
45   ArrayList stock = new ArrayList();
46
47    public StockListReport(Reporter reporter){
48
49    super (reporter);
50
51   }
52
53    public void addStockItem(StockItem stockItem){
54
55   stock.add(stockItem);
56
57   addReportItem(stockItem);
58
59   }
60
61   }
62
63    // 实现层次的抽象父类定义原子方法,供抽象层次的类调用
64
65    public abstract class Reporter{
66
67   String header = "" ;
68
69   String trailer = "" ;
70
71   String report = "" ;
72
73    public abstract void addLine(String line);
74
75    public void setHeader(String header){
76
77    this .header = header;
78
79   }
80
81    public void setTrailer(String trailer){
82
83    this .trailer = trailer;
84
85   }
86
87    public String getReport(){
88
89    return header + report + trailer;
90
91   }
92
93   }
94
95    public class HTMLReporter extends Reporter{
96
97    public HTMLReporter(){
98
99   setHeader( " /n/n/n " );
100
101   setTrailer( " /n " );
102
103   }
104
105    public void addLine(String line){
106
107   report += line + "
108
109   /n " ;
110
111   }
112
113   }
114
115    public class ASCIIReporter extends Reporter{
116
117    public void addLine(String line) {
118
119   report += line + " /n " ;
120
121   }
122
123   }
124
125

   实际上,Bridge模式是一个很强大的模式,可以应用在很多方面。其基本思想:分离抽象和实现,是设计模式的基础之一。正如GOF所提到的:"找到变 化的部分,并将其封装起来";"更多的考虑用对象组合机制,而不是用对象继承机制"。Bridge模式很好的体现了这几点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tof21

支持原创

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值