Re: [問題] 重構的技巧
※ 引述《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)
推
02/04 03:27, , 1F
02/04 03:27, 1F
推
02/04 12:55, , 2F
02/04 12:55, 2F
→
02/04 13:13, , 3F
02/04 13:13, 3F
→
02/04 14:05, , 4F
02/04 14:05, 4F
推
02/04 16:41, , 5F
02/04 16:41, 5F
推
02/04 17:17, , 6F
02/04 17:17, 6F
推
02/04 19:24, , 7F
02/04 19:24, 7F
→
02/04 19:29, , 8F
02/04 19:29, 8F
→
02/04 20:13, , 9F
02/04 20:13, 9F
→
02/06 16:58, , 10F
02/06 16:58, 10F
→
02/06 16:58, , 11F
02/06 16:58, 11F
討論串 (同標題文章)