面向對象軟件構造(第2版)-第4章 複用性方法Approaches to reusability (中)

4.4 NON-TECHNICAL OBSTACLES

4.4 非技術障礙

 

Why then is reuse not more common?

爲什麼複用不能更普及?

 

Most of the serious impediments to reuse are technical removing them will be the subject of the following sections of this chapter (and of much of the rest of this book). But of course there are also some organizational, economical and political obstacles.

對複用而言,大部份嚴重的障礙是技術上的;解決這些障礙是本章下面各段的主題(同時也是本書其它部分的主題).但是當然也有一些是組織的,經濟的和政治上的障礙.

 

The NIH syndrome

NIH綜合症

 

An often quoted psychological obstacle to reuse is the famous Not Invented Here (“NIH”) syndrome. Software developers, it is said, are individualists, who prefer to redo everything by themselves rather than rely on someone else’s work.

對複用來說,一個時常被提起的心理障礙是出名的非自創("NIH")綜合症.據說,軟件開發者都是個人主義者,他們寧願親自重做每件事而不願藉助於他人的工作.

 

This contention (commonly heard in managerial circles) is not borne out by experience. Software developers do not like useless work more than anyone else. When a good, well-publicized and easily accessible reusable solution is available, it gets reused.

這個爭論(在管理圈中經常能聽到)並沒有被實際驗證過.軟件開發者比其他任何人更不喜歡無用的工作.當優秀的,易於宣傳的和容易理解的可複用解決方可以被使用時,它就會被複用.

 

Consider the typical case of lexical and syntactic analysis. Using parser generators such as the Lex-Yacc combination, it is much easier to produce a parser for a command language or a simple programming language than if you must program it from scratch. The result is clear: where such tools are available, competent software developers routinely reuse them. Writing your own tailor-made parser still makes sense in some cases, since the tools mentioned have their limitations. But the developers’ reaction is usually to go by default to one of these tools it is when you want to use a solution not based on the reusable mechanisms that you have to argue for it. This may in fact cause a new syndrome, the reverse of NIH, which we may call HIN (Habit Inhibiting Novelty): a useful but limited reusable solution, so entrenched that it narrows the developers’ outlook and stifles innovation, becomes counter-productive. Try to convince some Unix developers to use a parser generator other than Yacc, and you may encounter HIN first-hand.

考慮一下詞彙語法分析的典型情況.使用如Lex-Yacc組合這樣的解析生成器,對一個命令語言或一個簡單的程序語言產生一個解析器(parser),比您必須從頭開發它更加容易.結果很清楚:當能利用這樣的工具時,能幹的軟件開發者就會照例複用它們.由於這些所提及的工具有其侷限性,寫您自己度身訂做的解析器在一些情況下仍然是有道理的.但是開發者通常是這些工具沒有替代產品纔會去做;而且這是當您使用了一個並不基於複用機制的解決方案的時候,您也不得不同意. 事實上這可能引起一種新的併發症,和NIH相反,我們可以稱之爲HIN(Habit Inhibiting Novelty墨守成規):一種有用但是有限的複用解決方案,如此難以改變導致了開發者的視野狹窄並扼殺革新,成爲反生產力.試着讓一些Unix開發者除了Yacc之外去使用另一個解析器,您也許就會直徑遇到HIN.

[注] LexYaccUnix/Linux上的詞法語法分析代碼生成工具,可以用來編寫編譯程序和解釋程序,同時也可用於其它需要對結構化輸入生成解析工具的場合。

 

Something which may externally look like NIH does exist, but often it is simply the developers’ understandably cautious reaction to new and unknown components. They may fear that bugs or other problems will be more difficult to correct than with a solution over which they have full control. Often such fears are justified by unfortunate earlier attempts at reusing components, especially if they followed from a management mandate to reuse at all costs, not accompanied by proper quality checks. If the new components are of good quality and provide a real service, fears will soon disappear.

可能從外表看起來NIH好象並不存在,但是通常它只是開發者對新的和未知的組件的一種可理解的謹慎的反應.相比一個他們能完全控制的解決方案而言,他們可能害怕修改錯誤或其它的問題會更加困難.通常這樣的擔心在先前嘗試複用組件時被不幸地證明了,尤其是如果他們聽從一個管理命令不惜任何代價的去複用, 同時卻不做正確的品質檢查.但如果新組件是有良好的品質並且提供確實的服務,那麼恐懼就會很快地消失掉.

 

What this means for the producer of reusable components is that quality is even more important here than for more ordinary forms of software. If the cost of a non-reusable, one-of-a-kind solution is N, the cost R of a solution relying on reusable components is never zero: there is a learning cost, at least the first time developers may have to bend their software to accommodate the components and they must write some interfacing software, however small, to call them. So even if the reusability savings

                          R

r =    ------

           N

and other benefits of reuse are potentially great, you must also convince the candidate reusers that the reusable solution’s quality is good enough to justify relinquishing control.

在這裏,對可複用組件的生產者意謂着,品質比一般的軟件形式更爲重要.如果一個不可複用的,與衆不同的解決方案費用爲N,使用可複用組件的解決方案的費用爲R且不爲零:這裏有一個學習的成本,至少第一次會有開發者可能不得不修改他們的軟件以適應組件並且他們必須寫一些小型的接口軟件去調用組件.因此即使複用性節省了

                          R

r =    ------

           N

其它複用的利益可能很大,那麼您也一定要使潛在的複用者相信,可複用的解決方案的品質已經足夠好來證明放鬆控制的正確性.

 

This explains why it is a mistake to target a company’s reusability policy to the potential reusers (the consumers, that is to say the application developers). Instead you should put the heat on the producers, including people in charge of acquiring external components, to ensure the quality and usefulness of their offering. Preaching reuse to application developers, as some companies do by way of reusability policy, is futile: because application developers are ultimately judged by how effectively they produce their applications, they should and will reuse not because you tell them to but because you have done a good enough job with the reusable components (developed or acquired) that it will be profitable for their applications to rely on these components.

這解釋了爲什麼把公司的複用性政策對準潛在的複用者(消費者,也就是應用程序開發者)是個錯誤.相反的,您應該把精力放在生產者身上以確定他們所提供的品質和有效性,這包括掌管獲取外部組件的人.對應用程序開發者鼓吹複用是沒有效果的,就如一些公司複用性政策所做的: 因爲他們編寫的應用程序的有效性纔對應用程序開發者作出最終判斷,他們應該並將會採取複用,不是因爲您告訴他們要用而是因爲您利用可複用的組件(自己開發的或從外面獲得的)完成了一個相當出色的工作,要是把他們的應用程序建立在這些組件之上會是有利可圖的.

 

The economics of procurement

採購經濟學

 

A potential obstacle to reuse comes from the procurement policy of many large corporations and government organizations, which tends to impede reusability efforts by focusing on short-term costs. US regulations, for example, make it hard for a government agency to pay a contractor for work that was not explicitly commissioned (normally as part of a Request For Proposals). Such rules come from a legitimate concern to protect taxpayers or shareholders, but can also discourage software builders from applying the crucial effort of generalization to transform good software into reusable components.

