SlideShare uma empresa Scribd logo
1 de 28
Baixar para ler offline
コードに想いを込めて!	
 
bb.tech	
  #03	
  LT資料	
  
(株)アイキューブドシステムズ	
  
田崎	
 大輔	
  
2015/07/17
p  経歴	
  
p  2005〜2008:	
  女子大非常勤講師	
  
p  2008〜2014:	
  組み込み系エンジニア、アーキテクト	
  
p  2014〜	
  	
  	
  	
  :	
  i3Systems,	
  inc.	
  @	
  福岡	
  
p  Ruby/Rails/インフラエンジニア	
  
p  ソーシャル	
  
p  t:	
  @devchick99	
  
p  f:	
  daisuke.tasaki.7	
 
※本資料は私自身の見解であり、必ずしも私の所属する組織、立場、戦略、意見を代表するものではありません。
p  i3Systemsが自社開発するモバイルデバイス管理システム	
  
p  Ruby	
  on	
  Rails製	
  
p  モデル数:	
  356個	
  
p  コントローラ数:	
  294個	
  
p  モバイルデバイスをリモートで運用/管理	
  
p  デバイス情報の取得・閲覧	
  
p  デバイス機能の設定・制限	
  
p  ネットワーク設定の一括配信	
  
p  アプリ配布ポータル	
  
p  デバイスのロック、データ消去	
  
p  モバイル管理(MDM/MAM/MCM)市場4年連続シェアNo.1(※)	
 
※出典: 	
  「ミック経済研究所・ITリポート2014年12月号」	
  
	
  「ミック経済研究所・コラボレーション/コンテンツ・モバイル管理パッケージソフトの市場展望	
  2013年度版」	
  
	
  2011年度、2012年度、2013年度出荷金額実績および2014年度出荷金額予測
※以下、Rubyでサンプルコードを書いていますが、話の本質的にはCでもJavaでも言語問わず通用する内容です(と信じています)。
#	
  コマンドが有効なバージョンかチェックする	
 
def	
  enable_app_version?(app_version,	
  command_app_version)	
  
	
  	
  if	
  ApplicationModel.check_ver_isnew(app_version,	
  command_app_version)	
  ||	
  
	
  	
  	
  	
  	
  app_version.to_f	
  ==	
  command_app_version.to_f	
  
	
  	
  	
  	
  return	
  true	
  
	
  	
  else	
  
	
  	
  	
  	
  return	
  false	
  
	
  	
  end	
  
end
p  check_ver_isnewメソッドはおそらく新しかったら
trueを返すのだろう	
  
p  でもどっち!?	
  どっちが新しいとき?	
  同値だったらどうなんの?	
  
p  その後のto_fしてるのはなに?	
  小数点込みはダメなん!?	
 
#	
  コマンドが有効なバージョンかチェックする	
 
def	
  enable_app_version?(app_version,	
  command_app_version)	
  
	
  	
  if	
  ApplicationModel.check_ver_isnew(app_version,	
  command_app_version)	
  ||	
  
	
  	
  	
  	
  	
  app_version.to_f	
  ==	
  command_app_version.to_f	
  
	
  	
  	
  	
  return	
  true	
  
	
  	
  else	
  
	
  	
  	
  	
  return	
  false	
  
	
  	
  end	
  
end
 	
  	
  	
  if	
  tmp_new[idx].nil?	
  
	
  	
  	
  	
  	
  	
  rtn	
  =	
  false	
  
	
  	
  	
  	
  	
  	
  break	
  
	
  	
  	
  	
  end	
  
	
  
	
  	
  	
  	
  str_new	
  =	
  tmp_new[idx].rjust(3,	
  '0')	
  
	
  	
  	
  	
  str_old	
  =	
  tmp_old[idx].rjust(3,	
  '0')	
  
	
  	
  	
  	
  if	
  str_new	
  >	
  str_old	
  
	
  	
  	
  	
  	
  	
  rtn	
  =	
  true	
  
	
  	
  	
  	
  	
  	
  break	
  
	
  	
  	
  	
  elsif	
  str_new	
  <	
  str_old	
  
	
  	
  	
  	
  	
  	
  rtn	
  =	
  false	
  
	
  	
  	
  	
  	
  	
  break	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  	
  rtn	
  
end	
 
