1.Rename Method : 取個更合適的函式名
2.Add Parameter : 增加參數
3.Remove Parameter : 減少參數
4.Separate Query from Modifier : 將會回傳與會修改物件內部狀態的函式分開
5.Parameterize Method : 讓函式帶參數
6.Replace Parameter with Explicit Method : 以明確函式取代參數
7.Preserve Whole Object : 保持物件的完整
8.Replace Parameter with Method : 以函式取代參數
9.Introduce Parameter Object : 使用參數物件
10.Remove Setting Method : 去除不希望改變值的field的設值函式
11.Hide Method : 把不被其它class使用的method設為private或移除
12.Replace Constructor with Factory Method : 以Create method取代建構式
13.Encapsulate Downcast : 封裝向下轉型
14.Replace Error Code with Exception : 以錯誤碼來表示某些錯誤(異常)
15.Replace Exception with Test : 以測試取代異常
2006年11月30日 星期四
2006年11月28日 星期二
[重構]條件式的重構
1.Decompose Conditional : 分解條件式
2.Consolidate Condition Expression : 合併條件式
3.Consolidate Duplicate Conditional Fragments : 合併重複的條件片段
4.Remove Control Flag : 移去控制用的變數
5.Replace Nested Conditional with Guard Clauses : 以衛述句取代巢狀條件式
6.Replace Conditional with Polymorphism : 以多型取代條件式
7.Introduce Null Object : 使用NULL物件
8.Introduce Assertion : 使用Assertion
2.Consolidate Condition Expression : 合併條件式
3.Consolidate Duplicate Conditional Fragments : 合併重複的條件片段
4.Remove Control Flag : 移去控制用的變數
5.Replace Nested Conditional with Guard Clauses : 以衛述句取代巢狀條件式
6.Replace Conditional with Polymorphism : 以多型取代條件式
7.Introduce Null Object : 使用NULL物件
8.Introduce Assertion : 使用Assertion
2006年11月27日 星期一
[重構]物件內資料成員的重構
1.Self Encapsulate Field : 自我封裝欄位 (為field提供get/set moethod)
2.Replace Data Value with Object : 以物件取代資料
3.Change Value to Reference : 將實值物件改為參考物件
4.Change Reference to Value : 將參考物件改為實值物件
5.Replace Array with Object : 以物件取代陣列
6.Duplicate Observed Data : 將資料copy到domain object中,並以Observer pattern作同步控制
7.Change Unidirectionl Association to Bidirectionl : 將物件的單向關聯改為雙向關聯
8.Change Bidirectionl Association to Unidirectionl : 將物件的雙向關聯改為單向關聯
9.Replace Magic Number with Symbolic Constant : 以符號取代魔數
10.Encapsulate Field : 封裝欄位 (儘量不提供public field)
11.Encapsulate Collection : 封裝群集
12.Replace Recode with Data Class : 以資料類別取代記錄
13.Replace Type Code with Class : 以類別取代型別
14.Replace Type Code with Subclass : 以子類別取代型別
15.Replace Type Code with State/Strategy : 以State/Strategy取代型別
16.Replace Subclass with Field : 以欄位取代子類別
2.Replace Data Value with Object : 以物件取代資料
3.Change Value to Reference : 將實值物件改為參考物件
4.Change Reference to Value : 將參考物件改為實值物件
5.Replace Array with Object : 以物件取代陣列
6.Duplicate Observed Data : 將資料copy到domain object中,並以Observer pattern作同步控制
7.Change Unidirectionl Association to Bidirectionl : 將物件的單向關聯改為雙向關聯
8.Change Bidirectionl Association to Unidirectionl : 將物件的雙向關聯改為單向關聯
9.Replace Magic Number with Symbolic Constant : 以符號取代魔數
10.Encapsulate Field : 封裝欄位 (儘量不提供public field)
11.Encapsulate Collection : 封裝群集
12.Replace Recode with Data Class : 以資料類別取代記錄
13.Replace Type Code with Class : 以類別取代型別
14.Replace Type Code with Subclass : 以子類別取代型別
15.Replace Type Code with State/Strategy : 以State/Strategy取代型別
16.Replace Subclass with Field : 以欄位取代子類別
[重構]在物件之間的重構
1.Move Method : 將函式搬到它適合的位置
2.Move Field : 將資料搬到它適合的位置
3.Extract Class : 將一個功能太多的class,提練為多個class
4.Inline Class : 將功能過小的Class,合併為一個
5.Hide Delegate : 在server端建立client所需要的函式,用以隱藏delegation
6.Remove Middle Man : 移除過多的簡單 delegation
7.Introduce Foreign Method : 加入外來的函式
8.Introduce Local Extention : 加入區域性擴展
2.Move Field : 將資料搬到它適合的位置
3.Extract Class : 將一個功能太多的class,提練為多個class
4.Inline Class : 將功能過小的Class,合併為一個
5.Hide Delegate : 在server端建立client所需要的函式,用以隱藏delegation
6.Remove Middle Man : 移除過多的簡單 delegation
7.Introduce Foreign Method : 加入外來的函式
8.Introduce Local Extention : 加入區域性擴展
2006年11月22日 星期三
Serial port programming in Unix/Linux
最近有機會接觸了serial port programming(另外還有Video for Linux API,socket programming等等), 由於平台是Linux,所以有機會比較深入地去接觸kernel,發覺Linux真是個很漂亮的系統(當然不是指各套件預裝User Interface :P ),在欣賞這個精湛的設計時,也期許未來能夠參許這樣的藝術工作.
以下整理了一些serial programming常用的功能:
1.標頭檔,是在寫serial port programming時常用的,為了簡化版面,我就不細說每個標頭檔是那些函式會到了
2.開啟/關閉serial port
3.設定control options
4.常用的組合
5.設定hardware flow control
6.讀寫
以下整理了一些serial programming常用的功能:
1.標頭檔,是在寫serial port programming時常用的,為了簡化版面,我就不細說每個標頭檔是那些函式會到了
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
2.開啟/關閉serial port
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{//Could not open the port.
}
elsefcntl(fd, F_SETFL, 0);
close(fd) ;
3.設定control options
struct termios options;
//Get the current options for the port...
tcgetattr(fd, &options);
//Set the baud rates to 19200...
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
//Enable the receiver and set local mode
options.c_cflag |= (CLOCAL | CREAD);
//Set the new options for the port
tcsetattr(fd, TCSANOW, &options);
4.常用的組合
- No parity (8N1):
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
- Even parity (7E1):
options.c_cflag |= PARENB ;
options.c_cflag &= ~PARODD ;
options.c_cflag &= ~CSTOP ;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS7;
- Odd parity (7O1):
options.c_cflag |= PARENB ;
options.c_cflag |= PARODD ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS7;
- Space parity is setup the same as no parity (7S1):
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
5.設定hardware flow control
options.c_cflag |= CNEW_RTSCTS; /* Also called CRTSCTS */
或是 options.c_cflag &= ~CNEW_RTSCTS;
6.讀寫
直接用 read() , write()就好了
2006年11月21日 星期二
[重構]函式(method)的重構
1.Extract Method:把一段程式碼獨立出來,另外成為一個函式
2.Inline Method:將函式展開其它函式(合併)
3.Inline Temp:對於只用一次的暫存變數,把所有引用此變數的動作,替換成對它賦值的運算式本身
4.Replace Temp with Query:把暫存變數所存放的運算式結果,提煉成一獨立函式
5.Introdce Explaining Variable:把複雜的運算式的結果放進一暫存變數,並以變數名解釋其用途
6.Split Temporary Variable:不將一個暫存區域變數,用於多個功能
7.Remove Assignments to Parameters:不更改參數值(以一暫存變數複製之)
8.Replace Method with Method Object:將函式放入一物件,區域變數為其data field
9.Substitute Algorithm:將某個演算法替換成另一個更清晰的演算法
2.Inline Method:將函式展開其它函式(合併)
3.Inline Temp:對於只用一次的暫存變數,把所有引用此變數的動作,替換成對它賦值的運算式本身
4.Replace Temp with Query:把暫存變數所存放的運算式結果,提煉成一獨立函式
5.Introdce Explaining Variable:把複雜的運算式的結果放進一暫存變數,並以變數名解釋其用途
6.Split Temporary Variable:不將一個暫存區域變數,用於多個功能
7.Remove Assignments to Parameters:不更改參數值(以一暫存變數複製之)
8.Replace Method with Method Object:將函式放入一物件,區域變數為其data field
9.Substitute Algorithm:將某個演算法替換成另一個更清晰的演算法
2006年11月17日 星期五
[重構]bad smells in code
If it strikes,change it!
以下是一些需要被重構的code,若你的程式碼出現在下列的某幾種現象時,請改善它
1.Duplicated Code : 重覆的程式碼
2.Long Method : 太長的函式
3.Large Class : 過大的類別
4.Long Parameter List : 太長的參數列
5.Divergent Change : 發散式變化 (一個class受多種變化的影響)
6.Shotgun Surgery : 霰彈式修改 (一種變化會引發多個class的修改)
7.Feature Envy : 依戀情結 (函式對於某個class的存取,高過於自己的host class)
8.Data Clumps : 資料泥團 (某些資料總是綁在一起並,一起出現在多個地方)
9.Primitive Obsession : 基本型別偏執 (將幾個俱相關的基本型別合併成一個小物件)
10.Switch Statement : (少用switch句型)
11.Parallel Inheritance Hierarchies : 平行繼承體系 (不同繼承體系中存在著相同的class)
12.Lazy Class : 冗員類別 (除去沒有必要的class)
13.Speculative Generality : 非必要地談未來性 (除去非必要的hook)
14.Temporary Field : 暫存欄位 (除去class中,暫存用的欄位)
15.Message Chains : 過度耦合的訊息鏈 (連續向不同的函式要求不同的物件)
16.Middle Man : 中間人 (除去一些不做實事的函式)
17.Inappropriate : 狎暱關係 (兩個class花太多時間去用對方的private成員)
18.Alternative Classes with Different Interfaces : 異曲同工的類別 (兩個不同函式卻做一樣的事)
19.Incomplete Library Class : 不完備的函式庫 (想修改library部分功能時)
20.Data Class : 純稚的資料類別 (封裝好data class)
21.Refused Bequest : 被拒絕的遺贈 (當subclass 不希望或不需要得到superclass的功能)
22.Comments : 過多的註解 (試著讓註解變得多餘)
當你感覺需要撰寫註解時,請先嘗試重構,試著所有註解都變成多餘的 :)
以下是一些需要被重構的code,若你的程式碼出現在下列的某幾種現象時,請改善它
1.Duplicated Code : 重覆的程式碼
2.Long Method : 太長的函式
3.Large Class : 過大的類別
4.Long Parameter List : 太長的參數列
5.Divergent Change : 發散式變化 (一個class受多種變化的影響)
6.Shotgun Surgery : 霰彈式修改 (一種變化會引發多個class的修改)
7.Feature Envy : 依戀情結 (函式對於某個class的存取,高過於自己的host class)
8.Data Clumps : 資料泥團 (某些資料總是綁在一起並,一起出現在多個地方)
9.Primitive Obsession : 基本型別偏執 (將幾個俱相關的基本型別合併成一個小物件)
10.Switch Statement : (少用switch句型)
11.Parallel Inheritance Hierarchies : 平行繼承體系 (不同繼承體系中存在著相同的class)
12.Lazy Class : 冗員類別 (除去沒有必要的class)
13.Speculative Generality : 非必要地談未來性 (除去非必要的hook)
14.Temporary Field : 暫存欄位 (除去class中,暫存用的欄位)
15.Message Chains : 過度耦合的訊息鏈 (連續向不同的函式要求不同的物件)
16.Middle Man : 中間人 (除去一些不做實事的函式)
17.Inappropriate : 狎暱關係 (兩個class花太多時間去用對方的private成員)
18.Alternative Classes with Different Interfaces : 異曲同工的類別 (兩個不同函式卻做一樣的事)
19.Incomplete Library Class : 不完備的函式庫 (想修改library部分功能時)
20.Data Class : 純稚的資料類別 (封裝好data class)
21.Refused Bequest : 被拒絕的遺贈 (當subclass 不希望或不需要得到superclass的功能)
22.Comments : 過多的註解 (試著讓註解變得多餘)
當你感覺需要撰寫註解時,請先嘗試重構,試著所有註解都變成多餘的 :)
[重構]重構的時機
Don Robert所提出的準則: 事不過三,三則重構 (three strikes and you refactor)
這句話的意思是說,某件事第一次做時就直接去作,第二次做時也許會覺得很麻煩,第三次做的時候,就代表需要重構了.
其它重構的時機有
1.要加入新功能的時候
2.要修改bug的時候
3.在復審(review)程式碼的時候
而何時不該重構呢?就是你的code己經亂到幾乎要重寫的地步,那麼就不用浪貴那麼多的時間了. :)
這句話的意思是說,某件事第一次做時就直接去作,第二次做時也許會覺得很麻煩,第三次做的時候,就代表需要重構了.
其它重構的時機有
1.要加入新功能的時候
2.要修改bug的時候
3.在復審(review)程式碼的時候
而何時不該重構呢?就是你的code己經亂到幾乎要重寫的地步,那麼就不用浪貴那麼多的時間了. :)
trace程式碼的好工具 kscope
以往寫windows程式時,看程式碼都是用像是VisualC++這類的IDE,但是到了Linux底下,就一直找不到好用的工具,以前有試著用過anjuta跟eclipse,可是這些都不是好的trace工具,我覺得好的trace工具,一定要有對語法分析並標色的功能,對不同檔案用不同tag顯示,最好還能夠對變數能夠有快速參照並可以很快的找到定義的地方,這些kscope都滿足了!
http://kscope.sourceforge.net/
http://kscope.sourceforge.net/