複用的一個潛在的障礙來自許多大的公司和政府機構的採購政策,因關注短期的費用而妨礙了複用性的成果.例如,美國法規使政府機關對沒被明確委任工作的承包商支付費用很困難(通常爲徵求建議書(Request For Proposals, RFP)的一部份).這樣的規則來自於對保護納稅人或股東的合法考慮,但是也阻止了軟件構建者應用至關重要的泛化(generalization)成果把好的軟件轉變成可複用的組件.

 

On closer examination this obstacle does not look so insurmountable. As the concern for reusability spreads, there is nothing to prevent the commissioning agency from including in the RFP itself the requirement that the solution must be general-purpose and reusable, and the description of how candidate solutions will be evaluated against these criteria. Then the software developers can devote the proper attention to the generalization task and be paid for it.

在最近的研究中,這個障礙看起來並不是不能克服的.當對複用性的關注更廣泛時,可以把佣金代理包括在RFP本身的需求和描述中,其中,需求包括解決方案一定要可以被廣泛使用和複用,描述包括候選方案將會如何評估這些標準.然後軟件開發者才能專心於泛化工作並得到相應的報酬.

 

Software companies and their strategies

軟件公司及其策略

 

Even if customers play their part in removing obstacles to reuse, a potential problem remains on the side of the contractors themselves. For a software company, there is a constant temptation to provide solutions that are purposely not reusable, for fear of not getting the next job from the customer — because if the result of the current job is too widely applicable the customer may not need a next job!

即使客戶在消除複用障礙方面起到一定作用,但一個潛在的問題還在承包商自己這邊.對於一家軟件公司來說,有一個經常性的誘惑是故意提供可複用的解決方案,惟恐從客戶那裏得不到下一個定單-因爲如果當前工作的結果可以廣泛地適用,那麼客戶可能不再需要下一個任務!

 

I once heard a remarkably candid expose of this view after giving a talk on reuse and object technology. A high-level executive from a major software house came to tell me that, although intellectually he admired the ideas, he would never implement them in his own company, because that would be killing the goose that laid the golden egg: more than 90% of the company’s business derived from renting manpower — providing analysts and programmers on assignment to customers — and the management’s objective was to bring the figure to 100%. With such an outlook on software engineering, one is not likely to greet with enthusiasm the prospect of widely available libraries of reusable components.

在一次關於複用和對象技術的演講之後,對於這個觀點我聽到了非常坦白的陳述.來自一個主要的軟件機構的高層主管告訴我,因爲那會殺害了生金蛋的鵝,所以雖然他贊同這個演講的觀念,但是他無法在自己的公司中實現:超過90%的公司生意得自於人力收益-根據客戶的任務提供分析師和程序員-並且管理層的目標是要帶來100%的預期.在這種軟件工程的觀點上,對廣泛有效的可複用組件庫的熱衷是不可能接受的.

 

The comment was notable for its frankness, but it triggered the obvious retort: if it is at all possible to build reusable components to replace some of the expensive services of a software house’s consultants, sooner or later someone will build them. At that time a company that has refused to take this route, and is left with nothing to sell but its consultants’ services, may feel sorry for having kept its head buried in the sand.

對它的坦白之評價是正面的,但是它也引起了明顯的反駁:如果全然可能去建立可複用組件代替軟件機構中顧問的昂貴服務,遲早人們會建立它們.到那時拒絕接受變化並且除了顧問服務以外什麼也沒有的公司,只能自己騙自己罷了.

 

It is hard not to think here of the many engineering disciplines that used to be heavily labor-intensive but became industrialized, that is to say tool-based — with painful economic consequences for companies and countries that did not understand early enough what was happening. To a certain extent, object technology is bringing a similar change to the software trade. The choice between people and tools need not, however, be an exclusive one. The engineering part of software engineering is not identical to that of mass-production industries humans will likely continue to play the key role in the software construction process. The aim of reuse is not to replace humans by tools (which is often, in spite of all claims, what has happened in other disciplines) but to change the distribution of what we entrust to humans and to tools. So the news is not all bad for a software company that has made its name through its consultants. In particular:

在這裏,很容易地聯想到過去一直是重勞力密集的許多工程產業都變成工業化了,更確切的說,工具化了-那些不能及早了解世間變化的公司和國家正在承受着棘手的經濟結果.一定程度上,對象技術正對軟件工業帶來了相似的變化.在人和工具之間的選擇並不是必須的,然而,卻是唯一的.軟件工程的工程部份並不等同於大規模生產的工業;人或許會在軟件構造過程中繼續扮演着關鍵的角色.複用的目標不僅僅是用工具(常常是這樣,儘管所有的要求都已經在其它的產業中發生過)取代人而且是改變我們委派給人和給工具之間的分配.對一家以顧問聞名的軟件公司來說,這樣的新聞並不總是壞事.尤其:

 

• In many cases developers using sophisticated reusable components may still benefit from the help of experts, who can advise them on how best to use the components. This leaves a meaningful role for software houses and their consultants.

在許多情況中,使用複雜的可複用組件的開發者還可以受益於專家的幫助,專家能夠建議如何最有效地使用組件.這爲軟件機構和他們的顧問留下了一個有意義的角色.

 

• As will be discussed below, reusability is inseparable from extendibility: good reusable components will still be open for adaptation to specific cases. Consultants from a company that developed a library are in an ideal position to perform such tuning for individual customers. So selling components and selling services are not necessarily exclusive activities a components business can serve as a basis for a service business.

在下面討論中,複用性和擴充性是聯繫在一起的:對於特定情況下地改編,良好的可複用組件仍始終保持着開放性.在一家開發庫的公司裏,顧問們是在一個理想的形式中爲個別的客戶完成這樣的調整.因此銷售組件和銷售服務並不是獨立的活動;組件生意可視爲服務生意的一種基礎.

 

• More generally, a good reusable library can play a strategic role in the policy of a successful software company, even if the company sells specific solutions rather than the library itself, and uses the library for internal purposes only. If the library covers the most common needs and provides an extendible basis for the more advanced cases, it can enable the company to gain a competitive edge in certain application areas by developing tailored solutions to customers’ needs, faster and at lower cost than competitors who cannot rely on such a ready-made basis.

更一般的,在一個成功的軟件公司的策略中,一個優秀的可複用庫能夠扮演一個站略上的角色,即便公司銷售的是特定的解決方案而並非庫本身,並且只在內部使用庫.如果庫包含了最普遍的需求而且提供了對更高階情形的擴充基礎,那麼通過開發適應客戶需求的解決方案,比不具備這樣的現成基礎的競爭者更快速並花費更低成本,這樣能夠使公司在確定的應用領域中獲得競爭優勢.

 

Accessing components

存取訪問

 

Another argument used to justify skepticism about reuse is the difficulty of the component management task: progress in the production of reusable software, it is said, would result in developers being swamped by so many components as to make their life worse than if the components were not available.

常用來對有關複用的懷疑進行驗證的另一個論據,是組件管理工作的困難性: 據說在可複用的軟件產品的發展中,導致開發者陷入困境的是有太多的組件使他們變得更糟,而不是組件無法使用.

 

