Upgrade to Pro — share decks privately, control downloads, hide ads and more …

わかるコードを書くために

ktr
April 03, 2017

 わかるコードを書くために

ktr

April 03, 2017
Tweet

More Decks by ktr

Other Decks in Technology

Transcript

  1. 2 $ whoami 青木 太郎 Eyes, JAPAN / ヅ大 2

    年目 Groove Coaster STEINS;GATE 色々...
  2. 3 わからないコー ド s = a ( p . h

    ) ; f u n c t i o n a ( b ) { r e t u r n b * 9 0 0 + 4 0 0 0 ; }
  3. 17 18 代表的な表記法 名前 例 アッパー キャメルケー ス(UCC) ExampleString ロー

    ワー キャメルケー ス(LCC) exampleString スネー クケー ス example_string ハンガリアン記法 mExampleString
  4. 19 わりと一般的な命名規則の例 名前 表記 例 クラス UCC class ImageUtil {...}

    変数、 メンバ変数 LCC or スネー クケー ス let imageTitle; 関数、 メソッド LCC function fetchImageTitle() {...} 定数 大文字 + スネー クケー ス const MAX_STRING;
  5. 21 細かな違い i f ( e x a m p

    l e . i s T r u e ) { . . . } e l s e { . . . } i f ( e x a m p l e . i s T r u e ) { . . . } e l s e { . . . } i f ( e x a m p l e . i s T r u e ) { . . . } e l s e { . . . }
  6. 25 EditorConfig プロジェクトでのエディタの設定を共有できる [ * ] c h a r

    s e t = u t f - 8 e n d _ o f _ l i n e = l f t r i m _ t r a i l i n g _ w h i t e s p a c e = t r u e i n d e n t _ s t y l e = s p a c e i n d e n t _ s i z e = 2 [ * . j s ] i n d e n t _ s t y l e = s p a c e i n d e n t _ s i z e = 2 [ M a k e f i l e ] i n d e n t _ s t y l e = t a b i n d e n t _ s i z e = 4
  7. l e t s = a ( p . h

    ) ; f u n c t i o n a ( b ) { r e t u r n b * 9 0 0 + 4 0 0 0 ; } l e t s a l a r y = g e t S a l a r y ( p e r s o n . h o u r s ) ; f u n c t i o n g e t S a l a r y ( h o u r s ) { r e t u r n h o u r s * 9 0 0 + 4 0 0 0 ; }
  8. 28 関数やメソッドの命名パター ンの一例 パター ン プレフィックス 例 getter / setter

    get / set getText(), setText() boolean is, can, has isEmpty() 外部から取得する fetch fetchImageTitle() イベント発生時 on onItemClick()
  9. 29 明確な名前をつける l e t s a l a r

    y = g e t S a l a r y ( p e r s o n . h o u r s ) ; f u n c t i o n g e t S a l a r y ( h o u r s ) { r e t u r n h o u r s * 9 0 0 + 4 0 0 0 ; } l e t s a l a r y = c o m p u t e S a l a r y ( p e r s o n . w o r k e d H o u r s ) ; f u n c t i o n c o m p u t e S a l a r y ( w o r k e d H o u r s ) { r e t u r n w o r k e d H o u r s * 9 0 0 + 4 0 0 0 ; }
  10. 30 ロジックを確認しなくても把握しやすい l e t s a l a r

    y = c o m p u t e S a l a r y ( p e r s o n . w o r k e d H o u r s ) ;
  11. 31 スコー プと命名 スコー プと変数の持つ意味を考える v o i d s

    w a p ( i n t * a , i n t * b ) { i n t t m p ; t m p = * a ; * a = * b ; * b = t m p ; }
  12. 33 ゆとりを持つ < ? p h p / * 認証

    必要 読 込 * / r e q u i r e _ o n c e ( ' t w i t t e r / ' . ' c o n f i g . p h p ' ) ; r e q u i r e _ o n c e ( ' t w i t t e r / ' . ' t w i t t e r o a u t h . p h p ' ) ; s e s s i o n _ s t a r t ( ) ; / / g e t T o k e n . p h p o a u t h _ t o k e n 一致 i f ( $ _ S E S S I O N [ ' o a u t h _ t o k e n ' ] ! = = $ _ R E Q U E S T [ ' o a u t h _ t o k e n ' ] ) { u n s e t ( $ _ S E S S I O N ) ; e c h o ' < a h r e f = " g e t T o k e n . p h p " > t o k e n 不一致< / a > ' ; e x i t ; } / / a c c e s s t o k e n 取得 $ t w = n e w T w i t t e r O A u t h ( C O N S U M E R _ K E Y , C O N S U M E R _ S E C R E T , $ _ S E S S I O N [ ' o a u t h _ t o k e n ' ] , $ _ S E S S I O N [ ' o a u t h _ t o k e n _ s e c r e t ' ] ) ; $ a c c e s s _ t o k e n = $ t w - > g e t A c c e s s T o k e n ( $ _ R E Q U E S T [ ' o a u t h _ v e r i f i e r ' ] ) ; / / T w i t t e r u s e r _ i d + s c r e e n _ n a m e ( 表示名) $ _ S E S S I O N [ ' u s e r _ i d ' ] = $ a c c e s s _ t o k e n [ ' u s e r _ i d ' ] ; $ _ S E S S I O N [ ' s c r e e n _ n a m e ' ] = $ a c c e s s _ t o k e n [ ' s c r e e n _ n a m e ' ] ; i n c l u d e ( ' d b _ c o n n e c t i o n . p h p ' ) ; $ s q l = ' S E L E C T * F R O M u s e r _ d a t a W H E R E u s e r _ i d = ' . $ _ S E S S I O N [ ' u s e r _ i d ' $ q u e r y = m y s q l _ q u e r y ( $ s q l , $ l i n k ) ;
  13. 34 適切な改行とスペー ス < ? p h p / /

    認証 必要 読 込 r e q u i r e _ o n c e ( ' t w i t t e r / ' . ' c o n f i g . p h p ' ) ; r e q u i r e _ o n c e ( ' t w i t t e r / ' . ' t w i t t e r o a u t h . p h p ' ) ; s e s s i o n _ s t a r t ( ) ; / / g e t T o k e n . p h p o a u t h _ t o k e n 一致 i f ( $ _ S E S S I O N [ ' o a u t h _ t o k e n ' ] ! = = $ _ R E Q U E S T [ ' o a u t h _ t o k e n ' ] ) { u n s e t ( $ _ S E S S I O N ) ; e c h o ' < a h r e f = " g e t T o k e n . p h p " > t o k e n 不一致< / a > ' ; e x i t ; } / / a c c e s s t o k e n 取得 $ t w = n e w T w i t t e r O A u t h ( C O N S U M E R _ K E Y , C O N S U M E R _ S E C R E T , $ _ S E S S I O N [ ' o a u t h _ t o k e n ' ] , $ _ S E S S I O N [ ' o a u t h _ t o k e n _ s e c r e t ' ] ) ; $ a c c e s s _ t o k e n = $ t w - > g e t A c c e s s T o k e n ( $ _ R E Q U E S T [ ' o a u t h _ v e r i f i e r ' ] ) ;
  14. 36 マジックナンバー は敵 l e t s a l a

    r y = c o m p u t e S a l a r y ( p e r s o n . w o r k e d H o u r s ) ; f u n c t i o n c o m p u t e S a l a r y ( w o r k e d H o u r s ) { r e t u r n w o r k e d H o u r s * 9 0 0 + 4 0 0 0 ; }
  15. 38 マジックナンバー の置き換え l e t s a l a

    r y = c o m p u t e S a l a r y ( p e r s o n . w o r k e d H o u r s ) ; f u n c t i o n c o m p u t e S a l a r y ( w o r k e d H o u r s ) { r e t u r n w o r k e d H o u r s * 9 0 0 + 4 0 0 0 ; } l e t s a l a r y = c o m p u t e S a l a r y ( p e r s o n . w o r k e d H o u r s ) ; f u n c t i o n c o m p u t e S a l a r y ( w o r k e d H o u r s ) { c o n s t B A S E _ S A L A R Y = 4 0 0 0 ; c o n s t H O U R L Y _ P A Y M E N T = 9 0 0 ; r e t u r n w o r k e d H o u r s * H O U R L Y _ P A Y M E N T + B A S E _ S A L A R Y ; }
  16. 40 不要なコメント / / 引数 定数倍 返 f u n

    c t i o n m u l t i p l e ( n u m b e r ) { c o n s t M U L T I P L I E R = 5 ; r e t u r n n u m b e r * M U L T I P L I E R ; }
  17. 41 不要なコメント ( 補助的なコメント) / / 楽曲 名前 取得 f

    u n c t i o n g e t M u s i c L i s t ( ) { . . . r e t u r n m u s i c L i s t ; } f u n c t i o n f e t c h A l l M u s i c N a m e ( ) { . . . r e t u r n m u s i c N a m e L i s t ; }
  18. { " s t a t u s " :

    0 , " p l a y e r _ d a t a " : { " p l a y e r _ n a m e " : " N a m e " , " t o t a l _ s c o r e " : " 3 9 4 2 6 2 8 3 6 " , " r a n k " : 3 0 8 3 , " a v e r a g e _ s c o r e " : " 8 5 1 5 3 9 " , } } / / G E T 取得 J S O N 列挙 r e q u e s t . g e t ( U R L , f u n c t i o n ( e r r o r , r e s p o n s e , b o d y ) { i f ( ! e r r o r ) { l e t j s o n = J S O N . p a r s e ( b o d y ) ; i f ( j s o n . s t a t u s = = = 0 ) { l e t p l a y e r D a t a = j s o n [ " p l a y e r _ d a t a " ] ; f o r ( l e t p i n p l a y e r D a t a ) { i f ( p l a y e r D a t a [ p ] ! = = n u l l ) { c o n s o l e . l o g ( p + " i s " + p l a y e r D a t a [ p ] ) ; } } } } } ) ;
  19. / / G E T 取得 J S O N

    列挙 r e q u e s t . g e t ( U R L , f u n c t i o n ( e r r o r , r e s p o n s e , b o d y ) { i f ( e r r o r ) { r e t u r n ; } l e t j s o n = J S O N . p a r s e ( b o d y ) ; i f ( j s o n . s t a t u s ! = = 0 ) { r e t u r n ; } l e t p l a y e r D a t a = j s o n [ " p l a y e r _ d a t a " ] ; f o r ( l e t p i n p l a y e r D a t a ) { i f ( p l a y e r D a t a [ p ] = = = n u l l ) { c o n t i n u e ; } c o n s o l e . l o g ( p + " i s " + p l a y e r D a t a [ p ] ) ; } } ) ;
  20. 52 例えば… i f ( s e r v e

    r A . s t a t u s ! = = 0 & & s e r v e r B . s t a t u s ! = = 0 ) { / / A B 異常 時 処理 } e l s e i f ( s e r v e r A . s t a t u s ! = = 0 & & s e r v e r B . s t a t u s = = = 0 ) { / / A 異常 時 処理 } e l s e i f ( s e r v e r A . s t a t u s = = = 0 & & s e r v e r B . s t a t u s ! = = 0 ) { / / B 異常 時 処理 }
  21. i f ( s e r v e r A

    . s t a t u s ! = = 0 ) { i f ( s e r v e r B . s t a t u s ! = = 0 ) { / / A B 異常 時 処理 } e l s e { / / A 異常 時 処理 } } e l s e { i f ( s e r v e r B . s t a t u s ! = = 0 ) { / / B 異常 時 処理 } }
  22. 53

  23. 54 55 分かりづらい条件分岐 i f ( s e r v

    e r A . s t a t u s ! = = 0 & & s e r v e r B . s t a t u s ! = = 0 ) { / / A B 異常 } e l s e i f ( s e r v e r A . s t a t u s ! = = 0 ) { / / A 異常 } e l s e i f ( s e r v e r B . s t a t u s ! = = 0 ) { / / B 異常 }
  24. 57 分かりづらい条件分岐をメソッドで置き換える / / p u b l i c

    b o o l e a n i s S t a t u s E r r o r ( ) { i f ( s t a t u s ! = = 0 ) { r e t u r n f a l s e ; } r e t u r n t r u e ; } i f ( s e r v e r A . i s S t a t u s E r r o r ( ) & & s e r v e r B . i s S t a t u s E r r o r ( ) ) { / / A B 異常 } e l s e i f ( s e r v e r A . i s S t a t u s E r r o r ( ) ) { / / A 異常 } e l s e i f ( s e r v e r B . i s S t a t u s E r r o r ( ) ) { / / B 異常 }
  25. 64 一時変数をメソッドや関数で置き換える l e t e x i s t

    s = f a l s e ; f o r ( l e t i = 0 ; i < B L A C K _ L I S T . l e n g t h ; i + + ) { i f ( p e r s o n . n a m e = = = B L A C K _ L I S T [ i ] ) { e x i s t s = t r u e ; b r e a k ; } } i f ( e x i s t s ) { / / B A N } e l s e { / / 一般人 時 処理 }
  26. 65 メソッドに抽出する f u n c t i o n

    i s E x i s t s ( p e r s o n . n a m e ) { l e t e x i s t s = f a l s e ; f o r ( l e t i = 0 ; i < B L A C K _ L I S T . l e n g t h ; i + + ) { i f ( p e r s o n . n a m e = = = B L A C K _ L I S T [ i ] ) { e x i s t s = t r u e ; b r e a k ; } } r e t u r n e x i s t s ; } ↓ f u n c t i o n i s M a r k e d P e r s o n ( n a m e ) { f o r ( l e t i = 0 ; i < B L A C K _ L I S T . l e n g t h ; i + + ) { i f ( n a m e = = = B L A C K _ L I S T [ i ] ) { r e t u r n t r u e ; } } r e t u r n f a l s e ; }
  27. 66 呼び出し側 i f ( i s M a r

    k e d P e r s o n ( p e r s o n . n a m e ) ) { / / B A N } e l s e { / / 一般人 時 処理 }
  28. 76 メンバ変数を一つにまとめる S t r i n g f i

    r s t N a m e , l a s t N a m e , e m a i l , n i c k n a m e ; i n t g e n d e r ; f i r s t N a m e = j s o n . g e t S t r i n g ( " f i r s t N a m e " ) ; l a s t N a m e = j s o n . g e t S t r i n g ( " l a s t N a m e " ) ; e m a i l = j s o n . g e t S t r i n g ( " e m a i l " ) ; n i c k n a m e = j s o n . g e t S t r i n g ( " n i c k n a m e " ) ; g e n d e r = I n t e g e r . p a r s e I n t ( j s o n . g e t S t r i n g ( " g e n d e r " ) ) ;
  29. 77 デー タクラス c l a s s P r

    o f i l e { p r i v a t e S t r i n g f i r s t N a m e , l a s t N a m e , e m a i l , n i c k n a m e ; p r i v a t e G e n d e r g e n d e r ; P r o f i l e ( S t r i n g f i r s t N a m e , S t r i n g l a s t N a m e , S t r i n g e m a i l , S t r i n g n i c k n a m t h i s . f i r s t N a m e = f i r s t N a m e ; t h i s . l a s t N a m e = l a s t N a m e ; t h i s . e m a i l = e m a i l ; t h i s . n i c k n a m e = n i c k n a m e ; t h i s . g e n d e r = g e n d e r ; } / / g e t t e r & s e t t e r }
  30. 78 呼び出し側 P r o f i l e p

    r o f i l e = n e w P r o f i l e ( j s o n . g e t S t r i n g ( " f i r s t N a m e " ) , j s o n . g e t S t r i n g ( " l a s t N a m e " ) , j s o n . g e t S t r i n g ( " e m a i l " ) , j s o n . g e t S t r i n g ( " n i c k n a m e " ) , I n t e g e r . p a r s e I n t ( j s o n . g e t S t r i n g ( " g e n d e r " ) ) ) ; p r o f i l e . g e t F i r s t N a m e ( ) ;
  31. 80 null オブジェクトの利用 p u b l i c c

    l a s s P a r t T i m e S t u d e n t { p r i v a t e S t r i n g f i r s t N a m e , . . . , e m a i l , h i r e D a t e ; / / 下 P a r e n s H o m e 利用 / / 住民票 実家 場合 p r i v a t e P a r e n t s H o m e p a r e n t s H o m e ; / / g e t t e r & s e t t e r } c l a s s P a r e n t s H o m e { p r i v a t e S t r i n g p h o n e N u m b e r ; p r i v a t e S t r i n g a d d r e s s ; p r i v a t e S t r i n g r e p r e s e n t a t i v e ; p u b l i c S t r i n g g e t P h o n e N u m b e r ( ) { r e t u r n p h o n e N u m b e r ; } / / g e t t e r & s e t t e r }
  32. 81 if や switch を多用せざるを得ない i f ( e x

    a m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) = = = n u l l ) { S y s t e m . o u t . p r i n t l n ( " 実家 電話番号: - " ) ; } S t r i n g p h o n e N u m b e r = e x a m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) . g e t P h o n e N u m b e r ( ) ; S y s t e m . o u t . p r i n t l n ( " 実家 電話番号: " + p h o n e N u m b e r ) ;
  33. 82 1. null オブジェクトの追加 c l a s s N

    u l l P a r e n t s H o m e e x t e n d s P a r e n t s H o m e { . . . }
  34. 83 2. isNull() の追加 c l a s s P

    a r e n t s H o m e { p r i v a t e S t r i n g p h o n e N u m b e r ; p r i v a t e S t r i n g a d d r e s s ; p r i v a t e S t r i n g r e p r e s e n t a t i v e ; p u b l i c b o o l e a n i s N u l l ( ) { r e t u r n f a l s e ; } p u b l i c S t r i n g g e t P h o n e N u m b e r ( ) { r e t u r n t h i s . p h o n e N u m b e r ; } . . . } c l a s s N u l l P a r e n t s H o m e e x t e n d s P a r e n t s H o m e { @ O v e r r i d e p u b l i c b o o l e a n i s N u l l ( ) { r e t u r n t r u e ; } . . . }
  35. 84 3. PartTimeStudent クラスの呼び出し元の修正 p u b l i c

    c l a s s P a r t T i m e S t u d e n t { . . . P a r e n t s H o m e g e t P a r e n t s H o m e ( ) { r e t u r n p a r e n t s H o m e ; } . . . } ↓ p u b l i c c l a s s P a r t T i m e S t u d e n t { . . . P a r e n t s H o m e g e t P a r e n t s H o m e ( ) { i f ( p a r e n t s H o m e = = = n u l l ) { r e t u r n n e w N u l l P a r e n t s H o m e ( ) ; } r e t u r n p a r e n t s H o m e ; } . . . }
  36. 85 4. null 判定箇所を isNull() で置き換え、 テストする i f (

    e x a m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) = = = n u l l ) { r e t u r n ; } i f ( e x a m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) . i s N u l l ( ) ) { r e t u r n ; }
  37. 86 5. ParentsHome が null の時の getter の値を設ける c l

    a s s N u l l P a r e n t s H o m e e x t e n d s P a r e n t s H o m e { @ O v e r r i d e p u b l i c b o o l e a n i s N u l l ( ) { r e t u r n t r u e ; } @ O v e r r i d e p u b l i c S t r i n g g e t P h o n e N u m b e r ( ) { r e t u r n " - " ; } . . . }
  38. 87 6. if を削除できる i f ( e x a

    m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) = = = n u l l ) { r e t u r n ; } S t r i n g p h o n e N u m b e r = e x a m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) . g e t P h o n e N u m b e r ( ) ; S y s t e m . o u t . p r i n t l n ( " 実家 電話番号: " + p h o n e N u m b e r ) ; ↓ S t r i n g p h o n e N u m b e r = e x a m p l e S t u d e n t . g e t P a r e n t s H o m e ( ) . g e t P h o n e N u m b e r ( ) ; S y s t e m . o u t . p r i n t l n ( " 実家 電話番号: " + p h o n e N u m b e r ) ; 出力 実家 電話番号: 0 0 0 0 - 1 1 - 2 2 2 2 実家 電話番号: -
  39. 95 参考書籍 リー ダブルコー ド ― より良いコー ドを書くためのシンプルで実践的なテクニック JUnit 実践入門

    ~ 体系的に学ぶユニットテストの技法 新装版 リファクタリング― 既存のコー ドを安全に改善する―
  40. 97 出典 ( スライド内で使用した画像) ヴォイニッチ手稿: 青峰: アニメ黒子のバスケ2 期OP TABS vs

    SPACES: Emacs vs Vim: どうしてこうなった: 2 ちゃんねるAA FX で有り金全部溶かした人の顔: あいまいみー 第9 話 やらなければ、 一生わからん!!: 燃えよペン Voynich Manuscript Truly Code 4.bp.blogspot.com