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
Springで始める3層アーキテクチャ / start three layer archite...
Search
yachiy
November 14, 2019
120
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Springで始める3層アーキテクチャ / start three layer architecture with spring
yachiy
November 14, 2019
More Decks by yachiy
See All by yachiy
同人プロダクトのリプレース案件における技術的負債解消への取り組み / Addressing Technical Debt in the Revamp of Doujin Products
yachiy
0
24
AWS事始め / Introduction AWS
yachiy
1
77
Springで始めるWebApplication / Start Spring Web Application
yachiy
0
140
RDRAとDDDを実践していく上でのCleanArchitectureの同異点 / RDRA and Clean Architecture differences
yachiy
0
140
議事録のとり方 / how to write proceeding
yachiy
0
170
値オブジェクトの悩みポイントとどう付き合っていくか
yachiy
1
3k
Featured
See All Featured
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
320
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Speed Design
sergeychernyshev
33
2.1k
GitHub's CSS Performance
jonrohan
1033
470k
Crafting Experiences
bethany
1
340
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
A Modern Web Designer's Workflow
chriscoyier
699
190k
Bash Introduction
62gerente
615
220k
Transcript
4QSJOHͰ࢝ΊΔΞʔΩςΫνϟ
ͱ
ϓϨθϯςʔγϣϯ σʔλΞΫηε ϏδωεϩδοΫ
ϓϨθϯςʔγϣϯ
ը໘ͩͬͨΓɺ"1*ͷΤϯυϙΠϯτͩͬͨΓ ར༻ऀͱͷڥքɺΠϯλϑΣʔεʹͳΔ෦
σʔλΞΫηε
σʔλͷӬଓԽɺ࠶ߏΛߦ͏Έʢ%# ͱ͔ϑΝΠϧͱ͔ʣͱͷΓऔΓΛߦ͏
ϏδωεϩδοΫ
ۀͷϩδοΫΛهड़͢Δ
ʁʁʁ
ۀͱ
ۀ ˠͦͷΞϓϦέʔγϣϯͰղܾ͍ͨ͠ ˠଟذʹΘͨΔʹෳࡶ
IUUQTXXXTMJEFTIBSFOFUNBTVEBTT
͜͜
݁ہҰ൪ूத͍ͨ͠ͷۀͷ༰͔ͩΒ ೖग़ྗ͔Βִͯ͠͠·͠ΐ͏ͱ͍͏
4QSJOHͰ͍͏ͱ
!$POUSPMMFS !3FTU$POUSPMMFS !3FQPTJUPSZ !4FSWJDF
࣮ફ
ίϝϯτΛॻ͖ࠐΊΔϝϞாΛߟ͑Δ ʢߦͷ్தʹίϝϯτೖΕͯແࢹ͢Δʣ ༰Λॻ͚Δ ೖྗ༰ΛอଘͰ͖Δ ίϝϯτ͕ফ͑ͨঢ়ଶͰ༰͕ݟΕΔ
ίϝϯτΛॻ͖ࠐΊΔϝϞாΛߟ͑Δ ʢߦͷ్தʹίϝϯτೖΕͯແࢹ͢Δʣ ༰Λॻ͚Δ ೖྗ༰ΛอଘͰ͖Δ ίϝϯτ͕ফ͑ͨঢ়ଶͰ༰͕ݟΕΔ
package com.yachiy.spring.introduction.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class MemoController
{ @GetMapping("/") public String memo() { return "memo"; } } .FNP$POUSPMMFSKBWB
<!doctype html> <html> <head> <meta charset="UTF-8"/> <title>ίϝϯτΞτ͕ޮ͘ϝϞாʢԾʣ</title> </head> <body> <h1>ίϝϯτΞτ͕ޮ͘ϝϞாʢԾʣ</h1>
<textarea id="content" cols="50" rows="20" placeholder="༰Λೖྗ͍ͯͩ͘͠͞"></textarea> <button>ૹ৴</button> </body> </html> NFNPIUNM
࣮ߦͯ͠MPDBMIPTUʹΞΫηε
ը໘ग़Δʢೖྗͯ͠ૹ৴ͯ͠Կى͜Βͳ͍͚Ͳʣ
࣍ʹೖྗͷड͚औΓ
package com.yachiy.spring.introduction.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping;
@Controller public class MemoController { @GetMapping("/") public String memo() { return "memo"; } @PostMapping("/") public String receive(MemoForm memoForm, Model model) { model.addAttribute("content", memoForm.getContent()); return "received"; } } .FNP$POUSPMMFSKBWB 1045ͷ݁ՌΛड͚औΔϝιουΛ Ճ
package com.yachiy.spring.introduction.controller; /** * ϝϞ༰Λड͚ͨ͢ΊͷϞσϧ */ public class MemoForm {
private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } } .FNP'PSNKBWB
<!doctype html> <html xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"/> <title>݁Ռ</title> </head> <body>
<h1>༰Λड͚औΓ·ͨ͠</h1> <div th:text="${content}"></div> </body> </html> SFDFJWFEIUNM
<!doctype html> <html> <head> <meta charset="UTF-8"/> <title>ίϝϯτΞτ͕ޮ͘ϝϞாʢԾʣ</title> </head> <body> <h1>ίϝϯτΞτ͕ޮ͘ϝϞாʢԾʣ</h1>
<form method="post" action="/"> <textarea id="content" name="content" cols="50" rows="20" placeholder="༰Λೖྗ͍ͯͩ͘͠͞"></textarea> <button>ૹ৴</button> </form> </body> </html> NFNPIUNM GPSNλάՃ .FNP'PSNͷϑΟʔϧυ໊ͱҰகͤ͞Δ
࣮ߦͯ͠MPDBMIPTUʹΞΫηε
ೖྗͯ͠ ԡԼ
ೖྗ༰͕ө͞Ε͍ͯΔ
ίϝϯτΛॻ͖ࠐΊΔϝϞாΛߟ͑Δ ʢߦͷ్தʹίϝϯτೖΕͯແࢹ͢Δʣ ༰Λॻ͚Δ ೖྗ༰ΛอଘͰ͖Δ ίϝϯτ͕ফ͑ͨঢ়ଶͰ༰͕ݟΕΔ
࣍อଘͱ֬ೝʢϝϞாͳͷͰʣ
͚ͩͲ%#Λ༻ҙ͢Δͷ݁ߏେมʜ ˠࠓճϝϞϦ্ʹอଘ͢ΔΑ͏࣮
͡Ό࣮͋ࡍ%#͏Α͏ʹͳͬͨΒ ৭ʑͳॴஔ͖͑ͳ͖Ό͍͚ͳ͍ͷʁ ˠ%*ͷΈΛͬͯӬଓԽͷೖग़ྗͷϩδοΫ͚ͩ ஔ͖͑ΕॅΉΑ͏ʹ࣮͢Δ
package com.yachiy.spring.introduction.dao; public interface MemoDao { /** * ϝϞ༰ΛӬଓԽ͠ϝϞIDΛฦ٫͢Δ. *
* @param content ༰ * @return ϝϞID */ int store(String content); /** * IDΛࢦఆͯ͠ϝϞ༰Λऔಘ͢Δ. * * @param id ϝϞID * @return ϝϞ༰ */ String findById(int id); } .FNP%BPKBWB ϝϞΛӬଓԽ࠶ߏ͢ΔͨΊͷΠϯλϑΣʔε
package com.yachiy.spring.introduction.dao; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; @Repository public
class InMemoryMemoDao implements MemoDao { private static final List<String> memoList = new ArrayList<>(); @Override public int store(String content) { memoList.add(content); return memoList.size(); } @Override public String findById(int id) { return memoList.get(id - 1); // 0࢝·ΓͳͷͰ-1 } } *O.FNPSZ.FNP%BPKBWB ϝϞϦ্Ͱ.FNP%BPͷڍಈΛ࣮ݱ͢Δ࣮Ϋϥε %*ίϯςφʹొ
package com.yachiy.spring.introduction.controller; import com.yachiy.spring.introduction.dao.MemoDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @Controller public class MemoController { private MemoDao memoDao; @Autowired public MemoController(MemoDao memoDao) { this.memoDao = memoDao; } @GetMapping("/") public String memo() { return "memo"; } @PostMapping("/") public String receive(MemoForm memoForm, Model model) { int memoId = memoDao.store(memoForm.getContent()); model.addAttribute("memoId", memoId); return "received"; } @GetMapping("/{memoId}") public String view(@PathVariable int memoId, Model model) { String content = memoDao.findById(memoId); model.addAttribute("content", content); return "view"; } } .FNP$POUSPMMFSKBWB %FQFOEFODZ*OKFDUJPO ύε͔ΒΛऔಘ
<!doctype html> <html xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"/> <title>݁Ռ</title> </head> <body>
<h1>༰Λड͚औΓ·ͨ͠</h1> <div>ϝϞIDɿ</div> <div th:text="${memoId}"></div> </body> </html> SFDFJWFEIUNM <!doctype html> <html xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"/> <title>༰</title> </head> <body> <div th:text="${content}"></div> </body> </html> WJFXIUNM
!3FQPTJUPSZ ӬଓԽͷͨΊͷ࣮Λ%*ίϯςφʹొ ͢ΔͨΊͷΞϊςʔγϣϯ
%*ίϯςφ %FQFOEFODZ*OKFDUJPO͍࣮ͨ͠Λొ ͓ͯ͘͠ॴ
!"VUPXJSFE %*ίϯςφ͔Βͯ·Δ࣮Λೖ͢Δ ͨΊͷΞϊςʔγϣϯ
ʁʁʁ
ԿΛ͍͔ͨ͠
$POUSPMMFSͷཱ͔Β͢Δͱʜ ˠड͚औͬͨϝϞͷ༰ͷӬଓԽΛґཔ͍ͨ͠ɻ ˠӬଓԽઌ%#ͰϑΝΠϧͰϝϞϦ্Ͱ΄͍͠ͱ͖ʹऔΓग़ͤΕ Ͳ͜Ͱ͍͍ɻ ˠ࣮ʹґଘͨ͘͠ͳ͍ ˠΠϯλϑΣʔε͚͍ͩͬͯͨ ˠదͳ࣮Λউखʹࠩ͠ࠐΜͰ΄͍͠ ґଘੑٯసͷ๏ଇ
ґଘੑΛٯసΠϯλϑΣʔεʹͯ·Δ࣮ Λࠩ͠ࠐΉ ˠ%FQFOEFODZ*OKFDUJPO
͡Ό͋ԿΛࠩ͠ࠐΉ͔ ˠ%*ίϯςφʹొ͞Ε͍ͯΔͷͷͳ͔͔Βͦ ͷΠϯλʔϑΣʔεΛ࣮͍ͯ͠ΔͷΛࠩ͠ࠐΉ ͳͷͰಉ͡ΠϯλʔϑΣʔεΛ࣮͍ͯ͠Δ ͷ͔̍ͭ͠%*ίϯςφʹొͰ͖ͳ͍
ϝϞϦʹอଘ͢ΔͷΊͯ .Z42-Λ͍͍ͨ߹
package com.yachiy.spring.introduction.dao; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; // @Repository
public class InMemoryMemoDao implements MemoDao { private static final List<String> memoList = new ArrayList<>(); @Override public int store(String content) { memoList.add(content); return memoList.size(); } @Override public String findById(int id) { return memoList.get(id - 1); // 0࢝·Γͳͷ Ͱ-1 } } *O.FNPSZ.FNP%BPKBWB ίϝϯτΞτ package com.yachiy.spring.introduction.dao; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.List; @Repository public class MySQLMemoDao implements MemoDao { @Override public int store(String content) { JdbcTemplate …. } @Override public String findById(int id) { JdbcTemplate …. } } .Z42-.FNP%BPKBWB ͪ͜ΒΛ%*ίϯςφʹొ
package com.yachiy.spring.introduction.controller; import com.yachiy.spring.introduction.dao.MemoDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @Controller public class MemoController { private MemoDao memoDao; @Autowired public MemoController(MemoDao memoDao) { this.memoDao = memoDao; } @GetMapping("/") public String memo() { return "memo"; } @PostMapping("/") public String receive(MemoForm memoForm, Model model) { int memoId = memoDao.store(memoForm.getContent()); model.addAttribute("memoId", memoId); return "received"; } @GetMapping("/{memoId}") public String view(@PathVariable int memoId, Model model) { String content = memoDao.findById(memoId); model.addAttribute("content", content); return "view"; } } .FNP$POUSPMMFSKBWB มߋҰͳ͠
ಈ͔ͯ͠ΈΔ
CPPU3VOͯ͠MPDBMIPTUʹΞΫηε
ԡԼ
อଘ͞ΕͨϝϞͷ*%
MPDBMIPTU\NFNP*E^ʹΞΫηε
ϝϞͷ༰͕ग़ྗ͞Εͯ ͍Δ͜ͱΛ֬ೝ
ೖग़ྗ0,
ίϝϯτΛॻ͖ࠐΊΔϝϞாΛߟ͑Δ ʢߦͷ్தʹίϝϯτೖΕͯແࢹ͢Δʣ ༰Λॻ͚Δ ೖྗ༰ΛอଘͰ͖Δ ίϝϯτ͕ফ͑ͨঢ়ଶͰ༰͕ݟΕΔ
ͬͱۀϩδοΫ
ࠓճͷۀ ίϝϯτΛফ͢
ίϝϯτΛফ͢λΠϛϯάͲͪΒ͕ྑͦ͞͏͔ อଘ͢Δͱ͖ʹίϝϯτΛফ͔ͯ͠Βอଘ ͢Δ ੜσʔλΛอଘͯ͠ϝϞΛ֬ೝ͢Δͱ͖ʹ ίϝϯτΛফ͢
ݕ౼
อଘ࣌ʹίϝϯτΛফ͢ύλʔϯ ίϝϯτΛফ͢ॲཧ͕ͳͯ͘ࡁΉʢελΠϧ ͯΔͷอଘ࣌ͷΈʣ ੜσʔλͷ֬ೝෆՄ औಘ࣌ʹίϝϯτΛফ͢ύλʔϯ ੜσʔλΛ֬ೝͰ͖Δ ֬ೝͷͨͼʹίϝϯτΛফ͢ඞཁ͕͋Δ
࣮ࡍʹۀͷࠓޙΛߟ͑Δͱʜ ฤूػೳཉ͘͠ͳΓͦ͏ ˠͦͷͱ͖ʹੜσʔλͰฤू͍ͨ͠ ˠίϝϯτΛফͯ͠อଘ͢ΔͱͦͷใࣦΘ Εͯ͠·͏ ˠࠓճͷۀͰফͨ͠ঢ়ଶͰอଘ͍͚ͯ͠ ͳ͍
ͲͬͪͰ͍͍߹Έ ʢˍνʔϜͰͷܾΊʣ
package com.yachiy.spring.introduction.service; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class
CommentOutService { public String execute(String content) { List<String> lines = Arrays.asList(content.split("\r\n")); List<String> markUpList = lines.stream() .map(this::commentOut) .collect(Collectors.toList()); return String.join("\r\n", markUpList); } private String commentOut(String content) { if (content.matches("//.+")) { return ""; } return content; } } $PNNFOU0VU4FSWJDFKBWB
package com.yachiy.spring.introduction.controller; import com.yachiy.spring.introduction.dao.MemoDao; import com.yachiy.spring.introduction.service.CommentOutService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @Controller public class MemoController { private MemoDao memoDao; @Autowired public MemoController(MemoDao memoDao) { this.memoDao = memoDao; } @GetMapping("/") public String memo() { return "memo"; } @PostMapping("/") public String receive(MemoForm memoForm, Model model) { int memoId = memoDao.store(memoForm.getContent()); model.addAttribute("memoId", memoId); return "received"; } @GetMapping("/{memoId}") public String view(@PathVariable int memoId, Model model) { String content = memoDao.findById(memoId); model.addAttribute("content", new CommentOutService().execute(content)); return "view"; } } .FNP$POUSPMMFSKBWB ίϝϯτΞτͷۀ ϩδοΫΛݺग़
CPPU3VOͯ͠MPDBMIPTUʹΞΫηε
ԡԼ
MPDBMIPTU\NFNP*E^ʹΞΫηε
ίϝϯτ͕ফ͍͑ͯΔ͜ͱ Λ֬ೝ
ΞʔΩςΫνϟΛ࣮ݱͰ͖ͨ
େࣄͳͷ֤ͷׂ͕ଞͷʹછΈग़͞ ͳ͍͜ͱ ಛʹۀϩδοΫଞͷʹછΈग़͕ͪ͠ ͳͷͰҙࣝͯ͠ઃܭ͢Δ