Cast in a more positive style, this comment should be understood as a warning to developers of reusable software that the best reusable components in the world are useless if nobody knows they exist, or if it takes too much time and effort to obtain them. The practical success of reusability techniques requires the development of adequate databases of components, which interested developers may search by appropriate keywords to find out quickly whether some existing component satisfies a particular need. Network services must also be available, allowing electronic ordering and immediate downloading of selected components.

用一種較積極的態度來說,對於可複用的軟件開發者,應該把這個評論當成一個警告: 如果沒人知道它們的存在,或花了過多的時間和努力來獲取它們,那麼就算是世界上最好的可複用組件也根本無用.複用性技術的實際成功表明,這需要發展足夠的組件數據庫,讓感興趣的開發者可以通過適當的關鍵字快速查找以發現是否有存在的組件滿足特定的需求.網絡服務也應該可以利用,允許電子訂購併立即下載所挑選的組件.

 

These goals do raise technical and organizational problems. But we must keep things in proportion. Indexing, retrieving and delivering reusable components are engineering issues, to which we can apply known tools, in particular database technology there is no reason why software components should be more difficult to manage than customer records, flight information or library books.

這些目標引起了技術上和組織上的問題.但是我們必須保持一定的比例.索引,檢索和發佈可複用組件給那些我們能夠應用的已知工具,特別是數據庫技術方面,這是工程上的主題;這裏沒有說明爲什麼管理軟件組件應該比處理客戶記錄,航班信息或圖書館藏書更困難.

 

Reusability discussions used to delve forever into the grave question “how in the world are we going to make the components available to developers?”. After the advances in networking of the past few years, such debates no longer appear so momentous. With the World-Wide Web, in particular, have appeared powerful search tools (AltaVista, Yahoo¼) which have made it far easier to locate useful information, either on the Internet or on a company’s Intranet. Even more advanced solutions (produced, one may expect, with the help of object technology) will undoubtedly follow. All this makes it increasingly clear that the really hard part of progress in reusability lies not in organizing reusable components, but in building the wretched things in the first place.

在複用性的討論中,過去常常深入研究一個重大的問題是"我們究竟如何使開發者有效地使用組件?.在過去數年中網絡發展之後,這樣的討論已不再顯得那麼緊要了.特別是隨着WWW已經出現了強有力的搜索工具(AltaVista,Yahoo),這已經能非常容易的在英特網或公司內部網絡上找出有用的信息.甚至更先進的解決方案(可能期待的是藉助對象技術而產生)也將會毫無疑問地隨之而來.所有這些清楚地表明瞭,複用性過程中真正困難的部份不僅僅是在組織可複用組件方面,而且在開始就構建了糟糕的程序方面.

 

A note about component indexing

有關組件索引

 

On the matter of indexing and retrieving components, a question presents itself, at the borderline between technical and organizational issues: how should we associate indexing information, such as keywords, with software components?

在索引和檢索組件的內容上,一個問題出現在技術和組織的論點之間的分界線上: 我們如何應該關聯像關鍵字這樣的索引信息和軟件組件?

 

The Self-Documentation principle suggests that, as much as possible, information about a module — indexing information as well as other forms of module documentation — should appear in the module itself rather than externally. This leads to an important requirement on the notation that will be developed in part C of this book to write software components, called classes. Regardless of the exact form of these classes, we must equip ourselves with a mechanism to attach indexing information to each component.

自包含文檔原則建議了,儘可能多的有關一個模塊的信息-索引信息和其它形式的模塊文檔-應該出現在模塊本身中,而不是在外部.這導致了一個編寫軟件組件的一個重要需求,在符號上叫做類,在本書的C部份中將會被介紹.不管這些類的形式正確與否,我們必須使用某種機制以便把索引信息附在每個組件上.

 

The syntax is straightforward. At the beginning of a module text, you will be invited to write an indexing clause of the form

indexing

index_word1: value, value, value¼

index_word2: value, value, value¼

¼

¼ Normal module definition (see part C) ¼

 

Each index_word is an identifier each value is a constant (integer, real etc.), an identifier, or some other basic lexical element.

這個語法簡單易懂. 在模塊代碼的開頭,您要先聲明索引子句(indexing clause)

indexing

index_word1: value, value, value¼

index_word2: value, value, value¼

¼

¼ Normal module definition (see part C) ¼

每個index_word是一個標識符; 每個value是一個常量(整數,實數等等), 標識符,或其它的基本語法元素.

 

There is no particular constraint on index words and values, but an industry, a standards group, an organization or a project may wish to define their own conventions. Indexing and retrieval tools can then extract this information to help software developers find components satisfying certain criteria.

在索引命令和數值上沒有特別的限制,但是一種產業,一個一流團隊,一個組織或一個項目可能希望定義他們自己的標準.索引和檢索工具於是能抽取這個信息,來幫助軟件開發者找到符合特定標準的組件.

 

As we saw in the discussion of Self-Documentation, storing such information in the module itself — rather than in an outside document or database — decreases the likelihood of including wrong information, and in particular of forgetting to update the information when updating the module (or conversely). Indexing clauses, modest as they may seem, play a major role in helping developers keep their software organized and register its properties so that others can find out about it.

如我們在自包含文檔的討論中所看到的,在模塊的自身中儲存這些信息-勝於儲存在外面文件或數據庫中-減少了包括錯誤信息的可能性,特別是當更新模塊(或相反)時忘記了更新信息.如其所示,適度的索引子句,在幫助開發者組織他們的軟件和記錄軟件屬性中起着重要的作用,這樣便於其他人的查找.

 

Formats for reusable component distribution

可複用組件分配的格式

 

Another question straddling the technical-organizational line is the form under which we should distribute reusable components: source or binary? This is a touchy issue, so we will limit ourselves to examining a few of the arguments on both sides.

橫跨在技術-組織的界線上的另外一個問題是我們所發佈的可複用組件的格式: 源代碼或二進制碼? 這是一個敏感的話題,因此我們將有限地討論兩方中的一些論點.

 

For a professional, for-profit software developer, it often seems desirable to provide buyers of reusable components with an interface description (the short form discussed in a later chapter) and the binary code for their platform of choice, but not the source form.This protects the developer’s investment and trade secrets.

對於一個專業的,非盈利的軟件開發者來說,提供給買主的可複用組件具有一個接口描述(簡易格式(short form),在稍後的章節中討論)和相關平臺的二進制代碼,而不是源代碼形式,這通常看上去是很合理的.這保護了開發者的投資和商業祕密.

 

Binary is indeed the preferred form of distribution for commercial application programs, operating systems and other tools, including compilers, interpreters and development environments for object-oriented languages. In spite of recurring attacks on the very idea, emanating in particular from an advocacy group called the League for Programming Freedom, this mode of commercial software distribution is unlikely to recede much in the near future. But the present discussion is not about ordinary tools or application programs: it is about libraries of reusable software components. In that case one can also find some arguments in favor of source distribution.

