Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
JavaDo勉強会での学び実践
Search
sai-lens
October 24, 2025
Technology
110
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
0
33
非エンジニアが院内での業務のために個人開発をした
sailen2
1
71
論文検索を日本語でできるアプリを作ってみた
sailen2
0
460
Ruby の統計ツールと Ruby on Rails で分析をしてみた
sailen2
3
130
React Tokyoのハンズオンに飛び込んでみた話
sailen2
0
91
Other Decks in Technology
See All in Technology
TinyGoでオブザーバビリティ?OpenTelemetryはTinyGoで使えるのか / Is OpenTelemetry available in TinyGo environment?
ymotongpoo
2
120
自分で立ててみるLLMサービス
y_sera15
0
150
生成AIを使って「人が」考える技術 ― AI時代の人機共想と実践ノウハウ|UNITT AC2026
ishiirikie
0
580
[AWS 秋のクラウドオペレーション祭り 2026]AWS DevOps Agentで変わるリリースと運用対応 ~リリース管理機能と Directed actions のご紹介~
furuton
4
1.1k
The seven pitfalls of AI (revised version)
ufried
0
310
あなたの知らないAmazon VPC Route Server/Amazon VPC Route Server you don't know about
masakiokuda
2
250
LocalStack を使ったサーバーレスアプリケーション開発 / Serverless Development with LocalStack
kakakakakku
1
340
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
0
1k
go-sqletch
moznion
0
120
スキルを作る、その前に!複数人で使われるスキルを 作るためのプロセス
junkifurukawa
2
370
1万名の社員が使う認証基盤で どう信頼性を担保するか?
kairim0
0
220
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
8
1.8k
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Everyday Curiosity
cassininazir
0
350
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Site-Speed That Sticks
csswizardry
13
1.6k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
370
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
740
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
980
New Earth Scene 8
popppiees
4
2.7k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
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