p  →	
 定義元もなにしているのかわからん	
  (-­‐”-­‐;	
 
#	
  バージョンチェック	
  
def	
  self.check_ver_isnew(new,	
  old)	
  
	
  	
  tmp_new	
  =	
  new.split('.')	
  
	
  	
  tmp_old	
  =	
  old.split('.')	
  
	
  
	
  	
  if	
  tmp_new.length	
  >=	
  tmp_old.length	
  
	
  	
  	
  	
  max_size	
  =	
  tmp_new.length	
  
	
  	
  else	
  
	
  	
  	
  	
  max_size	
  =	
  tmp_old.length	
  
	
  	
  end	
  
	
  
	
  	
  rtn	
  =	
  false	
  
	
  	
  for	
  idx	
  in	
  0..(max_size-­‐1)	
  
	
  	
  	
  	
  if	
  tmp_old[idx].nil?	
  
	
  	
  	
  	
  	
  	
  rtn	
  =	
  true	
  
	
  	
  	
  	
  	
  	
  break	
  
	
  	
  	
  	
  end	
  
p  “1.0.0”のような文字列2つを引数にとり、	
  
新しいバージョンか調べるメソッド	
  
p  第1引数の方が第2引数より新しいバージョン番号の場合true	
  
p  同値の場合はfalse	
  
p  同値も含めたい場合は呼び出し後に同値チェック(to_fの箇所)	
  
p  ただし、“1.0”と“1.0.1”を同値と認識してしまう不具合あり	
  
p  そんなん読み取れないよ!	
  
p  この挙動を完全に把握するのに約30分かかりました…	
  
p  もっとコードに想いを込めようぜ!!	
  
check_ver_isnew(“1.0.0”,	
  “0.9.9”) 	
  →	
  true	
  
check_ver_isnew(“1.0.0”,	
  “1.0.0”)	
  ||	
  “1.0.0”.to_f	
  ==	
  “1.0.0”.to_f 	
  →	
  false	
  ||	
  true	
  
check_ver_isnew(“1.0.0”,	
  “1.0.1”)	
  ||	
  “1.0.0”.to_f	
  ==	
  “1.0.1”.to_f 	
  →	
  false	
  ||	
  true!?	
  
p  ISO/IEC	
  9126	
  
p  ソフトウェア品質特性に関する国際規格	
  
p  機能性:	
  機能とその特性に影響する特性群	
  
p  信頼性:	
  ある状況がある時間続いたときにどの程度機能するかに影響する特性群	
  
p  使用性:	
  利用するのにかかる手間、個人の努力などに影響する特性群	
  
p  効率性:	
  ソフトウェアの性能やそれに要するリソース量に影響する特性群	
  
p  保守性:	
  何らかの変更を加えるのにかかる手間に影響する特性群	
  
p  移植性:	
  別の環境にソフトウェアを移行させる可能性に影響する特性群	
  
p コードに想いを込めて保守性向上	
  
p  作成/変更の意図を誰が見てもわかるように	
  
p  保守性が必要ないケース	
  
p  自分しか使わないコード	
  
p  一度しか使わないコード	
  
p  保守性が重要なケース	
  
p  他人も見るコード	
  
p  ずっと使われ続けるコード	
  
p  なぜなら	
  
p  我々は製品コードを作成&メンテするプロ集団だから。	
  
p  チームでコードを作成し、	
  
p  サービスがEOLを迎えるまでメンテし続けなければならない	
 
とにかく動けばなんてもいい
#	
  バージョンチェック	
 
#	
  使い方1:	
  
#	
  	
  	
  ApplicationModel.check_ver_isnew(比較対象文字列1,	
  比較対象文字列2)	
  
#	
  	
  	
  	
  	
  →	
  比較対象文字列1	
  が	
 比較対象文字列2	
  より新しい場合true,	
  同値もしくはより古い場合false	
  
#	
  使い方2:	
  
#	
  	
  	
  ApplicationModel.check_ver_isnew(比較対象文字列1,	
  :newer_than	
  =>	
  比較対象文字列2)	
  
#	
  	
  	
  	
  	
  →	
  比較対象文字列1	
  が	
 比較対象文字列2	
  より新しい場合true,	
  同値もしくはより古い場合false	
  
#	
  使い方3:	
  
#	
  	
  	
  ApplicationModel.check_ver_isnew(比較対象文字列1,	
  :newer_than_or_equal_to	
  =>	
  比較対象文字列2)	
  
#	
  	
  	
  	
  	
  →	
  比較対象文字列1	
  が	
 比較対象文字列2	
  より新しいもしくは同値の場合true,	
  より古い場合false	
  
def	
  self.check_ver_isnew(	
  *args	
  )	
  
	
  	
  ……	
  
	
  	
  #	
  初期値:	
  等号含むならtrue,	
  含まないならfalse	
  
	
  	
  #	
  (各要素が同値なら次の要素へ判断を持ち越す。すべて同値なら判断できず、初期値のままとなる。)	
 
	
 	
 result	
  =	
  (equality	
  ==	
  :newer_than_or_equal_to)	
  ?	
  true	
  :	
  false	
  
	
  	
  new.zip(old).each	
  do	
  |str_new,	
  str_old|	
  
	
  	
  	
  	
  #	
  文字数の多い方に合わせて右寄せでゼロ埋め	
  
	
  	
  	
  	
  str_len	
  =	
  [str_new.length,	
  str_old.length].max	
  
	
  	
  	
  	
  ……	
  
	
  	
  end	
  
end
p  メソッドの使い方説明を追加	
  
p  2つの引数のどっちが新しいときにtrueとなるのか明記	
  
p  同値の場合にtrueとなるのか明記	
  
p  既存の仕様はそのまま	
  
p  どうせならメソッド名も変えたかった…	
  
p  同値を含めるか否かを呼び出し時に指定できるように	
  
p  説明的なハッシュキー&バリューで指定	
  
p  複雑な処理にはコメントを追加	
  
p  なぜこのコードが必要かという理由も	
  
p  変数名をより説明的に	
  
p  例:	
  この変数はオブジェクトのときと配列のときとどっちもあるんだよな…	
  
p  その想いをそのまま変数名にしたらいい!	
  →	
  device_or_ids	
  
	
  #	
  サービスへの招待をコマンドプッシュで通知する	
 
	
 def	
  invite_by_command(admin,	
  device_or_ids)	
  
	
  	
  	
  if	
  device_or_ids.is_a?(Device)	
  
	
  	
  	
  	
  	
  device_ids	
  =	
  [device.id]	
  
	
  	
  	
  elsif	
  device_or_ids.is_a?(Array)	
  
	
  	
  	
  	
  	
  device_ids	
  =	
  device_or_ids	
  
	
  	
  	
  end	
  
	
  	
  	
  ……	
  
	
  end	
  
p  短命な変数は1文字でもOK。ただし意味深く。	
  
p  イテレータ変数iはindexを意味する	
  
p  tmpは非推奨	
  
p  ローカル変数なんて大抵テンポラリなもの	
  
p  何を表現したいのかもっとよくよく考えよう	
  
p  長命なほどより意味深く、より説明的な命名を	
 
長命	
 短命	
 
for文の	
  
イテレータ変数	
 
ローカル変数	
  メソッドの仮引数	
  インスタンス変数	
  グローバル変数
p  メソッドを呼ぶことでどんなことが起きるのかわかるように	
  
p  英語のSVC構文、SVO構文を意識する	
  
p  短く略称を使ってもよいケース	
  
p  汎用的に、頻繁に呼び出すメソッド	
  
p  気軽に(副作用なく)利用できるメソッド	
  
	
  
p  意味深く説明的にするケース	
  
p  特定の用途にしか使わないメソッド	
  
p  呼び出しに注意が必要(副作用がある)メソッド	
  
	
  app_ver.newer_than_or_equal_to?(command_ver)	
  
	
  	
  	
  →	
  Is	
  the	
  app_version	
  newer_than_or_equal_to	
  command_version?	
  
	
  wizard.validate_params_on_building_request	
  
	
  	
  	
  →	
  The	
  wizard	
  validates	
  parameters	
  on	
  building	
  a	
  request.	
  
	
  	
  name	
  =	
  device.to_s	
  
	
  	
  self.generate_aes_encrypt_compatible_key	
  	
  ←	
  単にgenerate_keyだったらどんな用途かわからない	
  
	
  	
  self.push_certificate_with_disable_expired_certificates	
  
p  クラス名はグローバル定数とほぼ同義	
  
p  長命	
  
p  ヒト/モノ、用途を表す	
  
p  ヒト/モノ:	
  User、Device	
  
p  用途:	
  DeviceBuilder、CommandGenerator	
  
p  業界用語を使う	
  
p  製品ドメインの用語	
  
p  デザインパターン名	
  
p  コードの作者と読者で共通の認識を持ちやすい	
  
p  ただし、目的と手段を履き違えないように
p  コメントは作者から読者への直接的なメッセージ	
  
p  でも、変数名/メソッド名/クラス名が充分に意味深ければコメントは不要	
  
p  効果的なコメントとは?	
  
p  whatは今のコードを読めば大体わかる	
  
p  how/whyでコーディング時の想いを残そう	
  
p  [how]	
  クラス/メソッドの使い方説明	
  
p  [why]	
  なぜそのコードが必要なのか	
  
p  [why]	
  なぜ現在のコードになったのか	
 
	
  	
  #	
  結果を返す	
  
	
  	
  return	
  result	
  
	
  	
  #	
  初期値:	
  等号含むならtrue,	
  含まないならfalse	
  
	
  	
  #	
  (各要素が同値なら次の要素へ判断を持ち越す。すべて同値なら判断できず、初期値のままとなる。)	
 
	
  	
  result	
  =	
  (equality	
  ==	
  :newer_than_or_equal_to)	
  ?	
  true	
  :	
  false	
  
	
  	
  #	
  人物がいない場合は、該当組織のみで検索実施	
  
	
  	
  #(不具合対応。これをはずすと人物が存在しない組織の管理者の場合に条件が追加されない)	
 
	
  	
  #	
  return	
  {}	
  if	
  people_abstract_user_ids.blank?	
  
	
  	
  abstract_user_ids	
  =	
  organization_abstract_user_ids	
  +	
  people_abstract_user_ids	
  
論外
p  publicなメソッド	
  
p  いろんなところから呼び出されている可能性があるため全体
grepして影響調査が必要	
  
p  privateなメソッド	
  
p  そのクラス内だけで使われているため、クラス外部への影響を
気にしなくて良い	
  
p  なので、	
  
p  とりあえずpublicで。というのはやめよう	
  
p  影響範囲はここまでなんです!と主張しよう
p  利用者と拡張者へのメッセージ	
  
p  to	
  利用者:	
  
p  オブジェクトがどの具象クラスのもの
か分からなくても、そのメソッドは呼
び出していいよ	
  
p  to	
  拡張者:	
  
p  子クラスを実装するときには必ずオー
バーライドしなさい	
  
p  Rubyにはvirtual修飾子がない	
  
p  どのメソッドでも後から気軽に拡張
できるから疎かにされがち	
  
p  親クラスのメソッドで例外発生させ
ることで表現	
 
class	
  Device	
  
	
  	
  def	
  push_notification	
  
	
  	
  	
  	
  raise	
  “Must	
  be	
  overriden!”	
  
	
  	
  end	
  
end	
  
p  コミットメッセージで改修意図を示そう	
  
p  [what/when/where/who]	
  コミット内容を見れば大体わかる	
  
p  [why]	
  なぜその改修をしたのかを残そう	
  
p  [how]	
  どうやったかは残しにくい	
  
p  ログ表示やblame表示したときに読まれることがある	
  
p  プッシュしてしまうとメッセージを修正できない	
  
p  誤字/脱字、関連するチケット番号に間違いがあるかも	
  
p  情報としてちょっと信頼性が低いので注意
p  コード改修の意図を記載しよう	
  
p  コメント、コミットメッセージには書ききれなかった改修意図	
  
p  思いの丈をレビュアーにぶつけよう	
  
p  コード改修が問題ないことをどう確認したか	
  
p  [how&result]	
  影響範囲調査項目とその結果	
  
p  [how&result]	
  デバッグ試験項目とその結果	
  
p  コードだけでなくプロセスのレビューができるように	
  
p  コードからチケットへのトレーサビリティ	
  
p  コメント、コミットメッセージにチケット番号を記載	
  
p  チケット番号を自動的にリンクしてくれるツールを活用	
  
p  Redmine、JIRA&Bitbucket、などなど	
  
p  チケットにはいろいろ書ける	
  
p  [what]	
  改修内容の概要	
  
p  [how&result]	
  影響範囲調査項目とその結果	
  (プルリクがなければ)	
  
p  [how&result]	
  デバッグ試験項目とその結果	
  (プルリクがなければ)	
  
p  [why]	
  コード改修のそもそもの要件
p  実装の意図大事!	
  
p  なぜそのコードなのか意図を主張しよう	
  
p  名前付け大事!	
  
p  意味深く説明的な名前がついていればコメントはもはや不要	
  
p  コードに込め切れないあふれた感情は	
  
p  コミット、プルリク、チケットに吐き出そう

Mais conteúdo relacionado

Mais procurados

知って得するC#
知って得するC#知って得するC#
知って得するC#Shota Baba
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみたSatoshi Sato
 
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行monglee
 
2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリングkeki3
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング道化師 堂華
 
C++ Template Metaprogramming
C++ Template MetaprogrammingC++ Template Metaprogramming
C++ Template MetaprogrammingAkira Takahashi
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らないdigitalghost
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論MITSUNARI Shigeo
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)Akihiko Matuura
 