對於商業應用程序,操作系統和其它的工具,包括面嚮對象語言的編譯器,解釋器和開發環境而言,二進制代碼的確是發佈的首選形式.儘管遭到不斷的抨擊,特別是來自一個被稱爲自由編程協會(League for Programming Freedom)的擁護組織,但這個商業軟件發佈的形式在不久的將來不太可能會改變.但是目前的討論並不涉及通常的工具或是應用程序:它是有關於可複用的軟件組件庫.在那種情況下也能找到一些論據來支持源代碼發佈.

 

[注] 自由編程協會(League for Programming Freedom) 是一民間組織,由教授,學生,經商者,程序員,用戶和軟件公司組成,獻身於重新得到編寫程序的自由.該協會並不反對議會所希望的法律系統一一個體程序的版權。該協會的目標是扭轉由特殊利益引起的判決所造成的變化(有關軟件的版權).

 

For the component producer, an advantage of source distribution is that it eases porting efforts. You stay away from the tedious and unrewarding task of adapting software to the many incompatible platforms that exist in today’s computer world, relying instead on the developers of object-oriented compilers and environments to do the job for you. (For the consumer this is of course a counter-argument, as installation from source will require more work and may cause unforeseen errors.)

對於組件作者,發佈源代碼的一個好處是能夠減輕移植的消耗.您可以從爲計算機領域中現存的許多不相容的平臺而修改軟件中脫離出來,改爲依靠面向對象的編譯器和環境的開發者爲您做這些乏味無聊的工作.(對消費者而言,這當然是一個駁論,因爲安裝源代碼將會需要更多的工作,並可能引起無法預料的錯誤.)

 

Some compilers for object-oriented languages may let you retain some of the portability benefit without committing to full source availability: if the compiler uses C as intermediate generated code, as is often the case today, you can usually substitute portable C code for binary code. It is then not difficult to devise a tool that obscures the C form, making it almost as difficult to reverse-engineer as a binary form.

一些面嚮對象語言的編譯器可以在不用提交完整代碼的情況下讓您保留一些移植性上的好處:正如如今的一種慣例,如果編譯器使用C作爲介質以產生代碼,那麼您通常能用可移植的C代碼代替二進制代碼.然後這很容易設計一個的工具用以加密C的結構,使其幾乎不能反編譯成一種二進制形式.

 

Also note that at various stages in the history of software, dating back to UNCOL (UNiversal COmputing Language) in the late fifties, people have been defining low-level instruction formats that could be interpreted on any platform, and hence could provide a portable target for compilers. The ACE consortium of hardware and software companies was formed in 1988 for that purpose. Together with the Java language has come the notion of Java bytecode, for which interpreters are being developed on a number of platforms. But for the component producer such efforts at first represent more work, not less: until you have the double guarantee that the new format is available on every platform of interest and that it executes target code as fast as platform-specific solutions, you cannot forsake the old technology, and must simply add the new target code format to those you already support. So a solution that is advertized as an end-all to all portability problems actually creates, in the short term, more portability problems.

同時也要注意在軟件歷史的各種不同階段中,遠在五十年代的UNCOL時期(通用計算語言UNiversal COmputing Language),人們就已經定義了低級指令格式以便能在任何的平臺上解釋,想從此可以對編譯器提供一個可移植的標準.爲了這個目的,1988年成立了包括硬件和軟件公司在內的ACE聯盟.加之JAVA語言帶來了JAVA字節碼的觀念,解釋器正在許多的平臺上被開發.但對於組件作者,這樣的話在開始會需要做更多的工作,而非減少:除非您加倍保證新格式在每個重要的平臺上都同樣有效,並且運行目標代碼就像在特定平臺的解決方案一樣快速,那麼在此之前,您就不能放棄舊有的技術,還必須能輕鬆地把新的目標代碼格式加入到您已經支持的平臺上.因此,就眼前來說,一個號稱能解決所有的移植性問題的解決方案實際上可能產生更多的移植性問題.

 

[注]60年代,計算機界有過面向通用計算機的統一語言(Universal Computer Oriented Language,UNCOL)用虛擬機實現統一編譯的思想,即各種語言都編譯到UNCOL,然後在本地機上實現UNCOL,但後來沒有流行起來.現在一般還都是針對具體機器、具體的操作系統研製特定語言的編譯系統.

 

Perhaps more significant, as an argument for source code distribution, is the observation that attempts to protect invention and trade secrets by removing the source form of the implementation may be of limited benefit anyway. Much of the hard work in the construction of a good reusable library lies not in the implementation but in the design of the components’ interfaces and that is the part that you are bound to release anyway. This is particularly clear in the world of data structures and algorithms, where most of the necessary techniques are available in the computing science literature. To design a successful library, you must embed these techniques in modules whose interface will make them useful to the developers of many different applications. This interface design is part of what you must release to the world.

作爲一個對源代碼發佈的意見,也許更重要一點是,觀察表明通過去掉實現中的源代碼來保護髮明和商業祕密的行爲無論如何其利益都是有限的.在一個優秀的可複用庫的構造中,許多艱苦的工作不是存在實現中,而是在組件接口的設計中;那是您無論如何都得要發佈的一部份.這在數據結構和算法的領域中尤其清楚,在計算科學文獻中大部份必需的技術在其中都有效.爲了要設計一個成功的庫,您一定要在模塊中嵌入這些技術,這些模塊的接口會有用於許多不同的應用程序開發者.這個接口設計是您必須發佈出去的一部份.

 

Also note that, in the case of object-oriented modules, there are two forms of component reuse: as a client or, as studied in later chapters, through inheritance. The second form combines reuse with adaptation. Interface descriptions (short forms) are sufficient for client reuse, but not always for inheritance reuse.

也要注意,在面向對象模塊的情況下,有二種組件複用的形式:客戶端複用或經由繼承複用,後者在稍後的章節中學到.第二種形式結合了複用和修改.接口描述 (簡易格式)對客戶端複用是足夠了的,但對繼承複用卻不.

 

Finally, the educational side: distributing the source of library modules is a good way to provide models of the producer’s best engineering, useful to encourage consumers to develop their own software in a consistent style. We saw earlier that the resulting standardization is one of the benefits of reusability. Some of it will remain even if client developers only have access to the interfaces but nothing beats having the full text.

最後,具有教育意義的一面是:要提供最好的工程模型,發佈庫模塊的源代碼是一個好方法,這有利於鼓勵用戶以一致風格去開發他們自己的軟件.我們早就看到結果標準化是複用性的優點之一.其中的一些將會保留,即使客戶端開發者只能使用接口;但擁有全部源代碼更好.

 

Be sure to note that even if source is available it should not serve as the primary documentation tool: for that role, we continue to use the module interface.

注意,即使可以利用源代碼,它也不應該視爲主要的文檔工具:對此,我們繼續使用模塊接口.

 

This discussion has touched on some delicate economic issues, which condition in part the advent of an industry of software components and, more generally, the progress of the software field. How do we provide developers with a fair reward for their efforts and an acceptable degree of protection for their inventions, without hampering the legitimate interests of users? Here are two opposite views:

這個討論已經略微提及了一些微妙的經濟議題,即軟件組件工業出現的部份條件,更概括的講,是軟件領域進步的部份條件.我們如何提供給開發者一個公平的報答,對他們所做的努力,並以一種可接受的程度保護他們的發明,而不阻礙用戶的合法興趣? 這裏有二個對立的觀點:

 