2006年11月16日 星期四
Refactoring 重構
「任何一個傻瓜都能寫出計算機可以理解的程式碼,唯有寫出人類容易理解的程式碼,才是優秀的程式員.」
這是兩年前吸引我去閱讀Refactoring(重構)的一句話,就名詞定義上而言,重構是一種對軟體內部的調整,在不改變外在行為的原則下,提高程式碼的可讀性,以及降低成本,提昇效能.
這是兩年前吸引我去閱讀Refactoring(重構)的一句話,就名詞定義上而言,重構是一種對軟體內部的調整,在不改變外在行為的原則下,提高程式碼的可讀性,以及降低成本,提昇效能.
2006年11月14日 星期二
[ubuntu]製作iso檔
將光碟機的內容製成iso檔
$dd if=/dev/cdrom of=image.iso
將is掛載到檔案系統
$mkdir /mnt/iso
$mount -o loop,ro -t iso9660 ./image.iso /mnt/iso
$dd if=/dev/cdrom of=image.iso
將is掛載到檔案系統
$mkdir /mnt/iso
$mount -o loop,ro -t iso9660 ./image.iso /mnt/iso
2006年11月13日 星期一
2006年11月10日 星期五
[note] socket programming中AF_INET與PF_INET的不同
在最初的定義上,AF_INET是Address Family的,而PF_INET是protocol family,兩者在網路架構上層級不同.其中protocol較為低層,像是TCP/IP,而Address較為高層,在TCP/IP中有IPv4與IPv6兩種不同的協定,因為現今的網路只使用IPv4,故兩者通常定為一樣的值,用久了,大家都混著用了,若程式只是要在IPv4上work的話,那麼使用兩種都可以,但若是要支援不同的Address Family的話,就必須使用PF_INET了.
[note]移除不必要的service
用 ps ax 可以知道目機有那些會使用I/O port的行程在跑,可以的話,盡量讓這些程式減少到一頁,同時也要注意inetd或xinetd有沒有代理那些service,
//檢查inetd中有那些service
$ grep -v "^#" /etc/inetd.conf
//關 service
#/etc/init.d/some_service stop
// 列出正在listen的程式
#netstat -lp
//檢查inetd中有那些service
$ grep -v "^#" /etc/inetd.conf
//關 service
#/etc/init.d/some_service stop
// 列出正在listen的程式
#netstat -lp
訂閱:
文章 (Atom)