实施UML九项注意
UML的符號比較多(可能太多)而且足夠靈活能適應大范圍項目的需求。為了成功使用UML,在使用的過程中必須流程化。不同的項目需要不同的內容。項目中使用UML符號的哪些具體元素取決于項目的本質(使用關系數據庫客戶端/服務器端或實時嵌入式)及要使用的開發語言。使用JAVA或Smalltalk時一些詳細的C++設計組件將不會被使用;如果使用VB,你可能想避免使用更多的泛化和繼承。有時,純粹的建模組件可能太龐大了,尤其對那些剛開始接觸面向對象分析和設計的學生來說。但是,好消息是幾乎任何事情都可以使用UML來建模來實現。有很多建模組件可供使用。
You Still Need a Process過程仍然需要
UML本身僅僅是一種符號,為了創建有效的模型,仍然需要一個建模過程。使用UML有很多種建模方法;建模語言本身并不描述過程。在UML產生的幾年前,我們一直把作了微小變化的Objectory過程(從Ivar Jacobson的 《面向對象軟件工程:一個用例驅動方法》而來,Addison-Wesley, 1992)作為Booch/Rumbaugh/Jacobson的綜合來授課,并取得了成功。我們的方法將重點放在了區分更高層次的靜態模型(域模型),同時也產生用例。然后我們精煉出靜態模型,在開發用例和動態模型時反復精練。
或者你更傾向于使用Objectory,對象模型方法,我們的ICONIX統一對象模型過程,或其他一些方法。在從事建模工作之前,理解UML不是一個過程是重要的。讓項目組處于同一個開發階段尤其重要。讓項目組對UML有統一的理解使建模成功的保證。UML的規模(文檔符號的龐大相對于過程而言)很容易陷入“分析麻痹”。關注項目組通過UML符號對過程的統一理解,能讓建模更容易。
Legacy Methods Are Important 過去的方法依然重要
我的大部分學生會問我理解Booch, Jacobson, and Rumbaugh過去的方法是否仍然很重要。我的答案是非常重要。就像知道電流設計并沒有排除知道電路理論一樣,雖然UML符號而不排除理解對象建模理論的必要性。自從UML代表了Jacobson, Booch, and Rumbaugh三人方法的綜合,但早期的方法是信息的來源。
Keep It Simple保持簡單
讓一個項目組有效的使用UML是有難度的。項目組成員對于面向對象分析和設計以及UML的理解層次各自不同。開始之前統一培訓是不錯的方法,培訓需要認真考慮項目組每個成員的背景及項目的特殊要求。最重要的決定在于課程表的明智選擇和指導老師在工作期間的調整。
在學習UML中需要記住的一點是我們并不需要使用每一個存在的組件。讓過程盡量簡單化。流程化一個項目的文檔和建模方法對項目的進行有非凡的作用。
用UML建模和有時和座在一大堆事物面前很相似,開始吃之前就有不能吃完盤子里面的所有食物的想法可能毀了你的食欲。同樣的現象可能發生在UML建模過程中。用完全詳細的動態模型描述系統的每一個用例,而不得不創建一系列完整的時序圖、協作圖、狀態圖、部署圖,用例和類圖的想法可能會讓一個團隊完全脫離面向對象分析和設計。
在一個給定的建模方法中決定使用哪一個組件簡單同樣是要考慮的。舉例來說,在一個用例圖上同時使用USES 和EXTENDS真的有必要嗎?或者我們只需要使用USES?我的經驗是流程化的東西越多,建模成功的可能性越大。
Write the User Manual Before You Design the Classes設計類之前寫使用手冊
寫程序的一條老的規矩是在寫代碼之前寫使用手冊。在我學習的時候我認為這是一條好的建議,并且到今天為止我仍然認為是好的建議。在面向過程的年代和面向對象方法的早期,這條規矩很少被遵從。在用例驅動建模方法中,Jacobson把這個規律編寫成一系列的步驟,通過這些步驟可以為對象服務并且能用UML描述。每一個步驟建立在上一個步驟的基礎之上,形成一個可以跟蹤的方法,直道最后,管理能加強這個方法把它作為一個設計范例并且確認在分析和設計的過程中能被遵守。
基礎層次的人理解Objectory和用例驅動對象建模的本質的簡單方法是:在設計類之前寫使用手冊。大腦里一直有這個想法將會幫助你在UML的迷宮里穿越靜態和動態的建模符號。每一個用例代表著用戶手冊的一部分,并且應該按著“用例分析的目的是產生對象模型”的方式寫。
Organize Use Cases into Packages用例打包
一旦你準備為你的系統的每一個用例書寫使用手冊的時候,你將很快會意識到需要更高層次的把用例組裝起來。UML允許你把用例打包。這些可以用文件標簽代表。每一個包至少應該包括一個用例圖,這個圖可以作為一個上下文圖,它可能把設計階段每個用例的動態視圖和用例描述聯系起來。有一些項目從高層次的包分割開始。這些分割并不總是代表最終的分割,有時是很好的開始起點。
Use the Objectory Stereotypes使用Objectory模板
整個設計過程從用例中分離出來,表明注重描述它們是“正確“的方法。同時在需求分析和業務過程建模中用例作為一種備選方案正越來越受到歡迎。不同形式的用例建模有一些不同的向導,我遇到的大部分項目仍把用例作為得到對象模型的方法。
Jacobson的早期的OOSE/Objectory包括這樣一個我們稱之為健壯性分析的階段。在健壯性分析中,用例描述被解釋為粗略地分割一系列協作對象。在分析的過程中,Jacobson提出將對象進行分類,把它們分為接口對象,控制對象,和實體對象。
這個小又快的建模步驟產生令人驚訝的收益。它幫助人們寫出正確的用例,較早地確認客戶端/服務器端和MVC設計信息,很可能最重要的是快速的瀏覽所有用例能確認可重用的對象。同時也填補了需求分析和詳細設計之間的空白。
不幸的是,由于某些原因,健壯性分析的一些符號(三個容易畫的符號),在轉變的過程中只有部分保留在UML中。符號仍然存在,但被分離到一個稱為對象過程擴展的文檔當中,并且工具支持也缺少。我把健壯性分析作為一個整體部分描述用例(圖變成了文本的完全檢查)時,發現學生已經很快適應了這個對象。
Important Questions重要的問題
你可以把整個領域的面向對象的分析和設計減少到兩個簡單的問題: 首先,系統中的對象是什么?其次,需要的系統行為如何在對象中分配?
已經明確要建立的正確的對象集,并且你已經為一個系統分配了合適的類集,你的項目將會進展順利。最難的工作恐怕是我們聽起來覺得很很順耳的“分配行為是不錯的工作”這句話,這也是有經驗的面向對象分析者的生存之本。
Drive the Static Model from the Dynamic Models從動態模型中分離出靜態模型
無論你打算在哪個過程使用UML,從動態模型中分離出靜態模型(類圖)是不錯的實踐方式,從較高層次的用例圖開始,尤其是使用UML 時序圖在類圖中分配行為。 這個理論,是從Jacobson的OOSE/Objectory 過程中得來的,是1993年的時候一個關系好的Objectory咨詢者解釋給我聽的。在過去的四年中我繼續把它作為一種設計形式在教,它內在的智慧和廣泛的應用讓我已經越來越信服它了。
這個觀點的本質在于: 通過遵從對象模型方法我們可以開始并且得到一個系統的粗略的對象集,這同通過問題描述來尋找名詞得到“現實世界”或“問題領域”很相似。有時,我們可以做出聰明的猜測,一個特殊的類可能會是一個特殊操作的容器。但是,通常在面向對象的設計過程中,我們發現缺少用例開發來考慮靜態模型是幼稚的。
以我的經驗,面向對象分析與設計的實質在于真正好的方法解決類中分配行為的問題,把用例在更詳細的(信息傳遞/方法)階段。正規的或者非正規的,我所遇到的年長的的面向對象分析者大部分是這樣設計的。當方法不正式時(不可見),設計者對怎樣從一系列給定的領域對象和用例中得到一個明確的方法充滿疑惑。通常,在使用一個系列像“多態、封裝接口“這樣的行話時這樣的疑慮又會產生。這樣能限制項目組成員完成有用的設計評估,讓水平高的程序員更靈活地根據情況完成任務。
然而,在我看來,在UML(參看“UML模型如何匹配“,關注UML, SR4 頁,時序圖例子)中使用時序圖設計方法才能更好的完成。時序圖通過左側的早先的(需求階段,用戶手冊視圖)父用例文本描述,圖中間的實際的詳細的動態行為(每一個方法和觸發事件)描述來實現的。在一頁紙上描述看出詳細設計和需求階段用例描述需要快速的瀏覽需求,可以證明至少你的用例設計符合需求。簡單的重復系統中所有用例,將會得到一個可跟蹤的設計。
畫時序圖的過程中,在設計中要確認具體的操作并把它分給具體的對象。雖然畫動態(時序)圖實際上也是在創建靜態類模型。時序圖是教我們如何從抽象的世界中找到對象模型的。
Defer Assigning Operations to Classes操作遲些分配給類
在項目分析階段不要過多的去關注將操作放進哪個類中。除了大部分顯而易見的情況外(有時連這些也會出錯),很可能規劃錯誤。經驗告訴我,做這些行為分配決定的時候最好仔細,隨著動態模型的開發一次一個。
要把這種分離一直記住(分析:什么是對象?設計:行為如何分配?)會幫助項目組定義分析和設計的界限。我們最先的統一對象建模過程方法在最初的分析階段使用了對象建模方法符號,在設計階段使用了Booch符號。在分析的過程中對象建模方法被使用,更詳細的設計階段的模型使用Booch方法。在UML中,這些符號被融合成單一的,對象模型方法。隨著分析和設計符號的模糊不清,項目組經常要分清分析和設計的界限在哪兒會很困難。
即使我在教跌代和遞增過程, 在某些邏輯點上,需求和設計評估是必須的。如果我在評估一個分析模型,我并不會很在意類的操作(在大多數場合,如果沒有我會很高興)。我在尋找一個好的域類集和可以理解的用例模型。而在設計評估時,所有的操作都需要考慮在內,在時序圖中需求和設計必須可以跟蹤。設計者必須能解釋清楚為什么他會把一些操作放在特定的類中。
Simply Successful簡單既成功
在項目中使用UML,需要時刻記住的是保持簡單,先寫用戶手冊(一次一個用例),同時讓項目組對過程有統一的認識。記住,UML是一種符號,而不是過程。我所見到的最成功的項目都采用用例驅動,迭代,遞增方法的。如果能把過程細化并且讓項目組掌握技巧,UML項目已經離成功不遠了。
?
英文原文:
In the last quarter of 1997, I taught object-oriented analysis and design with UML to a wide range of developers working on various projects. The projects spanned application domains including retail shelf space management, pharmaceutical clinical trials, cellular telephony, and more. Implementation languages included Visual Basic, C++, Java, DB2, and others. This article discusses several aspects of how well the UML notation, along with my company's use case-driven Unified Object Modeling process (also based on the methods of Booch, Jacobson, and Rumbaugh), met the demands of a diverse set of projects. It provides practical guidance for tailoring your use of UML for various projects.
The UML notation is big (maybe too big) and is flexible enough to accommodate the needs of a very wide range of projects. To succeed with UML, you must streamline how you use it. Different projects will need different pieces. Which specific elements of the UML notation you need for your project will depend on its nature (client/server with a mainframe RDBMS vs. real-time embedded, for example) and on the implementation language you will be using. Some detailed C++ design constructs are not needed if you're building in Java or Smalltalk, and you may want to avoid too much use of generalization or inheritance if you're building in Visual Basic. Sometimes, the sheer volume of modeling constructs can be overwhelming, especially to those students who are new to object-oriented analysis and design. However, the good news is that you can model almost anything using UML. There are plenty of modeling constructs to go around.
You Still Need a Process
UML itself is only a notation; to build effective models, you still need a modeling process. There are many modeling approaches you can use with UML; the modeling language itself does not prescribe the process. My company has been successful teaching a slightly modified version of the Objectory process (derived from Ivar Jacobson's Object-Oriented Software Engineering: A Use Case Driven Approach, Addison-Wesley, 1992) that we developed as a synthesis of Booch/Rumbaugh/Jacobson several years prior to the advent of UML. Our approach places slightly more emphasis on identifying high-level static models (domain models) up front, in parallel with use cases. We then refine the static model iteratively and incrementally refine as we explore the use cases and dynamic models.
Whether you prefer using Objectory, Object Modeling Technique, our ICONIX Unified Object Modeling process, or some other approach, it's important to understand that UML is not a process, and that it is critically important to get your project team on the same page process-wise before undertaking a modeling effort. Once again, the size and bulk of UML (and the overwhelming weight of documentation on notation as opposed to process) can make it easy to slip into "analysis paralysis." Focusing the team on an understandable process that is supported by the UML notation can generally get the modeling effort underway.
Legacy Methods Are Important
Many of my students ask whether developing an understanding of Booch, Jacobson, and Rumbaugh's legacy methods is still important. My answer is an emphatic yes. Just as knowing the symbols used for electronic circuit design doesn't eliminate the need to know circuit theory, understanding the notational aspects of UML doesn't eliminate the need to understand object modeling theory. Since UML represents the synthesis of the works of Jacobson, Booch, and Rumbaugh, the original legacy methods are a rich source of this information.
Keep It Simple
Getting a project team to make effective use of UML is tricky. Team members will have varied experience with object-oriented analysis and design and UML. A training workshop is a good way to begin. The workshop needs to be tailored to the specific needs of each project, taking the backgrounds of the various team members into careful consideration. The most critical tailoring decisions will ultimately involve judicious choices of what gets left out of the course agenda, as well as the instructor's ability to adjust on-the-fly during the workshop.
One of the most important things to remember when learning UML is that you don't need to use every construct just because it's there. Keep the process as simple as possible. Streamlining a project's documentation set and modeling approach does wonders for generating forward momentum.
Modeling with UML is similar to sitting down to an huge plate of food-sometimes, the thought that you can't possibly eat everything on the plate just kills your appetite before you get started. A similar phenomenon can occur with UML modeling. The thought of having to produce a complete set of sequence, collaboration, state, deployment, use case, and class diagrams that comprehensively covers each and every use case of the system with a fully detailed dynamic model can intimidate a team right out of object-oriented analysis and design.
The same thought process holds true for determining which constructs are employed within a given modeling technique. For example: is it really necessary to employ both USES and EXTENDS on a use case diagram, or can we live with just USES? My experience has been that the more streamlining that gets done, the better the chances of the modeling effort being carried through.
Write the User Manual Before You Design the Classes
One of the old saws of programming is to write the user manual before you write the code. This was good advice when I learned it, and it's still good advice today. In the days of structured methods, and in the early days of object-oriented methods, it was seldom followed. In his use case-driven modeling approach, Jacobson codified this maxim into a series of steps that work for object orientation and can be described using UML. Each step builds upon the previous step in a traceable manner, so that ultimately, management can enforce this approach as a design paradigm and verify that it has been followed at each step in the analysis and design process.
The key to understanding the essence of Objectory and use case-driven object modeling at the fundamental level is simple: write the user manual before you design the classes. Keeping this idea in the front of your mind will help guide you as you travel through the maze of UML static and dynamic model notations. Each use case represents a portion of the user manual, and should be written that way if the goal of your use case analysis is to produce an object model.
Organize Use Cases into Packages
As you begin to write the user manual for your system one use case at a time, you will immediately run into the need for a high-level organization of use cases. UML lets you organize your use cases into packages. These are represented as tabbed-folder icons. Each package should consist of at least one use case diagram, which will serve as a context diagram under which you can link all the use case descriptions along with the design-level dynamic model views for each use case. Some projects start with a top-level breakdown of one package per top-level menu. While this breakdown does not always represent the final breakdown, it's sometimes a helpful starting place.
Use the Objectory Stereotypes
Since we're driving the entire design process from the use cases, it makes sense to focus strongly on describing them in the "right" way. While it's becoming increasingly popular to employ use cases as an alternative to requirements specifications and for business process modeling, and while these styles of use case modeling have somewhat different guidelines, most projects I've run across still view use cases as a way to get to an object model.
Jacobson's original OOSE/Objectory process included a phase called Robustness Analysis, wherein use case descriptions were analyzed to determine a rough first cut at a collaborating set of objects. While doing this analysis, Jacobson proposed classifying the objects identified into Interface Objects, Control Objects, and Entity Objects.
This small, quick modeling step produces an amazing set of benefits. It helps people write use cases correctly, identify client/server and model-view-controller design information early, and perhaps most important, identify reusable objects by enabling a quick breadth-first pass across all the use cases. It also fills the void between requirements analysis and detailed design.
Unfortunately, for some reason, the notation for Robustness Analysis (three easy-to-draw symbols), only partially survived the transition into UML. The notation still exists, but has been banished to a separate document called the Objectory Process Specific Extensions, and tool support is often lacking. I teach Robustness Analysis as an integral part of describing use cases (the diagram becomes a sanity check for the text), and have found that students readily adapt to this object shorthand.
Important Questions
You can reduce the entire domain of object-oriented analysis and design to two simple questions: First, what are the objects in the system? Second, how is the required system behavior distributed among these objects?
While this is somewhat of an over-simplification of a subject that has been the topic of thousands of pages of methodology textbooks, it fundamentally isn't too far off the mark. If you've identified the right set of objects to build, and if you've done a good job of allocating the desired system behavior to the most appropriate set of classes, your project should be in good shape. The tricky part is really the innocent-sounding phrase "done a good job of allocating behavior"; this is where experienced object-oriented designers earn their living.
Drive the Static Model from the Dynamic Models
No matter which process you decide to use with UML, it's good practice to drive the design of the static model (class diagrams) from the dynamic models, starting from use cases at the high level, and particularly leveraging the UML Sequence Diagram to allocate behavior among your classes. This philosophy, which has its roots in Jacobson's OOSE/Objectory process, was first explained to me around 1993 by a friendly Objectory consultant. As I've continued to teach it as a design style over the last four years, I've grown increasingly convinced of its wisdom and (thus far) universal applicability.
The essence of the idea is this: we can start out and get a rough approximation of the core set of objects in a system by following an Object Modeling Technique-like strategy of identifying "real-world" or "problem domain" objects using techniques such as looking for nouns in the problem statement. Sometimes, we can make intelligent guesses as to when a particular class might be an appropriate container for a specific operation; however, often in the process of object-oriented design, we find that the original guesses that we made when considering the static models in the absence of exploring the use cases were naive.
Based on my experience, the reality of object-oriented analysis and design is that the only really good way to approach the (difficult) problem of allocating behavior among a set of classes is to explore the use case at a detailed (message passing/method invocation) level. Whether formally or informally, most senior object-oriented designers I've met arrive at their designs this way. When the approach is informal (not visible), a cloud of mystery sometimes surrounds how a designer arrived at a specific solution from a given set of domain objects and use cases. Often, this cloud of mystery is deepened by oblique explanations using a litany of jargon such as "multiple polymorphic encapsulated interfaces." This tends to limit the amount of useful design review that can be accomplished by team members and leaves the intrepid programmer free to implement as he or she sees fit.
In my experience, however, this design approach is best accomplished using a sequence diagram in UML (see "How the UML Models Fit Together" Focus on UML, page SR4, for an example of a sequence diagram), with the original (requirement-level, user manual view) text of the parent use case shown along the left margin, and the actual detailed dynamic behavior, showing each method invocation and the message that invokes it, in the body of the diagram. Showing the detailed design and the requirement-level textual use case description on the same page provides a quick "eyeball" requirements trace, which verifies that, for at least this use case, your design matches the requirements. Simply repeat this for all the use cases of your system, and you have a traceable design.
While drawing the sequence diagrams, you'll identify specific operations and assign them to specific objects within your design. You're actually building the static class model, even though you're drawing dynamic model (sequence) diagrams at the same time. The sequence diagram is the vehicle that teaches us how much we don't know when we explore the object model in the abstract.
Defer Assigning Operations to Classes
Don't worry too much about specifying which operations go in which classes during the analysis phase of your project. You'll probably get the mapping wrong anyway, except in the most obvious cases (and sometimes even then). Experience teaches that these behavior allocation decisions are best made very carefully, one at a time, as the dynamic models are explored.
Keeping this separation in mind (Analysis: what are the objects? Design: how is the behavior allocated?) helps project teams define the boundary between analysis and design. Our original Unified Object Modeling process approach used the Object Modeling Technique notation at the analysis level, and the Booch notation for design. The Object Modeling Technique was applied during analysis using the Booch method for detailed, design-level models. With UML, these notations have been merged into a single, Object Modeling Technique-flavored class diagram. As the line between analysis and design notations has blurred, project teams often experience difficulty in understanding where the analysis and design boundary is.
Even though I teach an iterative and incremental process, a requirements review and a design review must be included at some logical point. If I'm reviewing an analysis model, I'm not particularly concerned whether or not the classes have operations showing (in most cases, I'm just as happy if they don't). I'm looking for a good set of domain classes and a comprehensive use case model. For a design review, however, all operations should be accounted for, and there must be visual traceability between the requirements and the design on the sequence diagrams. The designer must also be able to defend his or her decisions as to why any given operation was placed in a particular class.
Simply Successful
The most important things to keep in mind as you apply UML to your project are to keep it simple, write the user manual first (one use case at a time), and get your project team on the same page regarding process. Remember, UML specifies a notation, not a process. The most successful projects I've seen are adopting use case-driven, iterative, and incremental approaches. If you tailor your process to the individual parameters of your project and to the skill set of your team, your UML project will be marked for success.
轉載于:https://www.cnblogs.com/Jackey_Chen/archive/2008/11/02/1324679.html
總結
- 上一篇: [ASP.NET 控件实作 Day28]
- 下一篇: Erlang China 大会 - CN