• At one end of the spectrum you will find the positions of the League for Programming Freedom: all software should be free and available in source form.

在其中的一方,您可以找到自由編程協會的態度: 所有軟件應該是免費的並能得到源代碼形式.

 

• At the other end you have the idea of superdistribution, advocated by Brad Cox in several articles and a book. Superdistribution would allow users to duplicate software freely, charging them not for the purchase but instead for each use. Imagine a little counter attached to each software component, which rings up a few pennies every time you make use of the component, and sends you a bill at the end of the month. This seems to preclude distribution in source form, since it would be too easy to remove the counting instructions. Although JEIDA, a Japanese consortium of electronics companies, is said to be working on hardware and software mechanisms to support the concept, and although Cox has recently been emphasizing enforcement mechanisms built on regulations (like copyright) rather than technological devices, superdistribution still raises many technical, logistic, economic and psychological questions.

在另一方,您會得到一個超發佈(superdistribution)的觀念,這是Brad Cox在一些文章和書中所主張的.超發佈允許用戶免費地複製軟件,在每次使用時付費而不是在購買時.設想一個小的計數器附在每個軟件組件上,每一次在您使用組件時記入一些美分,到月底時送您一份帳單.由於發佈源代碼很容易讓人刪除計數指令,所以這似乎排除了這種形式.雖然JEIDA,一個日本電子公司協會,據稱正在以硬件軟件結合的機制支持這種觀念,並且Cox最近一直在強調執行機制建立在規則上(類似版權)而非技術裝置上,但是超發佈仍然引起了許多技術上的,邏輯上的,經濟上的和心理學上的問題.

 

An assessment

評估

 

Any comprehensive approach to reusability must, along with the technical aspects, deal with the organizational and economical issues: making reusability part of the software development culture, finding the right cost structure and the right format for component distribution, providing the appropriate tools for indexing and retrieving components. Not surprisingly, these issues have been the focus of some of the main reusability initiatives from governments and large corporations, such as the STARS program of the US Department of Defense (Software Technology for Adaptable, Reliable Systems) and the “software factories” installed by some large Japanese companies.

任何複用性的綜合方案,連同技術方面一起,都會涉及組織和經濟方面的議題:使複用性成爲軟件開發文化的一部分,找出組件發佈的合理費用結構和正確格式,爲索引和檢索組件提供適當的工具.並不令人驚訝的是,這些議題已經是一些主要的複用性行動的中心,其來自於政府和大型公司,像是美國國防部的STARTS程序(可適應的,可靠的系統之軟件技術Software Technology for Adaptable, Reliable Systems)和被一些大型日本公司建立的"軟件工廠".

 

Important as these questions are in the long term, they should not detract our attention from the main roadblocks, which are still technical. Success in reuse requires the right modular structures and the construction of quality libraries containing the tens of thousands of components that the industry needs.

以長遠的觀點來看這些問題,重要的是,他們不應該從主要的障礙中轉移我們的注意力.這些障礙仍舊是技術上的.複用的成功需要良好的模塊結構和高品質庫的構造,這些庫中包含了數萬個工業所需要的組件.

 

The rest of this chapter concentrates on the first of these questions it examines why common notions of module are not appropriate for large-scale reusability, and defines the requirements that a better solution — developed in the following chapters — must satisfy.

本章的其餘部分專注於這些問題的第一條;它分析了通常的模塊概念爲什麼不適用於大規模的複用性,同時定義了一個更好的解決方案所必須滿足的需求,在下面的章節中將規劃這個方案.

 

4.5 THE TECHNICAL PROBLEM

4.5 技術問題

 

What should a reusable module look like?

一個可複用的模塊看上去象什麼?

 

Change and constancy

改變和恆定

 

Software development, it was mentioned above, involves much repetition. To understand the technical difficulties of reusability we must understand the nature of that repetition.

上面所提及的軟件開發中包括了大量的重複.要理解複用性上的技術困難,我們必須要理解重複的性質.

 

Such an analysis reveals that although programmers do tend to do the same kinds of things time and time again, these are not exactly the same things. If they were, the solution would be easy, at least on paper but in practice so many details may change as to defeat any simple-minded attempt at capturing the commonality.

某個分析表明了,雖然程序設計者一次又一次的做着相同類型的事,但卻並不是完全地相同.如果相同的話,至少在名義上,解決方案就會變得容易的多;但是在實際上,大量的細節可能會被改變,這導致在捕捉共性上任何頭腦簡單的嘗試都會遭到失敗.

 

A telling analogy is provided by the works of the Norwegian painter Edvard Munch, the majority of which may be seen in the museum dedicated to him in Oslo, the birthplace of Simula. Munch was obsessed with a small number of profound, essential themes: love, anguish, jealousy, dance, death¼ He drew and painted them endlessly, using the same pattern each time, but continually changing the technical medium, the colors, the emphasis, the size, the light, the mood.

一個生動的類比是由挪威畫家Edvard Munch的作品所提供的,其中大多數在奧斯陸的博物館中能看到,這也是Simula的誕生地. Munch迷於少數深刻,本質的主題: 愛,苦悶,妒忌,跳舞,死亡他不斷地汲取和繪畫它們,在每段時間內使用相同的圖案,但是不斷地變更技術媒介,顏色,重點,大小,光,情緒等等.

 

Such is the software engineer’s plight: time and again composing a new variation that elaborates on the same basic themes.

這是軟件工程師的情況:反覆構成了一種新的變化,這種新變化描述了相同的基本主題.

 

Take the example mentioned at the beginning of this chapter: table searching. True, the general form of a table searching algorithm is going to look similar each time: start at some position in the table t then begin exploring the table from that position, each time checking whether the element found at the current position is the one being sought, and, if not, moving to another position. The process terminates when it has either found the element or probed all the candidate positions unsuccessfully. Such a general pattern is applicable to many possible cases of data representation and algorithms for table searching, including arrays (sorted or not), linked lists (sorted or not), sequential files, binary trees, B-trees and hash tables of various kinds.

舉一個在本章開頭提到的例子:表查詢.表查詢算法的通式每次看上去都很相似:在表t的某些位置開始;然後從那個位置開始掃描,每次在當前的位置都檢查是否發現被尋找的元素,如果沒有,移到下一個位置.當發現了元素或在所有的預定範圍內都無所斬獲時程序結束.這樣一個表查詢的通用模式可以應用在數據表示法和算法中的許多可能的情況,包括各種不同類型的數組(排序或未排序),鏈表(排序或未排序),順序文件,二進制樹,B樹和哈希表.

 

It is not difficult to turn this informal description into an incompletely refined routine:

將非正式的描述變成一個並不完全精確的程序並不困難:

 

has (t: TABLE, x: ELEMENT): BOOLEAN is

-- Is there an occurrence of x in t?

local

pos: POSITION

do

from

pos := INITIAL_POSITION (x, t)

until

EXHAUSTED (pos, t) or else FOUND ( pos, x, t)

loop

pos := NEXT (pos, x, t)

end

Result := not EXHAUSTED (pos, t)

end

 

