第7回社内勉強会「Code Sucks - 人の振り見て我が振り直せ」
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

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

  • 2,089 views
Uploaded on

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

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

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,089
On Slideshare
1,958
From Embeds
131
Number of Embeds
3

Actions

Shares
Downloads
1
Comments
0
Likes
1

Embeds 131

http://kwappa.txt-nifty.com 74
http://randd.kwappa.net 56
http://www.slideshare.net 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Code sucks 人の振り見て 我が振り直せ 第7回社内勉強会
  • 2. テーマ
    • 巷にあふれる困ったコードを 晒して dis る
    • 身に覚えがあったら 反省する
    • 自信をつける
  • 3. お約束
    • 自分のコードが出てきたら
      • 一緒に笑う
      • こっそり反省する
      • 次から気をつける
    • 異論があったら
      • ガンガンツッコむ
    • 他にもsuckなコードを見つけたら
      • 社内wikiに投稿する
  • 4. その1
    • 終わらない二月、
    • 永遠の閏年
  • 5. 月の最終日を取得したいらしい // 検索月の末日を取得 switch( $s_month ) { case 2: $last_day = 28; if ( ( $year % 4 ) == 0 ) { $last_day = 29; } break;
  • 6. 閏年(via Wikipedia)
    • http://ja.wikipedia.org/wiki/%E9%96%8F%E5%B9%B4
    • グレゴリオ暦
    • ( 略 )
    • 次の規則に従って 400 年に 97 回の閏年が設けられる。 ( 略 )
    • 1. 西暦年が 4 で割り切れる年は閏年
    • 2. ただし、西暦年が 100 で割り切れる年は平年
    • 3. ただし、西暦年が 400 で割り切れる年は閏年
  • 7. ポイントをもう一度
    • 西暦年が 4 で割り切れる年は閏年
    • ただし、西暦年が 100 で割り切れる年は平年
    • ただし、西暦年が 400 で割り切れる年は閏年
  • 8. コードをもう一度 // 検索月の末日を取得 switch( $s_month ) { case 2: $last_day = 28; if ( ( $year % 4 ) == 0 ) { $last_day = 29; } break;
  • 9. コンピュータシステムと閏年
    • コンピュータシステムにおいて閏年を判定する アルゴリズムの記述には問題 がある場合が多く、しばしばこれが原因で システムは重大な障害 を起こす。
    • これは例えば、 「 4 で割り切れる年」 としかしていなかったり year==2000||year==2004 のようにある程度先の閏年しかコードしていないなどが挙げられる。
  • 10. 二段オチ $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   ↓ 毎年閏年になるじゃん
  • 11. 正解は $last_day = date("t") ; http://jp2.php.net/manual/ja/function.date.php
  • 12. その2
    • あなたが見ている
    • 世界は
    • ほんものか?
  • 13. こんなリストがありました
    • よくある商品リスト
    • Web に表示したい
  • 14. ソースをチェックしてみた $column_names = array( ' 商品名 ', ' 商品種別 ', ' 重量 ', ' 備考 ', ) ; イヤな予感!!
  • 15. テーブルをチェックしてみた 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 | | +--------------+---------+------+-----+---------+-------+    _, ._ (;゚ Д ゚)
  • 16. データをチェックしてみた mysql> SELECT * FROM item_master ; (  ゚ д ゚ ) ( つ д⊂) ゴシゴシ ( ;゚ д ゚ ) ( つ д⊂) ゴシゴシ    _, ._ (;゚ Д ゚) …? ! ( つ д⊂) ゴシゴシゴシゴシゴシ ( ;  Д   ) !!
  • 17. まあ落ち着け
    • カラムの追加に強い、という メリットがあるかもしれないじゃないか
    • プライマリキーに縛られないので、 データスキーマに自由があるじゃないか
    • なにかオトナの理由で、正規化できない 事情があったのかもしれないじゃないか
  • 18. ロジックをチェックしてみた // $result には表示対象の商品コードが入っている while ($data = mysql_fetch_array($result)) { for ($i = 0 ; $i < count($column_names) ; $i ++) { $sql = &quot;SELECT * FROM item_master&quot; . &quot; WHERE item_id = {$data['item_id']}&quot; . &quot; AND column_type = {$i}&quot; ; $ret = mysql_query($sql) ; $item = mysql_fetch_array($ret) ; echo &quot;<td>{$column_names[$item['column_type']]}</td> &quot; ; echo &quot;<td>{$item['column_value']}</td> &quot; ; } }
  • 19. 正解は
    • 正規化しよう
    http://www.kogures.com/hitoshi/webtext/db-seikika/index.html
  • 20. 補足
    • あえて正規化しない、という選択肢
      • トランザクションロックの範囲を小さくする
      • どっちにしても「正規化してから」非正規化を検討
    • 重複項目も同様
      • 「計算で出る要素」「他のテーブルにある要素」を あえて 持つ
        • 処理速度と記憶容量、保守性のトレードオフ
    • データベースは奥が深いね!
      • 技術者に敬意を
  • 21. その3
    • できるだけ コネタです
  • 22. コネタその1 if( $order == _SER_ORDER_LAST_ ) { // 前日閲覧数順 } elseif( $order == _SER_ORDER_NEW_ ) { // 新着順 } elseif( $order == _SER_ORDER_FAV_ ) { // 登録数順 } else { // 更新順 } switch – case を 使え!!
  • 23. コネタその2 // $iRecCnt( レコード数 ) が1以外なら // 不正アクセスらしい。 if($iRecCnt>1){ $strAttentMessage = &quot; 不正なアクセスです。 &quot;; } if($iRecCnt==0){ $strAttentMessage = &quot; 不正なアクセスです。 &quot;; } $iRecCnt != 1 じゃ ダメなの?
  • 24. コネタその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]) ; じゃ ダメなの?
  • 25. コネタその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() ;
  • 26. コネタその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); }
  • 27. コネタその4 (3/3)
    • 一連の処理でロールバックしている箇所を 数えてみた。
    $ grep $conn->rollback hoge.php | wc -l 29 全部、手で 保守する気?
  • 28. まとめ
    • 人の振り見て我が振り直せ
      • あなたのコードもどこかで dis られてる …かも。
    • 恐れる必要はない
      • 勇気とは恐怖を克服すること
        • 具体的には…
          • たくさん書こう
          • 人に見せよう
    • レビュー重要
      • 今回は「 dis る」という形式だった
      • 次回は「ライブレビュー」を予定
        • 「にこにこ力」「ほめ力」「自画自賛力」重要
  • 29. おしまい
    • ご清聴ありがとうございました