第1回勉強会スライド
第1回勉強会スライド第1回勉強会スライド
第1回勉強会スライドkoturn 0;
 
Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?智啓 出川
 
第2回勉強会スライド
第2回勉強会スライド第2回勉強会スライド
第2回勉強会スライドkoturn 0;
 
NetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルNetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルkusabanachi
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61TATSUYA HAYAMIZU
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときShintarou Okada
 
shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)Cryolite
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Takashi Hoshino
 

Mais procurados (20)

知って得するC#
知って得するC#知って得するC#
知って得するC#
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
 
Perl io layer
Perl io layerPerl io layer
Perl io layer
 
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
プログラミング言語 Ruby 2章 Rubyプログラムの構造と実行
 
2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
C++0x concept
C++0x conceptC++0x concept
C++0x concept
 
C++ Template Metaprogramming
C++ Template MetaprogrammingC++ Template Metaprogramming
C++ Template Metaprogramming
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
第1回勉強会スライド
第1回勉強会スライド第1回勉強会スライド
第1回勉強会スライド
 
Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?Why do we confuse String and Array of Characters in Fortran?
Why do we confuse String and Array of Characters in Fortran?
 
第2回勉強会スライド
第2回勉強会スライド第2回勉強会スライド
第2回勉強会スライド
 
NetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルNetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブル
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
 
shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
 

Destaque

DockerでGUIアプリケーションを動かす
DockerでGUIアプリケーションを動かすDockerでGUIアプリケーションを動かす
DockerでGUIアプリケーションを動かすigjit
 
前任者から引き継いだ Eight Android アプリ内部の改善
前任者から引き継いだ Eight Android アプリ内部の改善前任者から引き継いだ Eight Android アプリ内部の改善
前任者から引き継いだ Eight Android アプリ内部の改善健一 辰濱
 
ウフル・Enebular紹介 170225
ウフル・Enebular紹介 170225ウフル・Enebular紹介 170225
ウフル・Enebular紹介 170225知礼 八子
 
lean from the trenches
lean from the trenches lean from the trenches
lean from the trenches Kenji Hiranabe
 
世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート
世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート
世界最大級のアジャイルカンファレンス報告:Agile2016参加レポートHiroyuki Ito
 
TV連動サービスのリアルタイム通知を支える技術
TV連動サービスのリアルタイム通知を支える技術TV連動サービスのリアルタイム通知を支える技術
TV連動サービスのリアルタイム通知を支える技術Tsuyoshi Torii
 
Akka Cluster and Auto-scaling
Akka Cluster and Auto-scalingAkka Cluster and Auto-scaling
Akka Cluster and Auto-scalingIkuo Matsumura
 
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lensNaoki Aoyama
 
