架构情势-界面组装器情势[Java编程]
本文“架构情势-界面组装器情势[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
本文提出了一种界面计划中的架构情势-界面组装器情势,它努力于分化界面,将界面和组装行为解耦,将界面逻辑处理与范畴逻辑处理解耦,这样我们在开辟GUI胖客户端界面利用时可以从众多的界面掌握管理中摆脱出来,而专注于我们的后台业务逻辑的开辟.通过该情势,我们可以动态地组装我们的界面,我们乃至还可以在我们的界面中轻松地插入 transaction 事件或 session 会话管理.
本文将通过解析计划一个架构的历程来说授该情势,从一个简单的计划模子开始,一步步走向一个完好的架构.借此也向大家展示一个架构计划的思维历程.别的,本文给出了 Eclipse SWT(Standard Widget Toolkit) 的示例.
问题引出
界面计划常常是情势产生的本源,无论是架构情势,还是计划情势,比方 MVC 情势,Observer,Facade 等,也是整个软件行业向前发展的动力.遗憾的是,即便在软件技术发达的本日,界面计划还是软件计划中的难以冲破的瓶颈之一.我们用过 Java swing 或 Eclipse SWT 作过项目的都知道,要将界面举行分化是很艰难的,它不像我们的业务逻辑,可以便利地按职责分化到差别的类中去实现,因为各个业务逻辑之间耦合度很低.但界面逻辑不一样,你不大概将一个文本框的读取操作委任到另一个类中去,并且各个界面元素之间彼此依靠,无法去除耦合,普通的做法只能是在界面元素的事件触发(比方按钮点击事件)时,将输入数据封装成一个数据对象传给后台的逻辑处理类来处理.
Eclipse 的 Wizard 框架在界面分化上供应了一种很好的实践,它可以将按钮区和其他界面辨别离出来,用近似 MVC 的方法实现了 Wizard 框架.但这个实现并非没有瑕疵,一个缺陷是 wizard 是一个 plug-in,这样的话就削减了可重用性,不能移植到 eclipse 以外的环境.另一个缺陷就是它引入了很大的复杂性,并且在一些对界面元素的掌握上丧失了一些精密掌握的本领,这大概是它过度地夸大了自动化和用户扩大的便利性的来由.比方,用户不能将自己的逻辑插入按钮区的按钮事件掌握中,而只能在自定义区的界面元素 Listener 中设定按钮区状况,假如用户自定义的界面元素很多,就需求很多个 Listener 来组合判断一个按钮状况(如能否举行"下一步"),这样的话就很影响性能,并且无端地多了一堆复杂的逻辑判断,也就是说本来只需在按钮 Listener 事件中处理的逻辑目前要分离在各个界面元素的 Listener 中去处理.这也恰是计划上一个值得反复夸大的广泛问题:当你要保持架构或计划的完善性时必定会以丧失其他特点为代价.世上永久没有完善的东西,我们只关注合适我们的.
我下面要提出的这个架构情势的灵感来自于我的一个真实项目,一个用 RSA(Rational Software Architect)/Eclipse 建模的项目,在 RSA 环境中,读写模子都必须在一个特有的 context 下才能操作,这就意味着我在界面的启动之前必须封装好输入数据,关闭之后返回输出数据,而不是直接处理数据,必须对输入/输出数据对象举行封装.正如前面提到的,这种情形界面计划中很广泛.所以,在情势命名时我用了组装器-assembler 这个词,有一层意思是输入/输出数据对象的组装,另一层意思就是界脸部件(界面元素的调集)的组装,这里的组装还有更深层次的涵义就是指界脸部件的可装配性,可以在运行时动态组装.并且这个情势可以用任何语言(Java,C++ 等)来实现.在这里我会从一个简单的计划模子开始,一步步走向一个完好的架构.借此也向大家展示一个架构计划的思维历程.本文中给出了 Eclipse SWT(Standard Widget Toolkit) 的示例.
界面分化
在 Eclipse SWT 中,有几个重要的界脸部件,一个是Shell-界面的最外层容器,近似 Java Swing 中的 Frame,另一个就是 Composite-界面元素的调集的容器,近似 Java Swing 中的 Panel.我们的界面分化将从 Composite 开始,(Shell 本身是不需求分化的).我们可以在 Shell 中装配上一个空的 Composite ,然后我们的具体界面元素都定义在这个 Composite 里.这样就把 Composite 逻辑从 Shell 中别离出来了,因此我们目前有了 2 个类(目前我们用概念类来表示):
图1. 把 Composite 逻辑从 Shell 中别离出来
Editor : 该类处理 Shell 的逻辑,如显示-show,关闭-close,它负责成立和销毁 EditorComposite.
EditorComposite: 该类处理 Composite 的界面逻辑,如成立界面元素.
有两点值得注意,第一,Editor 负责 EditorComposite 的成立和销毁,也就是生命周期的管理.那么我们可以想到,假如我们的界面需求 transaction-事件或 session-会话的管理,那么我们完好可以让 Editor 来负责这项职责,而不是分离在各个 EditorComposite 中.怎么扩大界面的事件功效大概会很复杂,这已经超越本文的谈论范围,我只是从架构的层面来解析大概有的可扩大性.第二,一个 Editor 可以包含多个 EditorComposite,比方我们的属性页,此时我们在Shell中定义的空的 Composite 将会是一个 TabFolder. 还有一种情形,就是我们可以按照某种逻辑来判断我们需求装配哪个 EditorComposite.这就要求我们有一个装配的行为.
界脸部件装配
当我们的装配逻辑很简单时,我们可以定义一个 assemble() 办法来负责装配行为.但是当我们的界面需求组装一系列 EditorComposite 时,就会牵扯到挑选逻辑,挑选逻辑不一定很复杂,但我们还是应当把这种行为从 Editor 中别离出来,这样 Editor 可以集合精神负责与用户交互方面的职责,而装配行为被分配到一个新的类 EditorAssembler 中,这样做还有一个好处,就是我们一旦有新的 EditorComposite 需求增添时,我们只需求改变 EditorAssembler 的代码,而不用改正 Editor 的代码,这就把改变断绝出来,对 Editor 的改正关闭,对装配行为的扩大开放.这恰是面向对象计划范畴反复夸大的基本原则-开放-封闭原则(Open-Close Principle).经太重构后的架构以下图:
图2. 重构后的架构
EditorAssembler:该类处理 EditorComposite 的成立,还包含多个 EditorComposite 的挑选逻辑.
这里的挑选逻辑我们可以用 if/else 或 switch/case 来硬编码,假如逻辑不是很复杂并且此后的改正不会太频繁的话,用这种办法就充足了,当然可以考虑将多个 EditorComposite 的装载信息专门用一个资源/信息类来存储 style="COLOR: #000000" href="http://storage.it168.com/" target=_blank>存储,这在 EditorComposite 对比多的情形下很有效,这样每次增添 EditorComposite 就只需求改变这个资源类,这是一个很有效的建模原则(为了简化我们的核心模子,我在这里不将这个资源类表示出来).
假如进一步考虑到我们的组装逻辑会对比复杂,或会对比简单改变,乃至在运行时动态改变,我们便可以将众多的 EditorComposite 和复杂的逻辑存储在一个元数据文件中,如 XML 或配置文件.这样,有新的 EditorComposite 需求支持,或改正装配逻辑时,不用改正 EditorAssembler 类,只要改正元数据文件便可.这样便可以很动态的配置我们的界面.这里会有一个架构衡量的问题,元数据由它的长处,也有它的缺陷,其一,必须编写解析它的类,复杂性增添了,其二,不需求编译是它的长处也是它的缺陷,对 XML 或配置文件我们可以随便改正,只有在运行时发现非常才知道改错了,并且也大概被人蓄意破坏掉.所以我们只在真的需求很频繁地改正 EditorComposite 的配置或常常需求增添 EditorComposite 时才采取元数据筹划.在这里我偏向于采取资源类筹划.
InputDataObject:该类封装了输入数据.由 EditorComposite 负责解析这些数据.
OutputDataObject:该类封装了输出数据.由 EditorComposite 负责产生这些数据.
Editor 负责传输这两个数据对象.
以上是“架构情势-界面组装器情势[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |