第7回社内勉強会「code sucks - 人の振り見て我が振り直せ」

29
Code sucks 人人人人人人 人人人人人人 第 7 第第第第第第

Upload: hiromu-shioya

Post on 24-May-2015

1.355 views

Category:

Documents


0 download

DESCRIPTION

世間や社内で見かけた困ったコードをdisることでコードレビューの必要性をアピールする

TRANSCRIPT

Page 1: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

Code sucks人の振り見て我が振り直せ

第 7 回社内勉強会

Page 2: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

テーマ巷にあふれる困ったコードを晒して dis る

身に覚えがあったら反省する

自信をつける

Page 3: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

お約束 自分のコードが出てきたら

一緒に笑う こっそり反省する 次から気をつける

異論があったら ガンガンツッコむ

他にも suck なコードを見つけたら 社内 wiki に投稿する

Page 4: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

その1

終わらない二月、永遠の閏年

Page 5: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

月の最終日を取得したいらしい// 検索月の末日を取得switch( $s_month ) {case 2: $last_day = 28; if ( ( $year % 4 ) == 0 ) { $last_day = 29; } break;

Page 6: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

閏年 (via Wikipedia)http://ja.wikipedia.org/wiki/%E9%96%8F%E5%B9%B4

グレゴリオ暦( 略 )次の規則に従って 400 年に 97 回の閏年が設けられる。 ( 略 )

1. 西暦年が 4 で割り切れる年は閏年 2. ただし、西暦年が 100 で割り切れる年は平年 3. ただし、西暦年が 400 で割り切れる年は閏年

Page 7: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

ポイントをもう一度1. 西暦年が

4 で割り切れる年は閏年2. ただし、西暦年が

100 で割り切れる年は平年3. ただし、西暦年が

400 で割り切れる年は閏年

Page 8: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コードをもう一度// 検索月の末日を取得switch( $s_month ) {case 2: $last_day = 28; if ( ( $year % 4 ) == 0 ) { $last_day = 29; } break;

Page 9: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コンピュータシステムと閏年コンピュータシステムにおいて閏年を判定するアルゴリズムの記述には問題がある場合が多く、しばしばこれが原因でシステムは重大な障害を起こす。これは例えば、「 4 で割り切れる年」としかしていなかったり year==2000||year==2004のようにある程度先の閏年しかコードしていないなどが挙げられる。

Page 10: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

二段オチ$today = time();$s_year = date( "Y", $today);$s_month = date( "m", $today);$s_day = 1;$e_year = date( "Y", $today);$e_month = date( "m", $today);// 検索月の末日を取得switch( $s_month ) {case 2: $last_day = 28; if ( ( $year % 4 ) == 0 ) { $last_day = 29; } break;}

$ php -r "var_dump($year) ; "NULL

$ php -r "echo NULL % 4 ; "0

  ↓毎年閏年になるじゃん

Page 11: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

正解は

$last_day = date("t") ;

http://jp2.php.net/manual/ja/function.date.php

Page 12: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

その2

あなたが見ている世界は

ほんものか?

Page 13: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

こんなリストがありました よくある商品リスト Web に表示したい

Page 14: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

ソースをチェックしてみた$column_names = array(

'商品名 ','商品種別 ','重量 ','備考 ',

) ;

イヤな予感!!

Page 15: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

テーブルをチェックしてみたmysql> describe item_master ;

+--------------+---------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+---------+------+-----+---------+-------+| item_id | int(11) | NO | | NULL | || column_type | int(11) | NO | | NULL | || column_value | text | YES | | NULL | |+--------------+---------+------+-----+---------+-------+

  _, ._(;゚ Д ゚)

Page 16: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

データをチェックしてみたmysql> SELECT * FROM item_master ;

(  ゚ д ゚ )

( つ д⊂) ゴシゴシ

( ;゚ д ゚ )

( つ д⊂) ゴシゴシ   _, ._(;゚ Д ゚) …? !

( つ д⊂) ゴシゴシゴシゴシゴシ

( ;  Д   ) !!

Page 17: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

まあ落ち着け カラムの追加に強い、という

メリットがあるかもしれないじゃないか プライマリキーに縛られないので、

データスキーマに自由があるじゃないか なにかオトナの理由で、正規化できない

事情があったのかもしれないじゃないか

Page 18: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

ロジックをチェックしてみた// $resultには表示対象の商品コードが入っているwhile ($data = mysql_fetch_array($result)){ for ($i = 0 ; $i < count($column_names) ; $i ++) { $sql = "SELECT * FROM item_master" . " WHERE item_id = {$data['item_id']}" . " AND column_type = {$i}" ; $ret = mysql_query($sql) ; $item = mysql_fetch_array($ret) ;

echo "<td>{$column_names[$item['column_type']]}</td>\n" ; echo "<td>{$item['column_value']}</td>\n" ; }}

Page 19: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

正解は

正規化しようhttp://www.kogures.com/hitoshi/webtext/db-seikika/index.html

Page 20: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

補足 あえて正規化しない、という選択肢

トランザクションロックの範囲を小さくする どっちにしても「正規化してから」非正規化を検討

重複項目も同様 「計算で出る要素」「他のテーブルにある要素」を

あえて持つ 処理速度と記憶容量、保守性のトレードオフ

データベースは奥が深いね! 技術者に敬意を

Page 21: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

その3

できるだけコネタです

Page 22: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コネタその1if( $order == _SER_ORDER_LAST_ ) { // 前日閲覧数順} elseif( $order == _SER_ORDER_NEW_ ) { // 新着順} elseif( $order == _SER_ORDER_FAV_ ) { // 登録数順} else { // 更新順}

switch – case を使え!!

Page 23: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コネタその2// $iRecCnt(レコード数 )が1以外なら// 不正アクセスらしい。

if($iRecCnt>1){ $strAttentMessage = "不正なアクセスです。 ";}if($iRecCnt==0){ $strAttentMessage = "不正なアクセスです。 ";}

$iRecCnt != 1じゃ

ダメなの?

Page 24: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コネタその3// 取ってきたレコードを変数展開したいらしい。$sorter = $aRecData[0][c_sorter];$page_title = $aRecData[0][c_page_title];$page_content = $aRecData[0][c_page_content];$mailflg = $aRecData[0][c_mail];$signflg = $aRecData[0][c_sign];$backlink = $aRecData[0][c_backlink];$name = $aRecData[0][tname];$cl_bg = $aRecData[0][color_bg];$cl_text = $aRecData[0][color_text];$cl_link = $aRecData[0][color_link];$cl_vlink = $aRecData[0][color_vlink];$cl_hr = $aRecData[0][color_hr];$cl_title = $aRecData[0][color_title];

extract($aRecData[0]) ;

じゃダメなの?

Page 25: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コネタその4 (1/3)// なんだかいろんなコネクションがある。// INSERT祭りが始まるようだ。

$conn->begin_trans();$conn_sub->begin_trans();$conn_s->begin_trans();$conn_msg->begin_trans();$conn_ad->begin_trans();$conn_foo->begin_trans() ;$conn_bar->begin_trans() ;

Page 26: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コネタその4 (2/3)// ちょっと行数が多くて心が折れそうだが、// 処理にしくじったらロールバックさせたいようだ。if(!$conn->execute($strQue)) { $conn->rollback(); $conn_sub->rollback(); $conn_s->rollback(); $conn_msg->rollback(); $conn_ad->rollback(); $conn_foo->rollback() ; $conn_bar->rollback() ; db_regist_error($conn);}

Page 27: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

コネタその4 (3/3) 一連の処理でロールバックしている箇所を

数えてみた。$ grep \$conn-\>rollback hoge.php | wc -l

29全部、手で

保守する気?

Page 28: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

まとめ 人の振り見て我が振り直せ

あなたのコードもどこかで dis られてる…かも。

恐れる必要はない 勇気とは恐怖を克服すること

具体的には… たくさん書こう 人に見せよう

レビュー重要 今回は「 dis る」という形式だった 次回は「ライブレビュー」を予定

「にこにこ力」「ほめ力」「自画自賛力」重要

Page 29: 第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」

おしまい

ご清聴ありがとうございました