ぼくの実装した最弱のディープラーニング
ぼくの実装した最弱のディープラーニングぼくの実装した最弱のディープラーニング
ぼくの実装した最弱のディープラーニングなおき きしだ
 
Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析
Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析
Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析Amazon Web Services Japan
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsugToshiaki Maki
 
KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...
KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...
KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...John Musser
 
論文紹介: Fast R-CNN&Faster R-CNN
論文紹介: Fast R-CNN&Faster R-CNN論文紹介: Fast R-CNN&Faster R-CNN
論文紹介: Fast R-CNN&Faster R-CNNTakashi Abe
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldKonrad Malawski
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けーTanUkkii
 
Make your programs Free
Make your programs FreeMake your programs Free
Make your programs FreePawel Szulc
 
Ansibleの現在とこれから
Ansibleの現在とこれからAnsibleの現在とこれから
Ansibleの現在とこれからTaira Hajime
 
コードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsap
コードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsapコードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsap
コードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsapTomohiro Kumagai
 
Spring 5に備えるリアクティブプログラミング入門
Spring 5に備えるリアクティブプログラミング入門Spring 5に備えるリアクティブプログラミング入門
Spring 5に備えるリアクティブプログラミング入門Takuya Iwatsuka
 

Destaque (20)

DockerでGUIアプリケーションを動かす
DockerでGUIアプリケーションを動かすDockerでGUIアプリケーションを動かす
DockerでGUIアプリケーションを動かす
 
前任者から引き継いだ Eight Android アプリ内部の改善
前任者から引き継いだ Eight Android アプリ内部の改善前任者から引き継いだ Eight Android アプリ内部の改善
前任者から引き継いだ Eight Android アプリ内部の改善
 
ウフル・Enebular紹介 170225
ウフル・Enebular紹介 170225ウフル・Enebular紹介 170225
ウフル・Enebular紹介 170225
 
lean from the trenches
lean from the trenches lean from the trenches
lean from the trenches
 
世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート
世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート
世界最大級のアジャイルカンファレンス報告:Agile2016参加レポート
 
TV連動サービスのリアルタイム通知を支える技術
TV連動サービスのリアルタイム通知を支える技術TV連動サービスのリアルタイム通知を支える技術
TV連動サービスのリアルタイム通知を支える技術
 
Elasticsearch 5.2とJava Clientで戯れる #elasticsearchjp
Elasticsearch 5.2とJava Clientで戯れる #elasticsearchjpElasticsearch 5.2とJava Clientで戯れる #elasticsearchjp
Elasticsearch 5.2とJava Clientで戯れる #elasticsearchjp
 
Akka Cluster and Auto-scaling
Akka Cluster and Auto-scalingAkka Cluster and Auto-scaling
Akka Cluster and Auto-scaling
 
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lens
 
ぼくの実装した最弱のディープラーニング
ぼくの実装した最弱のディープラーニングぼくの実装した最弱のディープラーニング
ぼくの実装した最弱のディープラーニング
 
Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析
Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析
Amazon Kinesis Analytics によるストリーミングデータのリアルタイム分析
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
 
KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...
KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...
KPIs for APIs (and how API Calls are the new Web Hits, and you may be measuri...
 
論文紹介: Fast R-CNN&Faster R-CNN
論文紹介: Fast R-CNN&Faster R-CNN論文紹介: Fast R-CNN&Faster R-CNN
論文紹介: Fast R-CNN&Faster R-CNN
 
Akka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming WorldAkka-chan's Survival Guide for the Streaming World
Akka-chan's Survival Guide for the Streaming World
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
 
Make your programs Free
Make your programs FreeMake your programs Free
Make your programs Free
 
Ansibleの現在とこれから
Ansibleの現在とこれからAnsibleの現在とこれから
Ansibleの現在とこれから
 
コードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsap
コードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsapコードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsap
コードを書きやすくしてくれる Xcode の基本機能 #NSStudy #devsap
 
Spring 5に備えるリアクティブプログラミング入門
Spring 5に備えるリアクティブプログラミング入門Spring 5に備えるリアクティブプログラミング入門
Spring 5に備えるリアクティブプログラミング入門
 

Semelhante a 魂のコーディング

Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Rubymitim
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„和弘 井之上
 
第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)Masanori Machii
 
実行トレース間のデータの差異に基づくデータフロー解析手法の提案
実行トレース間のデータの差異に基づくデータフロー解析手法の提案実行トレース間のデータの差異に基づくデータフロー解析手法の提案
実行トレース間のデータの差異に基づくデータフロー解析手法の提案Kamiya Toshihiro
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカーTetsuya Morimoto
 
BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告
BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告
BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告Uptime Technologies LLC (JP)
 
今さらながらRSpecに入門してみた
今さらながらRSpecに入門してみた今さらながらRSpecに入門してみた
今さらながらRSpecに入門してみたzaru sakuraba
 
負荷テストことはじめ
負荷テストことはじめ負荷テストことはじめ
負荷テストことはじめKazumune Katagiri
 
知って得する標準関数の使い方
知って得する標準関数の使い方知って得する標準関数の使い方
知って得する標準関数の使い方Soudai Sone
 
