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

無用な認知負荷を減らしてお手入れしやすいコードを書こう / Reduce unnecessary cognitive load and write maintainable code

ShinkuFencer
November 09, 2023
4.6k

無用な認知負荷を減らしてお手入れしやすいコードを書こう / Reduce unnecessary cognitive load and write maintainable code

After Kaigi on Rails LT Nightで喋ったスライドです。

【資料内参考したものリンク】

プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ https://www.shuwasystem.co.jp/book/9784798068534.html​​

認知負荷および認知負荷理論 (Cognitive Load Theory) をもう少し正確に理解するための心理学研究・知見の紹介
https://zenn.dev/kangetsu_121/articles/6b31565dda6053

「快適な」学習のために〜認知負荷理論入門|教育のスゴい論文
https://note.com/sugo_ron/n/na8d0916b1f55

102. A Philosophy of Software Design (3/3) w/ twada | fukabori.fm
https://fukabori.fm/episode/102

ShinkuFencer

November 09, 2023
Tweet

More Decks by ShinkuFencer

Transcript

  1. 多重貯蔵モデルとワーキングメモリのイメージ図 5 感覚記憶 Sensory Memory ⻑期記憶 Long Term Memory (LTM)

    ワーキングメモリ Working Memory (WM) 短期記憶 Short Term Memory (STM)  情報のインプット 選択的注意 で分別 ⽬や⽿で取得した情報から 気を払った(≒注意した)ものだけ 短期記憶として取得する ワーキングメモリ*¹で 処理を⾏う 必要に応じて⻑期記憶から 情報を検索したり 情報を保存したりする *1 ワーキングメモリ=短期記憶とするパターンもありますが、今回は隣接するものとしてイメージ図化しました
  2. 多重貯蔵モデルとワーキングメモリ 6 感覚記憶 Sensory Memory 短期記憶 Short Term Memory (STM)

    ⻑期記憶 Long Term Memory (LTM) 記憶容量が少ない 記憶容量が多い 短期記憶は記憶容量が少ない
  3. 認知負荷理論の3つの認知負荷 9 課題内在性負荷 Intrinsic Cognitive Load 取り扱う学習内容がもとから 備えている”本質的な”負荷。 学習者がもとから備えている ⻑期記憶に備えた知識などで

    負荷の量は変化する。 課題外在性負荷 Intrinsic Cognitive Load 取り扱う学習内容には直接関 係ない”余計な”負荷。学習の ためには不要な負荷なので、 ないことが望ましい。 学習関連負荷 Germane Cognitive Load 単純な課題解決のための負荷 とは別の学習を通してより深 い理解に近づけることができ る”適切な”負荷。
  4. 認知負荷理論の3つの認知負荷 10 課題内在性負荷 Intrinsic Cognitive Load 解くべき課題そのものの負荷 「10÷20×20×9 を解けとい う問題を考える」など

    課題外在性負荷 Intrinsic Cognitive Load 課題の本質とは無関係の負荷 「問題説明をジョークを交え ながら話す」*²など 学習関連負荷 Germane Cognitive Load 算数を上達するうえでの負荷 「同じ数をかけて割る場合は 無視できる理屈の理解」など 算数問題を解くことに例えてみると… 10÷20×20×9 20が二重にあるね!!! 二重に二重苦だ *2 ジョークなどで身近な話題に変換することで負荷を下げるという話もあるのでジョークが一概に悪い訳では無い
  5. 認知負荷理論と”効率のよい脳の使い方” 11 • ワーキングメモリは有限であり、かけられる負荷は限られているので、配 分をうまく行いたい。 • 「課題内在性負荷」は学習内容の本質的な負荷なので、学習者がレベル アップしない限りは減らせない。 • レベルアップのためには「学習関連負荷」の比率を上げたい。

    • 残る「課題外在性負荷」は少ないことに越したことはない負荷なので挙げ た3つの中では最も減らしたい負荷となる。 • なので”認知負荷を減らす”というときは第一に課題外在性負荷を減らして いくのがまずは大事*³ *3 長期記憶をうまく使ったり自身のレベルアップができると課題内在性負荷を減らしたりすることもできるので 他の負荷の2種類の負荷も減らせないわけではない
  6. 認知負荷理論と”効率のよい脳の使い方” 12 課題内在性負荷 課題外 在性負 荷 学習関連負荷 効率のよい学習者のワーキングメモリ負荷割合 課題内在性負荷 課題外在性負荷

    学習関連負荷 効率が悪い学習者のワーキングメモリ負荷割合(キャパオーバー) ワーキングメモリにかけられる負荷には限りがあるので 一番不要な課題外在性負荷を減らすことは大事
  7. バラバラな記述方法が負荷になるので整える • 左のコードは金額を引数にとって消 費税10%を含んだ金額を返すs_tax というメソッド。スペースは特に意 味があるわけではない。 • スペースの配置に統一感がなく、逆 に「このスペースの置き方は他と異 なるのでなにか特別な意味があるの

    ではないか?」と考えるようになる のでその過程で認知負荷が増える • 一定のルールに整えるのはrubocop などのlinterで解決ができる 15 def calc_st(p) tp = 0.1 t= p * tp return t + p end def calc_st(p) tp = 0.1 t = p * tp return t + p end
  8. 日常的に利用している言葉を取り入れて負荷を減らす • 「長期記憶をうまく使うことで認知 負荷を減らすことができる」という 仕組みに基づいた考え方 • 日頃利用している英単語などは長期 記憶にあるので認知負荷軽減に寄与 する •

    左記の例だとstが消費税込みの価格 のことだったり、pが価格(price) になっているなど都度脳内で変換を 挟んでいるのでストレートな言葉に 置き換えて脳内変換コストを下げる ことに貢献できる 16 def calc_in_tax_price(base_price) tax_percentage = 0.1 tax = base_price * tax_percentage return tax + base_price end def calc_st(p) tp = 0.1 t = p * tp return t + p end
  9. 日常的に利用している言葉を取り入れて負荷を減らす • Railsの場合はよりActiveSupportを使えばより自然にかける • また、Rubyであれば “?” を使うことでbooleanを返すものは自然に読みや すくなり、自然に読めることで本質的な課題に取り組める 17 def

    available_date?(target_datetime) now_time = Time.zone.now now_time.yesterday <= target_datetime && target_datetime <= now_time.tomorrow end def is_available_date(target_datetime) now_time = Time.zone.now yesterday = DateTime.new(now_time.year,now_time.month,now_time.day - 1) tomorrow = DateTime.new(now_time.year,now_time.month,now_time.day + 1) return yesterday <= target_datetime && target_datetime <= tomorrow end
  10. 意味のある単位を近づけて負荷を減らす • 「関連のある事柄が分割されてしまうと認知負荷があがる」*⁴ということ に基づいた考え方 • プログラミングにおいては処理の単位を遠ざけないようにする 18 def building_object(base_data) flags_hash

    = {} item_array = [] object = {} if base_data[:list].size == 0 flags_hash[:size_zero] = true else base_data[:list].each do |item| item_array << item end object[:item_list] = item_array end object[:flags_hash] = flags_hash return object end flags_hashが確定するのが最後なので メソッドの最初から最後まで 考えておかないといけない item_arrayが登場するのは ネストの中なのに 宣⾔⾃体はメソッドの最初で⾏われている *4 Split-Attention Effect と呼ばれる効果
  11. 意味のある単位を近づけて負荷を減らす • 「関連のある事柄が分割されてしまうと認知負荷があがる」*⁴ということ に基づいた考え方 • プログラミングにおいては処理の単位を遠ざけないようにする 19 def building_object(base_data) flags_hash

    = {} item_array = [] object = {} if base_data[:list].size == 0 flags_hash[:size_zero] = true else base_data[:list].each do |item| item_array << item end object[:item_list] = item_array end object[:flags_hash] = flags_hash return object end def building_object(base_data) return {:flags_hash=>{:size_zero=>true}} if base_data[:list].size == 0 result_list = base_data[:list] { item_list: result_list, flags_hash: {} } end flags_hashもitem_arrayも 返却するobjectの⼀部なので修正して メソッド名どおりobjectをbuildでまとめる *1 Split-Attention Effect と呼ばれる効果
  12. 再代入を避けてイミュータブルにして負荷を減らす • 「関連のある事柄が分割されてしまうと認知負荷があがる」というところ の別の切り口の考え方 • 同じ変数に何度も代入するのは最新状態が不明瞭で認知負荷があがる 20 def response_build(params_hash) success_flag

    = true result_array = [] if params_hash[:error_messages].size > 0 success_flag = false end params_hash[:value_array].each do |value| if value > MAX_VALUE_SIZE success_flag = false else result_array << value end end success_flag = true if params_hash[:skip_error_check] == true return { data: result_array , is_success: success_flag } end success_flagは途中で何度も変わるので 最終的な値がわかりづらく 短期記憶やワーキングメモリを消耗する
  13. 再代入を避けてイミュータブルにして負荷を減らす • 「関連のある事柄が分割されてしまうと認知負荷があがる」というところ の別の切り口の考え方 • 同じ変数に何度も代入するのは最新状態が不明瞭で認知負荷があがる 21 def response_build2(params_hash) result_array

    = [] params_hash[:value_array].each do |value| next if value > MAX_VALUE_SIZE result_array << value end has_no_error_message = params_hash[:error_messages].size == 0 has_no_over_value = params_hash[:value_array].all? { |value| value <= MAX_VALUE_SIZE } is_skip_error_check = params_hash[:skip_error_check] is_success = is_skip_error_check || (has_no_error_message && has_no_over_value) return { data: result_array, is_success: is_success } end 再代⼊を無くすことで 内容を明瞭にする
  14. 24 プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ https://www.shuwasystem.co.jp/book/9784798068534.html 認知負荷および認知負荷理論 (Cognitive Load Theory) をもう少し正確に理解するための心理学研究・知見の紹介 https://zenn.dev/kangetsu_121/articles/6b31565dda6053

    「快適な」学習のために〜認知負荷理論入門|教育のスゴい論文 https://note.com/sugo_ron/n/na8d0916b1f55 102. A Philosophy of Software Design (3/3) w/ twada | fukabori.fm https://fukabori.fm/episode/102 Thanks! 参考にしたサイト/書籍など: オススメ しんくう / shinkufencer   @shinkufencer コード日進月歩 https://shinkufencer.hateblo.jp/