(A few clarifications on the notation: from ¼ until ¼ loop ¼ end describes a loop, initialized in the from clause, executing the loop clause zero or more times, and terminating as soon as the condition in the until clause is satisfied. Result denotes the value to be returned by the function. If you are not familiar with the or else operator, just accept it as if it were a boolean or.)

(符號中的一些聲明: from ¼ until ¼ loop ¼ end描述了一個循環,from子句開始,執行loop子句零次或多次,直到條件滿足until子句結束. Result指定了函數返回值.如果您不熟悉or else運算符,就當它是一個布爾類型的or好了.)

 

Although the above text describes (through its lower-case elements) a general pattern of algorithmic behavior, it is not a directly executable routine since it contains (in upper case) some incompletely refined parts, corresponding to aspects of the table searching problem that depend on the implementation chosen: the type of table elements (ELEMENT), what position to examine first (INITIAL_POSITION), how to go from a candidate position to the next (NEXT), how to test for the presence of an element at a certain position (FOUND), how to determine that all interesting positions have been examined (EXHAUSTED).

雖然上述的文字描述了(以它的小寫元素)一個算法行爲的通用模式,但是由於它包含了(大寫部分)一些不完全精確的部份,它並不是一個直接可運行的程序,相應的表查詢方面的問題依賴於被選擇的具體實現:表元素類型(ELEMENT),開始查詢的位置(INITIAL_POSITION),如何從一個選定的位置移到下一個(NEXT),該如何在一個特定位置檢測元素的存在(FOUND),該如何確定所有的指定位置都已經被檢測過了(EXHAUSTED).

 

Rather than a routine, then, the above text is a routine pattern, which you can only turn into an actual routine by supplying refinements for the upper-case parts.

那麼,上述的本文並非一個程序,而是一個程序模式,您只能通過提供大寫部分所對應的精確語句轉變成一個真實的程序.

 

The reuse-redo dilemma

複用重做的難題

 

All this variation highlights the problems raised by any attempt to come up with general-purpose modules in a given application area: how can we take advantage of the common pattern while accommodating the need for so much variation? This is not just an implementation problem: it is almost as hard to specify the module so that client modules can rely on it without knowing its implementation.

所有的這一變化突出了一個問題,在特定的應用程序領域中,嘗試着去找到通用的模塊的行爲引發了這個問題:當需要適應這麼多變化的時候,我們如何能夠利用通用模式?這不單單是一個實現的問題:它幾乎如此嚴密地詳細指明了模塊以至於客戶端模塊能在不知道其實現的情況下使用它.

 

These observations point to the central problem of software reusability, which dooms simplistic approaches. Because of the versatility of software — its very softness — candidate reusable modules will not suffice if they are inflexible.

這些觀察指出了軟件複用性的核心問題,即註定是過分單純化的方法.由於軟件的多功能性-其十足的柔韌性-如果備選的可複用的模塊不具有靈活性,那麼它們就滿足不了.

 

A frozen module forces you into the reuse or redo dilemma: reuse the module exactly as it is, or redo the job completely. This is often too limiting. In a typical situation, you discover a module that may provide you with a solution for some part of your current job, but not necessarily the exact solution. Your specific needs may require some adaptation of the module’s original behavior. So what you will want to do in such a case is to reuse and redo: reuse some, redo some — or, you hope, reuse a lot and redo a little. Without this ability to combine reuse and adaptation, reusability techniques cannot provide a solution that satisfies the realities of practical software development.

一個不可改變的模塊迫使您進入了複用或重做的難題之內: 照現在的樣子完全地複用模塊,否則全部重做.這時常有太多的限制.在一種典型的情形中,您發現一個模塊可能爲您的目前的部份工作的提供瞭解決方案,但卻不是完全的符合.您的特定需求可能需要改寫模塊原來的行爲.因此,在這種情況下您所想做的是複用重做:一部分複用,一部分重做-或者,如您所願,大部分複用,小部分重做.沒有結合複用和改寫這兩者的能力,複用性技術就不能夠提供一種解決方案來滿足現實軟件開發中的真實性.

 

So it is not by accident that almost every discussion of reusability in this book also considers extendibility (leading to the definition of the term “modularity”, which covers both notions and provided the topic of the previous chapter). Whenever you start looking for answers to one of these quality requirements, you quickly encounter the other.