初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)Masahiro Hayashi
 
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」Tsuyoshi Yamamoto
 
ソフトウェア工学2023 12 コードフォーマット
ソフトウェア工学2023 12 コードフォーマットソフトウェア工学2023 12 コードフォーマット
ソフトウェア工学2023 12 コードフォーマットToru Tamaki
 
Jubatus分類器の活用テクニック
Jubatus分類器の活用テクニックJubatus分類器の活用テクニック
Jubatus分類器の活用テクニックJubatusOfficial
 
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...Kaz Aiso
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„和弘 井之上
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんかcch-robo
 
flow による型のある世界入門
flow による型のある世界入門flow による型のある世界入門
flow による型のある世界入門sairoutine
 
第一回Data mining勉強会 -第二章 - 原案
第一回Data mining勉強会 -第二章 - 原案第一回Data mining勉強会 -第二章 - 原案
第一回Data mining勉強会 -第二章 - 原案yushin_hirano
 

Semelhante a 魂のコーディング (20)

R spec勉強会
R spec勉強会R spec勉強会
R spec勉強会
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第2回 ‟変数と型„
 
第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)
 
実行トレース間のデータの差異に基づくデータフロー解析手法の提案
実行トレース間のデータの差異に基づくデータフロー解析手法の提案実行トレース間のデータの差異に基づくデータフロー解析手法の提案
実行トレース間のデータの差異に基づくデータフロー解析手法の提案
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカー
 
BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告
BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告
BigDataを迎え撃つ! PostgreSQL並列分散ミドルウェア「Stado」の紹介と検証報告
 
今さらながらRSpecに入門してみた
今さらながらRSpecに入門してみた今さらながらRSpecに入門してみた
今さらながらRSpecに入門してみた
 
負荷テストことはじめ
負荷テストことはじめ負荷テストことはじめ
負荷テストことはじめ
 
知って得する標準関数の使い方
知って得する標準関数の使い方知って得する標準関数の使い方
知って得する標準関数の使い方
 
初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)
 
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
 
ソフトウェア工学2023 12 コードフォーマット
ソフトウェア工学2023 12 コードフォーマットソフトウェア工学2023 12 コードフォーマット
ソフトウェア工学2023 12 コードフォーマット
 
Jubatus分類器の活用テクニック
Jubatus分類器の活用テクニックJubatus分類器の活用テクニック
Jubatus分類器の活用テクニック
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第4回 「Function と Pro...
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第5回 ‟配列と構造体„
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
flow による型のある世界入門
flow による型のある世界入門flow による型のある世界入門
flow による型のある世界入門
 
第一回Data mining勉強会 -第二章 - 原案
第一回Data mining勉強会 -第二章 - 原案第一回Data mining勉強会 -第二章 - 原案
第一回Data mining勉強会 -第二章 - 原案
 

