作者loveme00835 (高髮箍)
看板C_and_CPP
標題Re: [問題] 重構的技巧
時間Sat Feb 4 03:22:00 2012
※ 引述《tyc5116 (累人啊....)》之銘言:
: 如題,請問一下,類似這樣的程式碼(虛擬碼)
: if (str=="A1"){
: P1.val=1;
: func1(p1.val);
: }
: else if (str=="A2"){
: P1.val=2;
: func2(p1.val)
: }
: else if (str=="A3"){
: P1.val=1;
: P2.val=2;
: P3.val=3;
: }
: ...
: 如上,一段程式就有類似這樣的if else(假設有很多)
: 裡面的描述有的很類似(如前兩個)
: 偶爾又穿插一些不太一樣的code(如第三個)
: 以各位的經驗,通常會以哪些手法對其進行重構呢
以下分享兩種方法:
(1) map<K,V> + function<F> [ + bind ]
(2) function templates
首先是(1), 以註冊的形式加入你想要的程序:
map< string,
function<
void(
void)>
> select_action = { {
"A1", [&](){ P1.val = 1; func1(P1.val); } },
{
"A2", [&](){ P1.val = 2; func2(P1.val); } },
...
};
之後再用 operator[] 選取操作
select_action["A2"]
();
完整程式碼:
http://codepad.org/VqibNVCV
-
再來是(2), 在全特化實作碼裡只需考慮要變動的部分:
template <
uint8_t ID>
void action( P &, std::string
const & );
template <>
void action<1>( P &p, std::string
const &str ) {
if( str ==
"A1" || str ==
"A3" ) {
p.val = 1;
if( str ==
"A1" ) func1(p.val);
}
else if( str ==
"A2" ) {
p.val = 2;
func2(p.val);
}
}
完整程式碼:
http://codepad.org/0gtZoRxR
-
以上分別是 (1)per case (2)per member 的方向去拆解, 在(2)中
也許還要考慮func1()、func2()的呼叫順序, 或者你可以考慮把
case共通部分合併以簡化龐大的switch, 然後把修改資料的權則轉
移得更分散一點...
--
★★★★★★★ * * * ∞ Swweet Dream ∞
███ ███ ███ █▉█ ███ ◢█◣ ▉▉█ ◢◣◢◣ *
█▅█ █▅█ █ *███ █▅█ █▌█ ███* ◥██◤ * *
*▉█▇* █ █ ███ ▉██ █▅◤ ◥█◤* ███ ◥◤ ◢◣◢◣ *
請不要將我從甜蜜的夢中叫醒 ------------ ∮ * * ◥██◤
∮ -------------- 請跟我一起繼續沉醉在愛情之中 ★★★★★★★ ◥◤ψ
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.121.221.213
※ 編輯: loveme00835 來自: 140.121.221.213 (02/04 03:26)
推 james732:板主終於出手了XD 02/04 03:27
推 hateexam:版主超強的!!! 02/04 12:55
→ jakevin:只能推了..... 02/04 13:13
→ diabloevagto:第二個完全看不懂... 02/04 14:05
推 shininglion:第一點 map 那邊的結構不會解讀,第二點看不懂Orz 02/04 16:41
推 littleshan:1. 是 lambda + initializer 都是 C++11 的功能 02/04 17:17
推 shininglion:感謝提供關鍵字, 沒接觸過 lambda expression... 02/04 19:24
→ diabloevagto:lambda好用啊~會上隱 02/04 19:29
→ tyc5116:我兩個都看不懂@@ 02/04 20:13
→ angleevil:我之前寫得就是參考版主第一個方法,只是我gcc只到4.1 02/06 16:58
→ angleevil:無法玩C++11.QQ 而且我也不太懂lambda expression 02/06 16:58