SCMLife.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 5561|回复: 1

[推荐] 利用以代码为中心的开发和建模实现成功的代码重用

[复制链接]
发表于 2012-5-15 11:29:02 | 显示全部楼层 |阅读模式
本帖最后由 技术狂人 于 2012-5-15 11:32 编辑 1 B$ K1 S  z) q4 D4 O

6 W  z! h  {, {; H新的开发项目往往从现有的源代码开始。了解代码对于重用是必不可少的,重用并不像看起来那么简单。例如,也许原来的开发人员已经离职或退休。代码可能一直由多个开发人员编写,或来自多个来源。代码的存在形式可能是您的公司所拥有的代码、外部代码(例如,开源或现成的代码)或库。它很可能在多年后已经有所改变和发展。无论代码的历史如何,您需要知道源代码如何进行交互,以及它包含哪些内容。您需要了解如何将代码结合在一起,将来如何最好地利用它,以及您可能想修改哪些部分。
7 k! Q8 d! Z8 ^$ q" q" ]$ ?1 y% X- U3 d7 q5 x0 ], J/ R5 F
代码分析的原因
; M+ L* H6 j. a+ E% A
$ q6 ?4 G, _/ Y' E% E分析代码的主要原因可以概括为:文档、重用、修改或维护。根据具体的情况,其动机包括:
+ Q1 m+ {8 l" K4 ?0 ~4 j# ^* h
  • 记录您的代码,以便您更好地理解它,并为下一次开发人员退休或离职做好准备(“记录” 意味着有用于解释代码的图表)
  • 建立产品线,其功能都在一个产品中,而在另一个产品线中,您可能不需要该产品
  • 将应用程序修改或更新为一个新版本
  • 维护现有代码7 f. X8 Z" \2 q- }+ e+ y# M" D
所有这些原因对于更好地理解代码都是合理的。本文着重于重用原因和实现重用所必须的代码分析。
8 H/ O( p+ T$ X1 R. I" `* ?

! [0 D$ D4 K  G8 c4 l
! B* d1 j3 W% l1 }/ ]* v重用的风险
1 B7 O: d, U6 h  t  F
6 d1 f; W; d: D) I; `' m4 h重用有潜在的风险,某些具体的原因可能导致重用失败。证明投资的挑战之一,是某些管理人员不允许团队花时间了解旧代码。失败的另一个潜在风险是缺乏对代码的域和组件的了解。分析瘫痪又是另一个潜在的风险。
' M( t' W5 c+ X努力了解所有的代码可能是一项艰巨的任务,分拆现有代码并确定要重用的关键代码非常重要。前期应该多花一些时间来评估应该重用哪些代码组件。在某些情况下,可能有必要记录在您的代码中所做的一切(如监管的原因),但是,试图重用并记录所有代码的效率通常并不高。在大多数情况下,我们的目标是智能地确定要记录哪些代码块,以及要重用哪些代码块。3 c1 j2 P/ Y: u% \' J5 o7 ^


  G; u* I" c8 Q6 Y& X* J. p成功的四个关键要素; O2 f' f+ f4 Q# R! o4 s
. b4 F/ J! _+ n
要获得成功,关键要素是:2 W0 x  s. B  {) t0 T; q/ O8 S' N
  • 了解原始代码的架构,从而识别组件、边界和接口
  • 确定潜在可重用的代码
  • 估计重用与重构组件的时间比较
  • 基于每个组件确定重用哪些内容以及重用的方式:不需要更改、小的更新和主要更新
    / I$ ~; B5 x: g* w

0 c0 @' D9 R4 }1 \
使用统一建模语言澄清软件代码
7 [. n; n# [" d$ T  P! @$ r无论您什么时候想获得对代码的明确了解,统一建模语言 (UML) 都是一个很好的方法。UML 是一个用于表示代码的标准图形化语言。它使您可以说明代码实际上在做什么,而这反过来又可以使您看到组件设计的全局。UML 使您能够理解原始代码的架构,从而识别组件、边界和接口。UML 澄清了代码是如何结合在一起的。您可以使用 UML 来分析你的代码。分析是记录代码之前的第一步。
: @: }- s& R% b8 v- |
" y; Z( O6 N% f( |利用 UML 建模组合以代码为中心的开发
! P2 |& {& {  E0 Y5 @) n/ z. H
, J3 b, f1 x0 H" E0 b/ M本文前面说明了成功的四个关键要素,其中一个要素是基于每个组件确定重用哪些内容和重用的方式。如果您想保持现有的代码并记录它,那么您可以继续采用以代码为中心的开发方式,但要将它与建模相结合。您可能不需要在模型中生成代码,但您肯定想更好地沟通和了解现有的代码如何组合在一起。通过将以代码为中心的开发与建模相结合,可以做到这一点。2 m1 i* n8 |; K% i* x. A; D9 m
如果您想了解现有的软件代码,以便能够重用它来创建新的产品或维护多个现有产品,那么模型驱动的开发可能是最佳解决方案。通过采用以代码为中心的开发,并结合模型驱动的开发,您可以确定自己要维护和重用代码的哪一部分。
* H2 a$ `2 Z- X0 V  w术语的定义5 A3 m. h. c9 U' v. w- T
" J3 S: `- G- I" @& q) i) \$ e
以模型为中心模型不仅驱动架构,还驱动最终的应用程序代码。. x: p( \# k4 n% o- t6 ~% ~
以代码为中心将代码作为一个可视化的参考导入模型。这意味着将使用模型来帮助显示架构,但永远不会改变代码。为了更新设计,您需要更新代码,然后将它再次导入模型。
$ f1 u" k2 [7 O: I) J& v 动态模型代码关联 (Dynamic Model Code Associativity, DMCA)在 IBM® Rational® Rhapsody® 建模软件中,这表示更新的方向。您可以从模型到代码进行更新,或者从代码到模型进行更新,抑或可以指定双向自动更新。往返 是将代码更新带进模型的过程。9 g9 R1 u; K# Z3 q' s6 D) n

# q! }& b& x9 c 不同类型的用户喜欢的开发场景是不同的。喜欢在模型中工作的用户被称为 “以模型为中心的用户”,而以代码为中心的用户喜欢在代码中完成所有工作。还有一些人处于两者之间。您可以使用您选择的代码重用和建模类型来适应不同类型的用户。不同类型的用户可以利用传统编码和以模型驱动的开发相结合来进行协作、共同努力。2 I3 y; u3 l1 l2 L$ e
技术定义可以映射到下一节中所描述的三种不同场景。! Q' x6 Q8 V* N' ?: P

4 P& j* c" \# \注意:3 F' @' M) a9 U- N5 `
这些定义可以在组件的基础上使用,也就是说,应用程序中有一个组件以模型为中心,而另一个组件可能以代码为中心。! {% Z& u* t$ y+ j+ r: j
以代码为中心和以模型驱动的开发相结合的场景
2 h( @* s9 a) a您可以使用几种方法来组合传统的代码重用与建模。选择范围可以在较高的层面上描述为以下四种场景:
! ^! j& C0 t3 T/ ?8 V
  • 可视化外部代码(仅可视化)是一个以代码为中心的流程。外部代码对于可视化建模工具而言仍然是外部的。您可以在建模工具中引用外部代码来使用和测试它。
  • 利用更新的文档持续编码 是一个以代码为中心的流程,支持将更新发送给模型。您可以在一个模型中可视化代码,但永远不能改变模型。
  • 以代码为中心的开发,在模型中进行的修改被生成代码。此开发是以代码为主。
  • 使用模型驱动的开发实现代码现代化,该开发以模型为主。确定要重用外部代码的一部分,并将它们直接带入模型。+ N; n6 z( h* r( f
可视化外部代码
7 j# H- X4 X9 A! \+ ^: r: G, A, w1 E
& p8 ?  [2 c6 p+ U5 b可视化意味着您将使用图表帮助您了解代码的设计、结构和对象(比如类和文件)之间的关系。作为一个用户,您还能够根据模型元素创建新图,在图中添加注释,并将模型元素与需求相联系。来自代码的元素描述被保存在模型中,并可以通过在模型上制作报告,然后将该描述生成一份报告。在模型中还可以更轻松地完成变更,比如添加可以在图上绘制的元素,在图上复制元素,继承元素等等。
$ O8 \( u3 H9 s$ e7 N- S6 g% @$ M1 ?; _, ]' ~7 }  R
利用代码可视化,代码的更新可以在建模工具外部的代码中完成。执行外部代码的可视化,向模型展示代码中的关系。例如,您可能希望引用外部 C 库,并在图中显示该引用。可以采用这种方式可视化和记录库与模型其他部分的关系。可以在模型内部完成库的以模型驱动的测试。利用模型驱动的开发,您不仅可视化自己的代码,还可以执行您的模型,从而验证和测试该模型。
+ l: l: q6 \0 r( d& A2 D. X, ~! ^& z3 J( W
利用更新的文档持续编码
$ G$ N% u4 v2 V- `
& V- z1 G! v' b7 c2 `在第二个场景中,由于对外部代码进行了更改,所以可以执行往返操作,将代码变更发送到模型中。该操作将从外部代码带入修改后的代码来更新文档。如果您选择可视化和更新代码的选项,那么您可以继续在模型或在外部代码中开发代码,并保持两者同步。; o) \0 Y( l/ e& d, o

$ ?7 ~1 S2 c, y* [2 Z4 x以代码为中心的开发
. ^/ b/ q1 H9 E. x% g
; J- O* e4 Q% T如之前在场景 3 中所述,您可以通过在 Rational Rhapsody 中生成代码并用变更来更新外部代码,从而利用模型驱动的开发来现代化代码。代码生成可以在建模工具中完成,同时在原始源文件中保留现有代码的指引。在模型中运行代码生成的选项,有助于将变更从模型带回代码中。可以使用模型动画来显示代码的行为。在这种场景中,开发是以代码为主的。
4 U) @. \% M) ^' m
  ~) _4 m: Y, g8 a7 e; J* x9 r. v使用模型驱动的开发实现代码的现代化 ( \3 R. ~9 G+ ^( q! H
# ^& p' O( c& y# d
您可以选择在模型中维护代码。这是场景 4 的基础。您希望如场景 1-3 中那样完成可视化代码,还是直接在模型中维护它以执行模型驱动的开发,决定这个选择的关键条件是,您是否希望在模型中严格地生成代码。如果您在模型中维护代码,则可以更高效地执行更多设计变更和增强。此开发是以模型为主的。% S8 F. O# `2 F& J3 `
Rational Rhapsody 现在显示了一个简单的示例,展示了 UML 如何实现现有代码的重用。该示例讲述的是一个用户如何基于现有的硬件建立一个新的收银机。第一个图被称为 Package 图。它提供了一个系统包的高层次视图。这些包是 CashRegister、Hardware 包,以及通过 Interfaces 包实现的两者之间的链接。Interfaces 包使得 Hardware 易于重用,并且支持按需要将现有硬件交换为新硬件。  q/ @# x. s# V" k9 k

, z7 F* d2 ?" B* U3 {图 1. 包图
$ _6 @0 X) @5 P2 Q! P! B ! t1 ]% w& t% K) O
下面的类图显示继承自接口 IBarcodeReader 的 Cash Register。这使 CashRegister 类可以实现接口,并从 BarcodeReader 类接收通信,那么 BarcodeReader 类需要来自外部硬件包。BarcodeReader 不需要在图中显示,尽管图中显示了 Barcode Reader 接口(图 2),因为 CashRegister 只需实现可以获得所需行为的接口即可。
; f$ q4 d5 \$ c  r: p- ]2 \4 s
6 m4 b: r; `8 I9 ]图 2. 类图
8 I( p8 W5 T- Q* g- O 3 l$ i& c* s3 k8 D' i- m# D  Z
图 3 中的类图显示的 Tester 类执行包括 来自外部源的 C 源文件。外部源被可视化,以显示来自 point_of_sale 文件的操作和变量,所以 Tester 类可以决定自己能够调用什么。
. P- r3 j+ N8 P- L6 k4 q
' J6 N$ e0 j& U: C图 3. Tester 类包括一个来自外部源的 C 源文件
7 a1 Y! w2 j+ v4 G' t5 Z& k" X9 i ( f  f. j7 n" D) i$ ]. ?+ J' ^
在图 4 中,动画序列图显示的 CashRegister 类,扫描产品上的条形码,并将产品添加到顾客的账单中。
1 W/ z# [, r7 t* O1 \
* ?* x+ y, J3 h0 }* V2 S5 W* [图 4. 动画序列图6 A! W( ^! d) [: H1 N2 b
7 v: M9 N9 J  W0 e) j2 t3 L
动画可使您能够在主机或目标上执行应用程序,然后使用 Rational Rhapsody 在设计中查看结果。这是一个重要的工具,可以查看代码的行为并调试代码,当您在重用代码时,这些工作非常重要。查看静态代码只会向您显示通过它的潜在路径。图 4 中所示的序列图显示了当应用程序真正响应外部刺激时通过它的路径。因此,您会看到在应用程序的真正生命周期中执行了哪些路径。因此,动画模型是一种测试和验证您的可重用代码行为的方法。  k, f3 g  A/ B3 h


: H. N& V/ Z, t5 R$ e重用和产品线工程 (PLE)
$ J0 x; |$ u) D. v$ r+ i9 \9 @, L9 t, [  G: ?
重用的制胜法宝是所谓的产品线工程 (PLE)。PLE 是一种实践,可以识别应用程序中因产品而异的特性,并将这些特性映射到每个产品的特定变体,那么,在最后,您会有一组支持多种产品的代码。因为重用的主要目标是在未来的产品中实现重用,所以这是一个制胜法宝,也是 PLE 的目标。3 b1 K/ v7 L+ A  g5 Y
构建多个产品中的其他选项是克隆并拥有 产品,或者使用 ifdefs
. P* y) q/ t7 U
  • 克隆并拥有产品带来了一堆问题,例如,当您在一个产品中发现一个 bug 时,该 bug 是否也存在于其他产品中?当您想将某个特性传播到所有产品时,会发生什么呢?寻找克隆中的变更会是一个噩梦。
  • Ifdefs 使代码变得不可读,并且当尝试在某个特定产品上工作时,代码会变得非常难以导航。
      p. b# ~5 r* K/ {' g; R5 z8 _
建模通过在代码上添加一个抽象层次,这有助于解决此难题。您可以在映射到特性时识别特定的模型元素(类、函数或其他任何元素),然后为产品特定的差异添加标签。因为它是图形,所以标签可以是链接,您可以根据需要调查这些链接。此外,当您从模型生成代码时,它只使用产品特定的标签,让您可以获得每个产品的定制代码。然后在模型中进行相应修改,拥有该特性的每个产品都会获得这些变更。不需要从产品到产品地传播变更。
& W/ W' v/ c1 E- [" l
) P" N. c7 l+ k! R4 F
结束语
: \! N% k. w* `  e- V6 l总之,因为时间线很短,所以重用对于满足最后期限非常重要。关键是如何在您的操作中构建有效的重用。首先,请确保您了解自己的架构,然后深入了解要重用的组件。建模在这个过程中非常有用,因为它可以帮助您对代码进行分析,并决定重用哪些内容。当您了解整体架构之后,将您的产品构建到一个完整的 PLE 工作流中就会变得更易于完成和维护。
4 {- R% D* L4 J7 V2 `/ ^5 }8 F
/ [9 b! O/ ]# i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
 楼主| 发表于 2012-5-15 11:31:35 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

SCMLife推荐上一条 /4 下一条

QQ|小黑屋|手机版|无图版|SCMLife.com ( 京ICP备06056490号-1 )

GMT+8, 2019-4-24 11:04 , Processed in 0.064525 second(s), 8 queries , Gzip On, MemCache On.

Powered by SCMLife X3.4 Licensed

© 2001-2017 JoyShare.

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