魂のコーディング

  • 1. コードに想いを込めて! bb.tech  #03  LT資料   (株)アイキューブドシステムズ   田崎 大輔   2015/07/17
  • 2.
  • 3. p  経歴   p  2005〜2008:  女子大非常勤講師   p  2008〜2014:  組み込み系エンジニア、アーキテクト   p  2014〜        :  i3Systems,  inc.  @  福岡   p  Ruby/Rails/インフラエンジニア   p  ソーシャル   p  t:  @devchick99   p  f:  daisuke.tasaki.7 ※本資料は私自身の見解であり、必ずしも私の所属する組織、立場、戦略、意見を代表するものではありません。
  • 4. p  i3Systemsが自社開発するモバイルデバイス管理システム   p  Ruby  on  Rails製   p  モデル数:  356個   p  コントローラ数:  294個   p  モバイルデバイスをリモートで運用/管理   p  デバイス情報の取得・閲覧   p  デバイス機能の設定・制限   p  ネットワーク設定の一括配信   p  アプリ配布ポータル   p  デバイスのロック、データ消去   p  モバイル管理(MDM/MAM/MCM)市場4年連続シェアNo.1(※) ※出典:  「ミック経済研究所・ITリポート2014年12月号」    「ミック経済研究所・コラボレーション/コンテンツ・モバイル管理パッケージソフトの市場展望  2013年度版」    2011年度、2012年度、2013年度出荷金額実績および2014年度出荷金額予測
  • 6. #  コマンドが有効なバージョンかチェックする def  enable_app_version?(app_version,  command_app_version)      if  ApplicationModel.check_ver_isnew(app_version,  command_app_version)  ||            app_version.to_f  ==  command_app_version.to_f          return  true      else          return  false      end   end
  • 7.
  • 8. p  check_ver_isnewメソッドはおそらく新しかったら trueを返すのだろう   p  でもどっち!?  どっちが新しいとき?  同値だったらどうなんの?   p  その後のto_fしてるのはなに?  小数点込みはダメなん!? #  コマンドが有効なバージョンかチェックする def  enable_app_version?(app_version,  command_app_version)      if  ApplicationModel.check_ver_isnew(app_version,  command_app_version)  ||            app_version.to_f  ==  command_app_version.to_f          return  true      else          return  false      end   end
  • 9.        if  tmp_new[idx].nil?              rtn  =  false              break          end            str_new  =  tmp_new[idx].rjust(3,  '0')          str_old  =  tmp_old[idx].rjust(3,  '0')          if  str_new  >  str_old              rtn  =  true              break          elsif  str_new  <  str_old              rtn  =  false              break          end      end      rtn   end p  → 定義元もなにしているのかわからん  (-­‐”-­‐; #  バージョンチェック   def  self.check_ver_isnew(new,  old)      tmp_new  =  new.split('.')      tmp_old  =  old.split('.')        if  tmp_new.length  >=  tmp_old.length          max_size  =  tmp_new.length      else          max_size  =  tmp_old.length      end        rtn  =  false      for  idx  in  0..(max_size-­‐1)          if  tmp_old[idx].nil?              rtn  =  true              break          end  
  • 10. p  “1.0.0”のような文字列2つを引数にとり、   新しいバージョンか調べるメソッド   p  第1引数の方が第2引数より新しいバージョン番号の場合true   p  同値の場合はfalse   p  同値も含めたい場合は呼び出し後に同値チェック(to_fの箇所)   p  ただし、“1.0”と“1.0.1”を同値と認識してしまう不具合あり   p  そんなん読み取れないよ!   p  この挙動を完全に把握するのに約30分かかりました…   p  もっとコードに想いを込めようぜ!!   check_ver_isnew(“1.0.0”,  “0.9.9”)  →  true   check_ver_isnew(“1.0.0”,  “1.0.0”)  ||  “1.0.0”.to_f  ==  “1.0.0”.to_f  →  false  ||  true   check_ver_isnew(“1.0.0”,  “1.0.1”)  ||  “1.0.0”.to_f  ==  “1.0.1”.to_f  →  false  ||  true!?  
  • 11.
  • 12. p  ISO/IEC  9126   p  ソフトウェア品質特性に関する国際規格   p  機能性:  機能とその特性に影響する特性群   p  信頼性:  ある状況がある時間続いたときにどの程度機能するかに影響する特性群   p  使用性:  利用するのにかかる手間、個人の努力などに影響する特性群   p  効率性:  ソフトウェアの性能やそれに要するリソース量に影響する特性群   p  保守性:  何らかの変更を加えるのにかかる手間に影響する特性群   p  移植性:  別の環境にソフトウェアを移行させる可能性に影響する特性群   p コードに想いを込めて保守性向上   p  作成/変更の意図を誰が見てもわかるように  
  • 13. p  保守性が必要ないケース   p  自分しか使わないコード   p  一度しか使わないコード   p  保守性が重要なケース   p  他人も見るコード   p  ずっと使われ続けるコード   p  なぜなら   p  我々は製品コードを作成&メンテするプロ集団だから。   p  チームでコードを作成し、   p  サービスがEOLを迎えるまでメンテし続けなければならない とにかく動けばなんてもいい
  • 14.
  • 15. #  バージョンチェック #  使い方1:   #      ApplicationModel.check_ver_isnew(比較対象文字列1,  比較対象文字列2)   #          →  比較対象文字列1  が 比較対象文字列2  より新しい場合true,  同値もしくはより古い場合false   #  使い方2:   #      ApplicationModel.check_ver_isnew(比較対象文字列1,  :newer_than  =>  比較対象文字列2)   #          →  比較対象文字列1  が 比較対象文字列2  より新しい場合true,  同値もしくはより古い場合false   #  使い方3:   #      ApplicationModel.check_ver_isnew(比較対象文字列1,  :newer_than_or_equal_to  =>  比較対象文字列2)   #          →  比較対象文字列1  が 比較対象文字列2  より新しいもしくは同値の場合true,  より古い場合false   def  self.check_ver_isnew(  *args  )      ……      #  初期値:  等号含むならtrue,  含まないならfalse      #  (各要素が同値なら次の要素へ判断を持ち越す。すべて同値なら判断できず、初期値のままとなる。) result  =  (equality  ==  :newer_than_or_equal_to)  ?  true  :  false      new.zip(old).each  do  |str_new,  str_old|          #  文字数の多い方に合わせて右寄せでゼロ埋め          str_len  =  [str_new.length,  str_old.length].max          ……      end   end
  • 16. p  メソッドの使い方説明を追加   p  2つの引数のどっちが新しいときにtrueとなるのか明記   p  同値の場合にtrueとなるのか明記   p  既存の仕様はそのまま   p  どうせならメソッド名も変えたかった…   p  同値を含めるか否かを呼び出し時に指定できるように   p  説明的なハッシュキー&バリューで指定   p  複雑な処理にはコメントを追加   p  なぜこのコードが必要かという理由も  
  • 17. p  変数名をより説明的に   p  例:  この変数はオブジェクトのときと配列のときとどっちもあるんだよな…   p  その想いをそのまま変数名にしたらいい!  →  device_or_ids    #  サービスへの招待をコマンドプッシュで通知する def  invite_by_command(admin,  device_or_ids)        if  device_or_ids.is_a?(Device)            device_ids  =  [device.id]        elsif  device_or_ids.is_a?(Array)            device_ids  =  device_or_ids        end        ……    end  
  • 18. p  短命な変数は1文字でもOK。ただし意味深く。   p  イテレータ変数iはindexを意味する   p  tmpは非推奨   p  ローカル変数なんて大抵テンポラリなもの   p  何を表現したいのかもっとよくよく考えよう   p  長命なほどより意味深く、より説明的な命名を 長命 短命 for文の   イテレータ変数 ローカル変数 メソッドの仮引数 インスタンス変数 グローバル変数
  • 19. p  メソッドを呼ぶことでどんなことが起きるのかわかるように   p  英語のSVC構文、SVO構文を意識する   p  短く略称を使ってもよいケース   p  汎用的に、頻繁に呼び出すメソッド   p  気軽に(副作用なく)利用できるメソッド     p  意味深く説明的にするケース   p  特定の用途にしか使わないメソッド   p  呼び出しに注意が必要(副作用がある)メソッド    app_ver.newer_than_or_equal_to?(command_ver)        →  Is  the  app_version  newer_than_or_equal_to  command_version?    wizard.validate_params_on_building_request        →  The  wizard  validates  parameters  on  building  a  request.      name  =  device.to_s      self.generate_aes_encrypt_compatible_key    ←  単にgenerate_keyだったらどんな用途かわからない      self.push_certificate_with_disable_expired_certificates  
  • 20. p  クラス名はグローバル定数とほぼ同義   p  長命   p  ヒト/モノ、用途を表す   p  ヒト/モノ:  User、Device   p  用途:  DeviceBuilder、CommandGenerator   p  業界用語を使う   p  製品ドメインの用語   p  デザインパターン名   p  コードの作者と読者で共通の認識を持ちやすい   p  ただし、目的と手段を履き違えないように
  • 21. p  コメントは作者から読者への直接的なメッセージ   p  でも、変数名/メソッド名/クラス名が充分に意味深ければコメントは不要   p  効果的なコメントとは?   p  whatは今のコードを読めば大体わかる   p  how/whyでコーディング時の想いを残そう   p  [how]  クラス/メソッドの使い方説明   p  [why]  なぜそのコードが必要なのか   p  [why]  なぜ現在のコードになったのか    #  結果を返す      return  result      #  初期値:  等号含むならtrue,  含まないならfalse      #  (各要素が同値なら次の要素へ判断を持ち越す。すべて同値なら判断できず、初期値のままとなる。)    result  =  (equality  ==  :newer_than_or_equal_to)  ?  true  :  false      #  人物がいない場合は、該当組織のみで検索実施      #(不具合対応。これをはずすと人物が存在しない組織の管理者の場合に条件が追加されない)    #  return  {}  if  people_abstract_user_ids.blank?      abstract_user_ids  =  organization_abstract_user_ids  +  people_abstract_user_ids   論外
  • 22. p  publicなメソッド   p  いろんなところから呼び出されている可能性があるため全体 grepして影響調査が必要   p  privateなメソッド   p  そのクラス内だけで使われているため、クラス外部への影響を 気にしなくて良い   p  なので、   p  とりあえずpublicで。というのはやめよう   p  影響範囲はここまでなんです!と主張しよう
  • 23. p  利用者と拡張者へのメッセージ   p  to  利用者:   p  オブジェクトがどの具象クラスのもの か分からなくても、そのメソッドは呼 び出していいよ   p  to  拡張者:   p  子クラスを実装するときには必ずオー バーライドしなさい   p  Rubyにはvirtual修飾子がない   p  どのメソッドでも後から気軽に拡張 できるから疎かにされがち   p  親クラスのメソッドで例外発生させ ることで表現 class  Device      def  push_notification          raise  “Must  be  overriden!”      end   end  
  • 24. p  コミットメッセージで改修意図を示そう   p  [what/when/where/who]  コミット内容を見れば大体わかる   p  [why]  なぜその改修をしたのかを残そう   p  [how]  どうやったかは残しにくい   p  ログ表示やblame表示したときに読まれることがある   p  プッシュしてしまうとメッセージを修正できない   p  誤字/脱字、関連するチケット番号に間違いがあるかも   p  情報としてちょっと信頼性が低いので注意
  • 25. p  コード改修の意図を記載しよう   p  コメント、コミットメッセージには書ききれなかった改修意図   p  思いの丈をレビュアーにぶつけよう   p  コード改修が問題ないことをどう確認したか   p  [how&result]  影響範囲調査項目とその結果   p  [how&result]  デバッグ試験項目とその結果   p  コードだけでなくプロセスのレビューができるように  
  • 26. p  コードからチケットへのトレーサビリティ   p  コメント、コミットメッセージにチケット番号を記載   p  チケット番号を自動的にリンクしてくれるツールを活用   p  Redmine、JIRA&Bitbucket、などなど   p  チケットにはいろいろ書ける   p  [what]  改修内容の概要   p  [how&result]  影響範囲調査項目とその結果  (プルリクがなければ)   p  [how&result]  デバッグ試験項目とその結果  (プルリクがなければ)   p  [why]  コード改修のそもそもの要件
  • 27.
  • 28. p  実装の意図大事!   p  なぜそのコードなのか意図を主張しよう   p  名前付け大事!   p  意味深く説明的な名前がついていればコメントはもはや不要   p  コードに込め切れないあふれた感情は   p  コミット、プルリク、チケットに吐き出そう