Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JavaDo勉強会での学び実践
Search
sai-lens
October 24, 2025
Technology
95
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JavaDo勉強会での学び実践
sai-lens
October 24, 2025
More Decks by sai-lens
See All by sai-lens
非エンジニアが院内での業務のために個人開発をした
sailen2
1
13
論文検索を日本語でできるアプリを作ってみた
sailen2
0
410
Ruby の統計ツールと Ruby on Rails で分析をしてみた
sailen2
3
120
React Tokyoのハンズオンに飛び込んでみた話
sailen2
0
79
Other Decks in Technology
See All in Technology
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
小さく始める AI 活用推進 ― 日経電子版 Web チームの事例/nikkei-tech-talk47
nikkei_engineer_recruiting
0
270
日本 Fintech 未来予測レポート 2027〜2028年(オリジナル版)
8maki
0
2.2k
不要なレビューをAIにまかせて AIコーディングの環境改善を加速した
shoota
1
150
Socrates × Looker 〜セマンティックレイヤーで進化するデータ分析エージェント〜
hanon52_
3
2.4k
AWS Security Agent といっしょに脅威モデリングをやってみよう
amarelo_n24
0
100
自律型AIエージェントは何を破壊するのか
kojira
0
160
Android の公式 Skill / Android skills
yanzm
0
150
現地で盛り上がった WWDC26 Keynote
zozotech
PRO
1
250
【2026年版】 ベクトル検索䛸 Embedding最前線
mocobeta
2
220
ルールやカスタム機能、どう活かす?ハンズオンで体感するIBM Bobの出力コントロール
muehara
1
170
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
1.1k
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
100
6.2k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
210
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
610
The Invisible Side of Design
smashingmag
302
52k
Between Models and Reality
mayunak
4
340
YesSQL, Process and Tooling at Scale
rocio
174
15k
BBQ
matthewcrist
89
10k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Transcript
JavaDo勉強会での学びの実践 2025.10.23/はじめてのIT勉強会 in 札幌(2025) さい/sai-lens
⾃⼰紹介 • さい/sai-lens • 現在は病院で臨床検査技師として勤務 • プログラミング学習3ヶ⽉⽬ • 現在学習中の技術 ◦
フロントエンド:JavaScript, React ◦ バックエンド:Ruby, Ruby on Rails 1 @GTposiwill @sye-lens
本⽇のLTのきっかけ • 勉強会に参加 ◦ JavaDo「増田 亨さんと設計の実践的な考え方 を学ぼう!」 ◦ ⽇時:10/4(⼟) ◦
場所:クオリサイトテクノロジーズ株式会社 (⽇本⽣命ビル) • 勉強会での学びをアウトプットして⾝につけたい 2
ソフトウェアを取り巻く「現実」 なぜソフトウェア設計が難しいのか? ソフトウェアはそもそも複雑 ソフトウェアの利⽤環境、技術も、ビジネス要求も変化し、変わり続ける 未知の課題に、不確実な状況で取り組まなければならない 設計に使える時間は限られている @さい/sai-lens 3
では「良い設計」とは? 勉強会で学んだ、設計の本質 良い設計は悪い設計よりも変更しやすい — 『達⼈プログラマー』より 4
どう実現するか? → 「関⼼の分離」 モデル駆動設計(MDD)の考え⽅:役割ごとにコードを分ける UI (表⽰‧操作) ユーザーが⾒る画⾯や、 操作を受け付ける部分 インフラ (DBなど)
データを保存したり、 外部と通信したりする部分 Domain (ロジック) 「アプリの核となるルール」 を決め、考える部分 5
学びの実践(モデル駆動設計) JavaDoのワークショップで 「⽇程調整アプリ」の設計に挑戦 お題: ⽇程調整アプリ (「調整さん」のイメージ) ⼿法: モデル駆動設計(MDD) 焦点: 「最適⽇を決定するルール」
(=ドメイン)に焦点を当てる 6 sye-lens/nitteichousei
最適⽇を決定するルール • 参加者と必須参加者がいる。 • 全員の回答をもとに候補⽇を評価する。 • もし「必須参加者が全員◯」かつ「他の参加者も全員◯」の候補⽇があれ ば、⽇程をその⽇に確定する。それ以外は再調整。 • 「すべての参加者が◯」の候補⽇が複数ある場合は、もっとも早い⽇付を
選んで確定する。 7
ディレクトリ構成 domains/attendance_decision.rb はcontrollers, models, viewから独⽴ / ├─ app │ └─
assets │ ├─ controllers │ ├─ domains │ │ └─ attendance_decision.rb │ ├─ models │ └─ views ├─ db 8
domains/attendance_decision.rb class AttendanceDecision AttendanceDecisionResult = Struct.new(:decision_status, :most_suitable_date, keyword_init: true) def
initialize(members:, required_members:, proposed_dates:, responses:) @members = members @required_members = required_members @proposed_dates = proposed_dates @responses = responses end def decide if (d = decided_date) return AttendanceDecisionResult.new(decision_status: :decided,most_suitable_date: d) end AttendanceDecisionResult.new(decision_status: :reschedule_required, most_suitable_date: best_date) end private def decided_date @proposed_dates.find { |d| all_yes?(d) && required_all_yes?(d) } end . 9
「分離」がもたらす変化 ロジック(ドメイン)を分離すると、コード構造はどう変わるか 従来(混在したコード) 画⾯処理、DB操作、⽇程決定ロジックが すべて⼀箇所に固まっている ルールの変更が画⾯やDBの修正に影響し そうで怖い MDD(分離したコード) 「⽇程決定ロジック」だけが独⽴した 「ドメイン」として存在
UIやDBとは疎結合(お互い依存しな い) 10
メリット①:機能拡張が「楽」 もし「新しい⽇程決定ルール」を追加したくなったら? 例:最適⽇を選ぶとき、必須は全員◯の候補の中で、同点トップが複数なら最早⽇で確定 (多数決で決定) 変更するのは「ドメイン(ロジック)」の部分だけ。 UIやDBのコードを触る必要がないため、変更が楽 11
メリット②:UIなどのI/O周りの変更が「安全」 もし「画⾯デザインを刷新」したくなったら? 例:画⾯のデザインやスタイルを⼤幅に変更 変更するのは「UI」の部分だけ。 「ドメイン(ロジック)」は分離されているため、⽇程決定ルールを壊す⼼配 がない(安全) 12
メリット③:コードが「わかりやすい」 どこに、なにが書いてあるのかをわかりやすく書くことができる I/Oと独⽴していることで、メインロジックが理解しやすくなる 加えて、ロジック部分を「ビジネスの⾔葉」で記述する 例: `decided` (確定), `most_suitable_date` (最適⽇) エンジニアも⾮エンジニアも、ロジックの意図が理解しやすくなる
13
良い設計:attendance_decision.rbを修正するだけ class AttendanceDecision AttendanceDecisionResult = Struct.new(:decision_status,:most_suitable_date) . . def decide
if (d = decided_date) return AttendanceDecisionResult.new( decision_status: :decided, most_suitable_date: d, . end private def decided_date @proposed_dates.find { |d| all_yes?(d) && required_all_yes?(d) } end . . 14 if (d = decided_by_required_all_yes_tiebreak) return AttendanceDecisionResult.new( decision_status: :decided, most_suitable_date: d, ) end # 必須参加者が全員◯の候補のみを対象に、 # 「total_yes」が最大のスコアで同点の候補が複 数ある場合は最も早い日を返す # そうでなければ nil def decided_by_required_all_yes_tiebreak candidates = @proposed_dates.select { |d| required_all_yes?(d) } return nil if candidates.empty?
悪い設計:controllersでI/Oとロジックが混在 15 class AttendancesController < ApplicationController def update attendance =
Attendance.find(params[:id]) meeting = attendance.participant.meeting if attendance.update(attendance_params) decision, scores = meeting.decide_and_score respond_to do |format| format.turbo_stream do render turbo_stream: [ ] end else . . end private def attendance_params params.require(:attendance).permit(:status) end end # ①「全員◯ & 必須◯」なら即 decided decided_pd = date_rows.find do |pd_id, _d| all_yes_for.call(pd_id) && required_all_yes_for.call(pd_id) end if decided_pd decided_date = decided_pd[1] decision = OpenStruct.new(decision_status: :decided, most_suitable_date: decided_date) else # ② 機能拡張:必須は全員◯の候補のみ抽出 required_yes_candidates = date_rows.select { |pd_id, _d| required_all_yes_for.call(pd_id) } if required_yes_candidates.any? # total_yes の最大値を算出 with_total = required_yes_candidates.map { |pd_id, d| [pd_id, d, total_yes_count_for.call(pd_id)] } max_total = with_total.map { |(_id, _d, tot)| tot }.max . . viewへの出力 DBから入力データを取得
まとめ - 「良い設計」は「悪い設計」よりも変更しやすい - 「変更に強い設計」を実践、メインロジックをその他のI/Oから分離した - その結果 - メインロジックの機能拡張、変更が「楽」 -
メインロジックに⼲渉しないのでその他の変更が「安全」 - どこに何が書いてあるのかが理解しやすく、誰にでも意図が伝わる コードになる 16