因此,這並不是偶然的現象,在本書中每次複用性的討論也同時考慮了擴充性(術語"模塊性的定義包括了這兩個觀念,在之前的章節中已介紹了).只要您開始尋找這兩個品質需求中的某個時,您很快就會遇到另一個.

 

This duality between reuse and adaptation was also present in the earlier discussion of the Open-Closed principle, which pointed out that a successful software component must be usable as it stands (closed) while still adaptable (open).

在先前的開閉原則的討論中,複用和改寫之間的二元性也同時介紹了.這個討論指出了一個成功的軟件組件一定是一直可用的,既使處在修改(開放)的狀態時也維持不變(關閉).

 

The search for the right notion of module, which occupies the rest of this chapter and the next few, may be characterized as a constant attempt to reconcile reusability and extendibility, closure and openness, constancy and change, satisfying today’s needs and trying to guess what tomorrow holds in store.

對模塊的正確觀念的研究,佔用了本章的餘下部分和下一個章的部分內容,這可以稱爲一個持續的嘗試,用以調協複用性和擴充性,開放和關閉,恆定和變化,滿足今天的需求和試着去猜測明天會發生什麼.

 

4.6 FIVE REQUIREMENTS ON MODULE STRUCTURES

4.6 模塊結構上的五個需求

 

How do we find module structures that will yield directly reusable components while preserving the possibility of adaptation?

我們如何找出一種模塊結構,使其在直接地產生可複用組件的同時保留更改的可能性?

 

The table searching issue and the has routine pattern obtained for it on the previous page illustrate the stringent requirements that any solution will have to meet. We can use this example to analyze what it takes to go from a relatively vague recognition of commonality between software variants to an actual set of reusable modules. Such a study will reveal five general issues:

• Type Variation.

• Routine Grouping.

• Implementation Variation.

• Representation Independence.

• Factoring Out Common Behaviors.

在前頁中的表查詢議題和has例程模式闡明瞭任何解決方案都會遇到的迫切的需求.我們能使用這個例子來分析,從軟件變體到一組實際的可複用模塊之間的模糊不清的共通性.這種研究提出了五個通用的議題:

Ÿ           類型變化

Ÿ           例程分組

Ÿ           實現變化

Ÿ           表示法獨立

Ÿ           合併通用行爲

 

Type Variation

類型變化

 

The has routine pattern assumes a table containing objects of a type ELEMENT. A particular refinement might use a specific type, such as INTEGER or BANK_ACCOUNT, to apply the pattern to a table of integers or bank accounts.

has例程模式假定一個表包含了一個類型爲ELEMENT的對象.一個特別的細化可以使用一個特定的類型,像是整型(INTEGER)BANK_ACCOUNT,在整數或銀行帳戶的表中應用這個模式.

 

But this is not satisfactory. A reusable searching module should be applicable to many different types of element, without requiring reusers to perform manual changes to the software text. In other words, we need a facility for describing type-parameterized modules, also known more concisely as generic modules. Genericity (the ability for modules to be generic) will turn out to be an important part of the object-oriented method an overview of the idea appears later in this chapter.

但是這並不夠.一個可複用的查詢模塊應該可以應用到許多不同的元素類型中,不需要複用者對軟件代碼進行手工改變.換句話說,我們需要一個描述參數化類型的模塊工具,也要更簡要的瞭解泛化(generic)模塊.泛型(泛化模塊的能力)將會成爲面向對象方法的一個重要部份;本章稍後會介紹這個概念.

 

Routine Grouping

例程分組

 

Even if it had been completely refined and parameterized by types, the has routine pattern would not be quite satisfactory as a reusable component. How you search a table depends on how it was created, how elements are inserted, how they are deleted. So a searching routine is not enough by itself as a unit or reuse. A self-sufficient reusable module would need to include a set of routines, one for each of the operations cited — creation, insertion, deletion, searching.

即使類型已經被完全地細化和參數化, has例程模式也不能完全滿足於當作一個可複用組件.您如何查找一個表要依賴於它被建立的方式,元素被插入的方式和被刪除的方式.因此,一個查詢例程單獨作爲一個單元或複用並不足夠.一個獨立的可複用模塊需要包括一系列的例程,其中一組是運算引用,如創建,插入,刪除,查找.

 

This idea forms the basis for a form of module, the “package”, found in what may be called the encapsulation languages: Ada, Modula-2 and relatives. More on this below.

這種思想構成了一種模塊形式-"軟件包"的基礎,可以在被稱之爲封裝語言中發現它:Ada,Modula-2和類似的語言.更多的將在下面介紹.

 

Implementation Variation

實現變化

 

The has pattern is very general there is in practice, as we have seen, a wide variety of applicable data structures and algorithms. Such variety indeed that we cannot expect a single module to take care of all possibilities it would be enormous. We will need a family of modules to cover all the different implementations.

has模式非常通用;如同我們已經看到的,它是在實踐中可以廣泛適用的數據結構和算法.如此真正的多樣性使我們不能夠指望一個單一模塊就能涵蓋所有的可能性;否則它就會非常巨大.我們需要一個模塊系列來包含所有不同的實現.

 

A general technique for producing and using reusable modules will have to support this notion of module family.

產生並使用可複用模塊的通用技術必須支持這個模塊系列的觀念.

 

Representation Independence

表示獨立

 

A general form of reusable module should enable clients to specify an operation without knowing how it is implemented. This requirement is called Representation Independence. Assume that a client module C from a certain application system — an asset management program, a compiler, a geographical information system¼ — needs to determine whether a certain element x appears in a certain table t (of investments, of language keywords, of cities). Representation independence means here the ability for C to obtain this information through a call such as

present := has (t, x)

without knowing what kind of table t is at the time of the call. C’s author should only need to know that t is a table of elements of a certain type, and that x denotes an object of that type. Whether t is a binary search tree, a hash table or a linked list is irrelevant for him he should be able to limit his concerns to asset management, compilation or geography. Selecting the appropriate search algorithm based on t’s implementation is the business of the table management module, and of no one else.

一個可複用模塊的通用形式應該使客戶端能夠使用一個運算而不必知道它是如何實現的.這個需求稱之爲表示法獨立.假設一個來自某個應用程序系統的客戶端模塊C-一個資產管理程序,一個編譯器,一個地理信息系統-需要確定某個元素x是否出現在表t中(投資表,語言關鍵字表,城市表).在這裏,表示法獨立意謂着,通過如 present := has (t, x) 這樣的調用C獲得信息的能力,在調用的時候不需要知道表t的類型.C的作者應該只需要知道t是具有某種類型元素的一個表,而x表示那個類型的一個對象.是否t是一個二進制查詢樹,一個哈希表或一個鏈表對他來說無關緊要;他應該能夠把他的重點放在資產管理,編譯或地理學上.基於t的實現選擇適當的查尋算法是表管理模塊的事務,而和其它模塊無關.

 

This requirement does not preclude letting clients choose a specific implementation when they create a data structure. But only one client will have to make this initial choice after that, none of the clients that perform searches on t should ever have to ask what exact kind of table it is. In particular, the client C containing the above call may have received t from one of its own clients (as an argument to a routine call) then for C the name t is just an abstract handle on a data structure whose details it may not be able to access.

當客戶端創建一個數據結構的時候,這個需求不能排除讓客戶端選擇一個特定的實現.但是隻會有一個客戶端不得不作出初始的選擇;在那之後,在t上進行查詢的客戶端不再需要了解表的精確類型.特別地,包含上述調用的客戶端C從它自己的客戶端中可能已經接收了t(作爲例程調用的參數);然後,對C來說,名字t只是一個數據結構上的抽象句柄,其細節不能夠被訪問.

 

You may view Representation Independence as an extension of the rule of Information Hiding, essential for smooth development of large systems: implementation decisions will often change, and clients should be protected. But Representation Independence goes further. Taken to its full consequences, it means protecting a module’s clients against changes not only during the project lifecycle but also during execution — a much smaller time frame! In the example, we want has to adapt itself automatically to the run-time form of table t, even if that form has changed since the last call.

您可以把表示法獨立看成是信息隱藏規則的一個擴展,對大系統的平滑開發很有必要: 實現的結果將會經常被改變,而且客戶端應該被保護.但是表示法獨立更進一步.利用其全面的作用,這意味着保護模塊的客戶端免於變化,不只有在項目週期期間而且也在執行期間-一個更加小的時間範圍! 在這個例子中,我們希望has對錶t的運行時形式能自動地自適應,即使那種形式由於上一個調用後已經改變了.

 

Satisfying Representation Independence will also help us towards a related principle encountered in the discussion of modularity: Single Choice, which directed us to stay away from multi-branch control structures that discriminate among many variants, as in

滿足表示法獨立也將會幫助我們使用一項相關原則,這就是我們在模塊性的討論中遇到的: 單選(Single Choice),它指導我們避免在許多變體之間作出區分的多分支控制結構, 如

 

if t is an array managed by open hashing” then

“Apply open hashing search algorithm”

elseif t is a binary search tree” then

“Apply binary search tree traversal”

elseif

(etc.)

end

 

It would be equally unpleasant to have such a decision structure in the module itself (we cannot reasonably expect a table management module to know about all present and future variants) as to replicate it in every client. The solution is to hide the multi-branch choice completely from software developers, and have it performed automatically by the underlying run-time system. This will be the role of dynamic binding, a key component of the object-oriented approach, to be studied in the discussion of inheritance.

至於在每個客戶端中重複它,在模塊本身中有這樣的一個選擇結構會相當地令人不愉快(我們不能夠期待一個表的管理模塊知道所有的已有的和將來的變體). 解決方案要對軟件開發者完全地隱藏多分支選擇,而且內在的運行時系統會自動地完成這種選擇.這將是動態綁定的任務,其是面向對象方式的一個關鍵組件,這會在繼承的討論中學習到.

 

Factoring Out Common Behaviors

合併通用行爲

 

If Representation Independence reflects the client’s view of reusability — the ability to ignore internal implementation details and variants –, the last requirement, Factoring Out Common Behaviors, reflects the view of the supplier and, more generally, the view of developers of reusable classes. Their goal will be to take advantage of any commonality that may exist within a family or sub-family of implementations.

如果表示法獨立反映了客戶端複用性的觀點-忽略內在的實現細節和變體的能力-那麼最後一個需求,合併通用行爲,則反映了供應者的觀點,更通常的是可複用類的開發者的觀點.他們的目標是要利用任何可能在一個實現系列或子系列裏存在共通性.

 

The variety of implementations available in certain problem areas will usually demand, as noted, a solution based on a family of modules. Often the family is so large that it is natural to look for sub-families. In the table searching case a first attempt at classification might yield three broad sub-families:

如您所知,在特定問題領域中,有效實現的多樣性通常要求一個基於模塊系列的解決方案.這個系列常常是非常龐大的,以致於總是要藉助於子系列.在表查詢的情況中,第一次分類嘗試就可能產生三個主要的子系列:

 

• Tables managed by some form of hash-coding scheme.

• Tables organized as trees of some kind.

• Tables managed sequentially.

Ÿ           由一些哈希碼方案結構所處理的表

Ÿ           由幾種樹類型所組織的表

Ÿ           順序處理

 

Each of these categories covers many variants, but it is usually possible to find significant commonality between these variants. Consider for example the family of sequential implementations — those in which items are kept and searched in the order of their original insertion.

這些種類的每一個都包括許多變體,但是在這些變體之間通常能找到顯著的共通性.考慮一個順序實現系列的例子-那些記錄以最初插入的順序被存儲和查尋.

 

 


 

Possible representations for a sequential table include an array, a linked list and a file. But regardless of these differences, clients should be able, for any sequentially managed table, to examine the elements in sequence by moving a (fictitious) cursor indicating the position of the currently examined element. In this approach we may rewrite the searching routine for sequential tables as:

一個順序表的表示法可能包括一個數組,一個鏈表和一個文件.但是不考慮這些不同,在任何順序處理的表中,客戶端應該能夠通過移動一個(虛擬的)光標(cursor)來依次檢查元素,這個光標指示了當前檢查元素的位置.在這方式中,我們可以對順序表重寫查詢例程:

 

has (t: SEQUENTIAL_TABLE x: ELEMENT): BOOLEAN is

-- Is there an occurrence of x in t?

do

from start until

after or else found (x)

loop

forth

end

Result := not after

end

 

This form relies on four routines which any sequential table implementation will be able to provide:

start, a command to move the cursor to the first element if any.

forth, a command to advance the cursor by one position. (Support for forth is of course one of the prime characteristics of a sequential table implementation.)

after, a boolean-valued query to determine if the cursor has moved past the last element this will be true after a start if the table was empty.

found (x), a boolean-valued query to determine if the element at cursor position has value x.

這段結構使用了四個例程,任何的順序表實現都要能夠提供:

·        start,一個移動光標至第一個元素的命令

·        forth ,一個移動光標前進至下一個元素的命令(支持forth當然是一個順序表實現的首要特性)

·       
after,一個布爾值,其值決定於是否移動光標經過了最後一條元素.如果表是空的,那麼在start之後其值爲真.

·        found (x),一個布爾值,其值決定於是否光標所在位置的元素含有值x.

 

 

 

At first sight, the routine text for has at the bottom of the preceding page resembles the general routine pattern used at the beginning of this discussion, which covered searching in any table (not just sequential). But the new form is not a routine pattern any more it is a true routine, expressed in a directly executable notation (the notation used to illustrate object-oriented concepts in part C of this book). Given appropriate implementations for the four operations start, forth, after and found which it calls, you can compile and execute the latest form of has.

乍一看,在前一頁的has例程代碼好似最初討論所採用的通用例程模式,其覆蓋了在任何表中的查詢(不僅僅是順序表).但是新的形式不再是一個例程模式;它是一個真實的例程,直接地表示了可執行符號(這些符號在本書的C部份用來描述面向對象的概念).對所調用的四個運算start, forth, afterfound,給定適當的實現後,您就能編譯而且執行has最後的形式.

 

For each possible sequential table representation you will need a representation for the cursor. Three example representations are by an array, a linked list and a file.

對於每個可能的順序表表示法,您都會需要一個光標的表示法.一個數組,一個鏈表和一個文件是表示法的三個例子.

 

The first uses an array of capacity items, the table occupying positions 1 to count. Then you may represent the cursor simply as an integer index ranging from 1 to count + 1. (The last value is needed to represent a cursor that has moved “after” the last item.)


第一個使用了一個 capacity項的數組,表的位置是從1count. 您可以用index簡單的表示光標,它是一個從1到count + 1的整數.(最後的整數值表示移動光標到最後一條之後).

 

 

The second representation uses a linked list, where the first cell is accessible through a reference first_cell and each cell is linked to the next one through a reference right. Then you may represent the cursor as a reference cursor.

第二個表示法使用了一個鏈表,通過一個引用first_cell訪問第一個單元,並且每一個單元通過引用right鏈接到下一個.您可以用引用cursor來表示光標.

 


The third representation uses a sequential file, in which the cursor simply represents the current reading position.

第三個表示法使用一個順序文件,其光標僅僅表示當前的位置.

The implementation of the four low-level operations start, forth, after and found will be different for each variant. The following table gives the implementation in each case. (The notation t @ i denotes the i-th element of array t, which would be written t [i] in Pascal or C Void denotes a void reference the Pascal notation f­, for a file f, denotes the element at the current file reading position.)

這四個底層的操作start, forth, afterfound,其實現對每一個變體來說都是不同的.下表給出了它們的實現.(符號t @ i表示數組ti個元素,PascalC中寫作t [i]Void表示一個空引用;對於文件fPascal符號f­指示了在當前文件中讀位置上的元素.)

 

 


The challenge of reusability here is to avoid unneeded duplication of software by taking advantage of the commonality between variants. If identical or near-identical fragments appear in different modules, it will be difficult to guarantee their integrity and to ensure that changes or corrections get propagated to all the needed places once again, configuration management problems may follow.

在這裏,複用性的挑戰是要利用在變體之間的共通性來避免不需要的軟件重複.如果相同或幾乎相同的片段出現在不同的模塊中,那麼這將很難保證它們之間的完整性,也不能確保變化或校正會涉及到所有可能的地方;再一次,配置管理問題也將隨之而來.

 

All sequential table variants share the has function, differing only by their implementation of the four lower-level operations. A satisfactory solution to the reusability problem must include the text of has in only one place, somehow associated with the general notion of sequential table independently of any choice of representation. To describe a new variant, you should not have to worry about has any more all you will need to do is to provide the appropriae versions of start, forth, after and found.

所有的順序表變體共享has函數,只是四個底層運算的實現不同而已.對複用性問題而言,滿意的解決方案必須只在一處包含有has代碼,以某種方式與順序表的通用觀念關聯,這些通用的觀念獨立於表示法的任何一種選擇.爲了要描述一個新的變體,您應該不再需要考慮has;您所需要的只是提供start,forth,afterfound合適的版本.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章