?? bianchenzhenyan.txt
字號:
般接口需實現,邏輯需繼承,此時其它庫可按需進行plug in 或者out),這就是庫引用庫,這種情況下有一些
未端的實現是不應該加入中間封裝的,比較好的作法是用一個庫定義架構和基本工具函數集,以及對其它未
端工具庫的接口邏輯(此時先前定義的那個庫就是主庫,其它的庫是可選的輔庫,比如Yake的實現就是這
樣),實現就是最后一節提到的幾個Demo(作為基礎的邏輯已經被庫封裝起來,其它的就是實現了)
像Yake,它提供了一個Base core和很多構架上的接口邏輯,每個接口邏輯都實現了一個對外來庫的引用,
Base core是工具函數集(也有一些接口邏輯),這是Yake的主體部分,而接口邏輯(Yake也在這里實現了一些
工具函數庫比如)和對其它庫的引用邏輯(也是一些Adapter)才是Yake的重要部分(Yake包括它的base和對
其它庫的引入邏輯這二大部分,當然還有它的一些工具實現,這樣算起來Yake有三大部分).
接口是可復用中一個很重要的概念。
?? 真正的DSL
編程新手真言 - GameRes.com 頁碼,14/101
mhtml:file://F:\Cpp\編程新手真言.mht 2008-7-30
聲明性的語言是建立在編譯語言之上的,編譯語言的目標就是要產生機器碼
像C++,ALGO,,PROLG這些語言都可以稱之為領域語言,,,而YACC就是建立在他們上面的更高階
語言
如果你有過寫編譯器或語言的經歷,你就會知道語義在這個過程中所發揮的作用了,,,,不同的語言用
于不同的領域,,所采用的語義也就不同,,數據庫有它的SQL語言,,建模有UML語言,接口有IDL語
言,,,等等,,,如果存在一種語義(并由此發展出一種語言),可以用來表示所有領域的語義,,那
么由這種語義發展而來的一種語言就是元語言,,而XML就可以做到元數據,,YACC(編譯器的編譯器)
在一定程序上實現了元語言,,而多范型可以稱得上元設計了,,
作用何在呢?
每一個領域都有它自己的字母表(領域字典),,,每個領域應當專門用一種語言來開發..有它不同于其它領域的
語義(不跟其它語言一樣),,語義是語言之上的一層邏輯,XXX學指出,,用一門語言比如C,C++或者僅
僅用OO來描述全部領域都是不完整的
繼承和虛函數都可以產生多態,
我們應該不要在接口中包含數據成員(像VC++的.h文件中就允許這種形式,這導致C++的頭文件并非一個
良好的接口)
接口往往是函數陣列,而且往往接口本身也是一個對象,包含這些函數陣列作為它的成員,虛函數的意義
就在于它不必定義它的實現,,正是因為沒有實現,所以它可以被override而形成新的接口供以后的繼承
類來實現它
對接口編程就是對函數編程,,定義行為集代表的邏輯層之間的關系,而數據分派在子類中作為實現
判斷一個類的成員是不是能被繼承,,最終的途征是看它是靜態綁定的還是動態綁定的,如果動態的,就
可以,(static 成員)
推遲綁定時間到編譯期(設計期),就是元編程的意義所在的一個重要方面
元編程就是設計期實現和運行期實現的結合(也即在編碼時同時進行設計期和運行邏輯的工作)
?? 真正的MetaProgramming
不是指.net那種共用一個庫的CLS
面向對象在復用工作方面做得很好(比如它提供了繼承,多態,還提供了二進制復用比如COM,還提倡用
類聚合代替繼承而不是tear off,還出現了諸如設計模式這樣的復用經驗),但是這是相對現實生活的那一端
做的工作,,然而它對于編程工具端(編譯器)本身來說是不友好的(程序源碼必須要進入runtime才能讓我們看
到這所有的OO里面發生的事,在編譯階段(一般也稱為design - time)我們不能控制這些OO對于問題域的實
現),我們應該在沒有讓程序進入某種具體編譯器之前,,就讓它得以被控制,而不僅僅是預測這些編譯的
文件進入runtime以后會形成怎么樣的邏輯
也即,類的職責單位是類文件,這種機制有一些的缺陷性,問題域是巨大的,如果我們動手一項工程,我
們不希望被無窮的細節所困擾(現實問題總要分解為一些類,最終要形成類文件,一般每個職責形成一個
類),我們希望有一種介于編譯器和現實問題之間的更大的整合層來考慮事物(而不是一個一個的類文件),,
也即,我們不需要考慮現實問題到類的實現路徑,我們希望在設計期就考慮現實問題到一個“比類還大
的”,“更接近現實問題”的邏輯層上去,再由這個邏輯層到最終的類實現路徑(比如單例模式,就是指代
設計中只能出現一個實例的邏輯實體,這已經十分接近設計了)
如果這個層面被提出來,它甚至不占用到運行的時間,,即增加這項抽象,并不耗費運期間任何成本(因
為它只發生在編譯期)
因此它是語法導向的,而不是虛擬函數集導向的
編程新手真言 - GameRes.com 頁碼,15/101
mhtml:file://F:\Cpp\編程新手真言.mht 2008-7-30
這個整合層就是策略,,,模板技術允許我們在編譯期就用“策略組合”加“模板技術”來生成源程序,
這實際上也是編寫庫為用戶所用時所要考慮到的問題
用戶希望能從庫中提取功能的子集,這勢必產生
這里提到一個trait的概念,簡單描述一下先
這就是元語言,
問題域永遠是多元的,因此需要元語言,數據格式是多樣的,因此會有表示數據的通用方法 XML,一般用
XML格式的metadata來封裝其它格式(即:不可能把所有格式的數據包括二進制啊,PE啊,,TXT啊都做
成XML,但我們可以把這些數據格式放進一個XML的字段內,XML就成了一種通用的數據打包形式并用它
用于進行統一數據交換過程,然后在使用時從這些這段中取出各個格式的數據再解碼成所需的格式,W3C
組織正在策起一個關于XML二進制格式的方案)
?? 真正的多范型設計
編程主要涉及三個主體,,,現實世界(方案領域),,,,編程工具也即通用的表達現實抽象的工具(應
用領域)范型就是編程界(編程界的范型都基于計算機這個底層實現)對設計(設計都源于人腦對現實世界的
模擬和用計算機來表達它的需求)的表達因子
從工程的角度來考慮一個領域里的最高高度就是多范型設計(請注意這還只是設計而非編碼,但是設計中的
某些因素最終要在代碼中最現體現出來-當然并不是設計中的全部中間過程與細節因為設計過程中某些用詞
只是輔助用詞,這“最終在代碼中表現出來”稱為對設計的實作,這實際上也可稱為設計的編碼,然而標準
意義上的編碼是寫最終的應用而不是寫中間邏輯比如庫邏輯)
如何把你的設計代碼化表現呢,用策略是其中之一,策略只是范型之一,當然還可用某種語言的一切范
型,比如C++是一種多范型的語言,范型就是問題域對于方案域(schma)的具體解法這種統用說法,即設
計通過范型才能在代碼中體現,我們所有的編程工作就是利用語言級或非語言級的編程界范型(比如二進制
的復用IDL等,這通常是部署設計)去實現問題。(因此要學習語言的范型和對問題的語言范型實現)
進行原語設計時可以不考慮范型(因為此時的原語設計不是面向編碼的),但是當用范型來實現時,就是面
向編碼的工作,此時要考慮設計中的哪些部分(去掉思想過程中的輔助過程,即那些不需在代碼級表達出來
的細節或用詞)用哪種范型來表達比較合適。
原語設計與多范型設計有著不同的出發點(這是區別),但是它們的聯系才是主要的,原語設計的出發點
是現實世界,最終的目的是為了提出一種構架,,,這種構架可以為未來擴展提供足夠余地接口(這是思想
級的接口并不實際是我們常說的“面向接口編程”的接口,這里這里的設計跟編程沒有多大關系,多范型設
計中的設計擴展接口才慢慢跟編程和計算機走到一起),多范型設計的出發點是計算機的范型,,最終目的
是產生源碼文件,并體現原語設計時提出的思想架構(這句話才是重點,這里再次重申,原語設計的架構僅
僅是按人類的思考來定義的架構并不是以范型的觀點來看待的),但是二者是統一的(這是聯系),只要思想
上科學的架構,當它被多范型用計算機的眼光被體現出來時,多范型因此沒道理不會具有當初思想級架構
所具有的擴展余地(或可復用余地),也即它們是統一的,,然而,最終的擴展瓶頸是由范型設計所決定的,
即接口余地=范型設計最大擴展余地=范型設計擴展余地+原語設計擴展余地。
為什么需要明白以上這些呢?明白以上這些,將極大地使程序員不滿足借用編程界現有的設計,而是創立
自己的設計方案并實現它(有意識的行動比沒有意識的行動有效得多,而有上述思想作為指導是必要的,而
如果連自身的問題都沒有找準根本就不行)
編程新手真言 - GameRes.com 頁碼,16/101
mhtml:file://F:\Cpp\編程新手真言.mht 2008-7-30
你可能在問,明白這些思想的東東有什么用?然而你如果真不明白這些思想級的障礙,那么代碼級的障礙
你也許根本過不去,一個直接的例子就是,在看到一些技術文章的時候就會碰到這些用詞時會用上
問題領域總可以分成它的子領域,,子領域又可分為它的子子領域,每個領域都可用一些范型來表示,對
每個問題域的每個中間抽象層次都要考慮擴展和可復用(而且是在設計期就考慮),或者每個領域各用一
種范型,或者
C++本身就是一種提供了多范型的語言(注意除了它的OO機制范型以外,它的模板啊,指針和引用啊,
虛函數啊,GP啊都是其它意義上的范型)
對多范型的考慮要充分考慮復用,因此必定要考慮到二個原則:找到方案領域的變化與,不變點,不變點
可以做到基層(高層抽象,,,并不一定要用繼承這種范型來實現,因為面向對象這種范型只是多范型的一
個子集而已),而在多范型的眼里,任何領域工程都不只通過一種范型來解決(比如的面向對象,比如某一
種語言的面向對象),,因此它可稱為metadesign,,注意,它是設計metaprogram是關于語言的語言,是
語言之上的更高一級抽象,
分析過程往往
往往
找出事物的不變點與變化點這是多范型里面常常提到的二個詞,這二個詞反映了什么事實呢?
在“設計與策略”一節的開頭有講解
?? 真正的xp編程
即使你通過閱讀和實踐的手段獲得了足以編制任何軟件的知識,你還是需要(當然并非必要)一種實在的
方法學來更為有成效地建一個應用,,,敏捷開發就是這樣一種方法(Rose公司的UPS,統一開發過程也
是一種軟件開發的工程學),敏捷方法學指出了很多原則(只是指出這些原則,,并沒有相關的理論,也
即,XP編程實際上與其說是方法論,不如說是一組具體的實踐實體),比如它要求重構的時候,要注意二
個重要的問題那就是測試和結對編程
這二個要求幾乎是XP編程的精髓.
不要把重構的意思跟重載弄混了,,,重構refracting是重新構成,,,是復用和增加新功能(在不改變向
外的接口和表現的同時在其內部進行代碼級的改進)的代名詞,,我們常說重構一個應用,,就是說如何
重新應用現有的代碼或框架
重構又跟單元測試有關(這個主題本身都可以自成一書,是極限編程學里的內容),,又跟極限編程有
關,,,OMG
實際上一個XP編程提倡的測試就是增量開發的意思,你可以向你的代碼增加一個類,然后寫一個使用這個
類的框架,,如果測試通過,這個類就可以跟整個代碼協調一起工作,所以可以通過這種方式為代碼不斷
提供新的功能。。
先寫測試用例,再寫實際代碼,(這個順序很奇怪吧)這些測試用例都能通過的時候,代碼在這個迭代周期
就算完成了,
一些最最低層的API就可以定義出一個大型程序(我們稱這些核心API為算法API,它們屬于真正的實現部
編程新手真言 - GameRes.com 頁碼,17/101
mhtml:file://F:\Cpp\編程新手真言.mht 2008-7-30
分),,因為我們可作基于這些api之上的無盡抽象,,,(即定義這些核心API如何被使用,如何被更好地
滿足復用地使用,如何簡化而又合理地使用,,簡言之,這些抽象就是接口,,)
我們常常把行為(更準確來說僅僅是行為的聲明形式,要注意,一個函數的原型(也即簽名)和它的具體實現是
分開的)作為接口,而不把數據放進接口,這是因為數據是實現部分,不應該被加進一個接口
重載是定義一個行為的同名的多種變形形式,這些變形接受不同的函數簽名,,,但共用一個函數名(也即
接口只規定函數聲明形式,,只不寫出它們的實現,由實現它的子類來寫出實現)
上面不說繼承而說實現它的子類,,是因為,接口(或抽象基類)一般是用來實現的,而一般基類是用來繼
承的
OO本身就帶有對重載的支持,因為OO的低層實現是一種被稱為RTTI的對象內存模型機制,一個定義了虛
函數的類應該存在對這個函數重載的需要,,否則就不要定義虛函數
在構件中,,queryinterface()也是一種構件多態的手段
指針也可以辦到不需要OO就能重載的目的
?? 真正的調試
調試幾乎是與設計,與實際編碼地址相等的過程,,一個軟件花在調試和維護上的時間幾乎比實際編碼的時
間還要長(重構級的調試)
所以,千萬不要以為調試只是一種與編譯器打交道的活,實際上,它是軟件工程學(特別是方法學)中一
個很重要的部分,初期的調試就是Assert,軟工里面的調試還包括寫Log,寫專門的測試案例(這樣的測試可
以稱為事前調試,設計級的調試-希望這個詞是我第一次用)
先來介紹一些高級編譯技術
1.stlport在include路徑里置前,因為VC6的舊的SDK里帶有同名的文件
2.dx8置dx9前,并且置頂,因為需要一個dxinput8.h的文件
3.cpp文件和inc文件到底有什么區別?本質上在h和cpp里都可寫代碼實現,然而h里面的代碼經常是一些
inline,define之類的代碼,因為它們要被其它文件包含
4.編譯頭可加快編譯速度
5.編譯大型庫時,注意條件編譯,可選部分按需略掉
6.不需要inc的一個方法是用路徑號./,,少用\
7.可在link選項卡里加路徑
8.disable warning stl
9.直接把.lib加進工程
10.macro redine錯誤時用_下標
11.#include 的<>符號是優先在環境變量中查找,而“”是當前相對路徑中查找
12.用VS9中的VS8來編譯庫
下面介紹一下大型開源庫的編譯技術,,比如Yake的編譯
編程新手真言 - GameRes.com 頁碼,18/101
mhtml:file://F:\Cpp\編程新手真言.mht 2008-7-30
領域數學與算法
數學不但是算法和解決一切領域問題的基礎,別忘了,計算機本來就是一個離散結構!
宜結合數據結構閱讀本節!它與OO的結合點就是利用了ADT的算法!
?? 真正的邏輯
P∨q 為命題p和q的析取,是p和q用邏輯連接符’或’連接的結果
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -