Fundamentals of Software Engineering
軟體工程的基本原則
摘自《The Art of Software Architecture: Design Methods and Techniques 》
http://as.wiley.com/WileyCDA/WileyTitle/productCd-0471228869.html
劉建文略譯(http://blog.csdn.net/keminlau)
The main task of engineers, according to Pahl (Pahl, 1996), "is to apply their scientific and engineering knowledge to the solution of technical problems, and then to optimize those solutions within the requirements and constraints set by material, technological, economical, legal, environmental, and human-related considerations." We can extend this definition to define the main task of software engineers. Informally, the main task of software engineers is to apply their logic and programming knowledge to the solution of technical and business problems. Then they optimize those solutions within the requirements and constraints set by logic (the material of software engineering); software technology; and economical, legal, environmental, and safety considerations.
根據Pahl《Engineering Design: A Systematic Approach》上的觀點,工程師的主要工作是應用他們的科學的工程的知識去解決技術問題,並且根據各種的需求和限制最佳化解決方案,各種限制包括原材料的、技術的、經濟方面的、合法性上的、環境方面的和人類有關的考慮。我們可以擴充一下這個定義來定義軟體工程師的主要工作。非形式地說,軟體工程師的主要工作是運用他們的邏輯和編程知識去解決商務問題和技術問題。這些解決方案要滿足各種的商務需求和各種限制,如邏輯限制、軟體技術限制、經濟成本、合法性、環境限制和安全考慮。
The term engineering, as applied to software, is not always entirely appropriate. I think it assumes too broad of a specialty. I think of software development as involving many subdisciplines. These include specialties like database design and implementation, Structured Query Language (SQL), Java, and C++ programming, and eXtensible Stylesheet Language Transformations (XSLT) coding. The specialties can even be finer grained than this. Each of these technologies needs specialists just as there are specialists in established engineering disciplines such as electronic and mechanical engineering. In each of these fields there are further specializations. Yet we treat software development as if it were a single engineering discipline. It is, in fact, several related disciplines. Imagine that a competent developer of XSLT is given very clear specifications, to which a given transformation, or stylesheet, must conform, including well-defined inputs and outputs. The XSLT designer can produce a stylesheet using available tools and methods and possibly reuse parts from an existing library of XSLT. This assumes that we can provide well-defined specifications.
工程這個概念應用於軟體開發並不是很合適的。我認為過於寬泛。軟體開發涉及了很多的子學科,這些特殊的子學科包括資料庫設計和實現、SQL、JAVA、C++編程、XSLT等。每個子學科本身的內容也相當的多,也是一個工程科學。現在我們把軟體工程當作似乎是單一的工程學科,實際上軟體工程是很多相關的工程學科的混合。
I think that the division of software engineering is probably necessary with some combination of technology (databases, Java) and problem domains. Of course, having specialties with individual techniques, tools, and methods still poses a problem of engineering sophisticated systems that involve integrating these technologies. This is where the software architect comes in. The software architect could be considered a type of software engineer that may not necessarily be a specialist in all of the particular software engineering domains. The software specialist is a specialist in architecture design, and understands the varieties of technology well enough to integrate them into a cohesive solution to a complex problem.
我覺得對軟體工程進行技術和問題領域的分解是有必要的。當然,這種分解是有代價的,因為各種獨立的技術、工具和方法要整合在一起來解決軟體工程問題需要額外的整合知識。這也是軟體架構師的職責所在。軟體架構師可以理解成一種不必完全掌握所有軟體工程子領域的工程師,他們專職於架構設計、瞭解各種工程技術的區別,從而整合這些技術來解決複雜的工程問題。
It is not uncommon in practice today to divide labor along technology lines. It is common to separate user interface (UI) or presentation development from middle-tier development or back-end development. But without architecture, even this separation of engineering specialties will not necessarily help produce high-quality systems. Some authors argue that this separation (called horizontal slicing) is not necessarily effective and advocates a vertical slicing where each developer owns a set of functional requirements and implements them front to back. Both approaches can be used effectively. It's more a matter of the skills of the individuals together with the technical leadership and project management techniques.
技術工作的分解出現已經相當的常見了。像分離系統的UI、中介層和後端。如果沒有架構的分解,大系統的品質沒有保證。有一些人認為這種“水平分區”的分解的效率不高,他們提倡垂直的分區,就是每個開發人員負責系統的一部分的功能代碼的實現,再進一步協作。這兩種方法都有效。無論是哪一種,有件東西是很確定的,就是大項目的技術指導和管理提上議程。
The two primary problems in software development that have yet to be solved satisfactorily are making systems cost effective and of higher quality. Improving the productivity of software engineers is an important part of making systems cost effective. Improving the quality of systems is important in order to make them safer and more effective in accomplishing business goals and objectives. Improving the quality of the design of a system also aids in achieving cost-effectiveness. A major obstacle to solving these two problems is the complexity inherent in developing software. This is a result of the complexity of the problems being solved, the wide variety of technologies that may be applied, and the fact that software development is almost purely a design activity. (As opposed to other engineering disciplines of which manufacturing is a major time and cost element of the process, in software even writing code is a design activity and cannot be managed like a manufacturing process.)
軟體開發的兩大基本問題--系統的成本效益與高品質已經得到很好的控制了。解決這兩大問題的主要障礙是軟體開發的固有的複雜性。複雜性的根源有,第一,待解決的問題本身的複雜性;第二,可供選擇的技術多種多樣;第三,軟體開發是種純設計的活動(相對於其它的工程學科,有相對固定的生產時間和生產成本,軟體就算寫代碼也是一種設計工作而無法受生產過程式控制制)。
Using current methods, technologies, and programming languages, we are able to solve problems to a certain level of complexity. However, to break through the barriers established by the complexity of the problem to build larger systems, we need to evolve our methods and tools. As systems grow in complexity, certain other quality attributes become more relevant; as the size of a system grows, the number of dimensions of the system also grows. In small systems, we can focus on functional correctness and performance. In large systems, we need to address attributes such as portability, security, reliability, and modifiability.
使用目前的技術、方法和程式設計語言,我們可以解決問題在一定層次水平的複雜性。但是,要解決大系統所面臨的問題則需要混合使用所有方法和工具。當系統開始變得複雜,這些系統品質有關的屬性變得很很重。在小型的系統,我們可以集中系統功能的正確性和效能,而在大系統我們還得考慮系統的靈活性、安全性、可靠性和可修改性等。
There are several fundamental software engineering techniques that can help improve the quality and cost-effectiveness of software:
- Reusable assets
- General-purpose programming languages
- Special-purpose programming languages
- Modeling languages and notations
有四種提供軟體品質和成本效益的基本技術:
- 可重用資源
- 通用程式設計語言
- 專用程式設計語言
- 建模語言和圖形
Reusable Assets
Code reuse improves the productivity of the programmer by shortening the amount of time required to implement some functionality. Of course, there is a trade-off of time spent discovering, learning, and integrating the reusable code, so reusable code needs to be easy to find, quick to learn, and straightforward to integrate. Code reuse manifests itself in the following:
Source code that can be copied and modified to suit or be used as is (for example, C++ algorithms from a shareware repository or copied from a book).
Commercial off-the-shelf (COTS) components that are available in binary (compiled) form and that can be imported or linked to other components or applications. This includes:
Binary code "libraries" that can be linked into a program at compile time or loaded and bound at run time (for example, a sockets library).
Operating environments and platforms (for example, operating systems, databases, application servers).
代碼重用提高程式員功能模組的開發效率,當然,部分折衷的時間用在了學習、發現和整合這些可重的代碼,所以可重用代碼必須設計得易用易學和易整合。代碼重用的形式有:
- 原始碼,可以被複製和修改的(像C++演算法)直接的原始碼
- 商業(成品)組件,是可被引入和連結的二進位組件,形式包括:
- 二進位代碼“庫”,可在編譯期連結到新應用或者在運行期進行動態綁定的“庫”;
- 作業環境或平台(例如,作業系統、資料庫和應用伺服器)
Reusable components, especially ones that address large problem spaces, provide a huge boost in productivity. Imagine if you had to write your own middleware, application server, and database in order to develop a distributed business application. Of course, all of those reusable technologies contain more features than any single application needs but even to develop the subset required by an application is a formidable and time-consuming task.
可重用組件,特別對於定位大問題空間的,在開發效率上提供巨大的的協助。想像一下,為了開發一個分布式商務應用,沒有可重用組件,你得自己開發中介軟體、應用伺服器和資料庫。
In order to effectively reuse components, we must be able to express our solution in terms of the abstractions of the component. There are times when a particular abstraction, such as relational entities, doesn't suit all of our needs, just as a natural language may not have words to express certain concepts. So we invent new technologies just as we invent new words. Object-oriented databases are an example of such an invention. When object-oriented programming started to supplant existing structured languages like C and Pascal, a semantic gap was introduced between the representation of information in the programming language and the representation of information in the database. Many papers and books have addressed the object-relational mapping problem. Today we have documented patterns for object-relational mapping that assist us in overcoming this obstacle.
為了更有效使用可重用組件,我們必須能夠使用組件抽象級的詞彙來表達我們的解決方案。但是有時我也不得不使用一些意外的抽象詞彙,像關聯性物件,關聯性物件不能完全混進OO的抽象層級。這就好像自然語言有時無法有一些詞語來表達某個概念,所以我用創造新詞彙來表達不明概念的方來解決關聯性物件不能完全混進OO的問題,這就是物件導向資料庫。當物件導向語言開始排擠結構化語言,像C和Pascal時,程式設計語言中表達資訊的形式與資料庫中的表達資訊的形式產生了語義斷層。已經有很多論文和圖書討論了這個對象-關係映射問題。現在我們也已經有了詳細的模式處理對象-關係映射問題。
General-Purpose Programming Languages
Powerful general-purpose programming languages like C++ and Java provide expressive power for creating solutions to many complex problems by allowing the programmer to focus on the problem at hand and worry less about specific hardware capabilities. General-purpose object-oriented languages don't solve the problem of complexity alone; they must be used in conjunction with guidelines and design patterns. How often have you seen a class that was really just a big collection of structured subroutines, such as the God Class (Riel, 1996)?
通用程式設計語言,像C++和JAVA的強大在於為開發複雜的應用提供強大的表達能力。通用的物件導向語言本身對處理問題複雜性是有限的,它們必須聯合各種模式使用。
Special-Purpose Programming Languages
Some COTS components have specialized programming languages for creating applications or parts of an application. The languages can be easier to use than general-purpose programming languages for specific problems. For example, when using a relational database component a programmer uses Data Definition Languages (DDL) and SQL to implement a data storage and access solution. SQL is specialized for the domain of relational databases. Specialized languages improve productivity by allowing the developer to think in terms of the abstractions of a specific technology (which is a simpler domain to comprehend) rather than by using the same general-purpose language for all programming problems. If a programmer had to understand how the data was stored in files and how the files were indexed, the problem would become much more complex. Of course, specialized languages introduce complexities of their own. The industry addresses this by developing guidelines and design patterns for the effective use of a particular technology. In relational databases, the theory of normal forms was developed to help programmers design databases with certain quality attributes. Other examples of specialized languages are Web presentation technologies such as Active Server Pages (ASP), Java Server Pages (JSP), and Hypertext Preprocessor (PHP), and data representation and transformation languages such as Hypertext Markup Language (HTML), eXtensible Markup Language (XML), and eXtensible Stylesheet Language Transformations (XSLT).
一些商業組件使用了專用語言來開發應用或者開發應用的部分。對於一些特定的問題,專用語言比通用語言更有效。例如,當使用關聯式資料庫組件時,程式員會使用資料定義語言 (Data Definition Language)(DDL)和結構化查詢語言 (SQL)(SQL)來實現資料存放區和訪問。SQL是關聯式資料庫領域的特殊語言。專用語言能有效提高開發效率,原因是它為程式員解決特定問題提供了特定的語言詞彙。不像通用語言,如果程式員為了使用資料庫必須理解資料是如何被儲存為檔案並且如何被索引,問題就變得很複雜了。當然,專用語言也有它自身的複雜性。業界已經為有效使用專用技術開發出了相關的開發指導和設計模式。如在關聯式資料庫,範式理論為開發人員設計資料庫提供了指導。
Modeling Languages and Notations
Modeling languages and design notations emerged as methods for improving software design quality. It is argued that an expressive modeling notation can expand our capability to design software much like mathematics allows us to reason about more complex things than our minds would normally be capable of without such a language. The entity relationship diagram (ERD), for example, is a powerful modeling language and notation that allows a software engineer to design and communicate expressive data models. Without such a language, it would be difficult to think about the information design of a system, and without a notation to represent the diagrams, it would be difficult to communicate those designs to others. The formality of the language allows different people to interpret a model in a precise way.
The UML is a rich collection of modeling notations for representing many aspects or views of a software system, including the information and information flow, class structure, and object interactions. The UML and other modeling languages improve a software engineer's individual capacity to create complex solutions. Some UML tools today allow for partial code generation from UML models. It is possible that a language like UML may become a true programming language (either special-purpose or general-purpose) As we have seen in the brief history above, what begins as a notation for representing software design can become the next-generation programming language.