Intro
π μ°λ¦¬λ μ§λ μκ°μ, μμ μΉ μ΄ν리μΌμ΄μ μ΄ μ΄λ ν μλ¦¬λ‘ μ΄λ»κ² λμνλμ§, κ·Έ μ€μ μΉμλ²(μ ννλ Web Application Server)λ μ΄λ»κ² λμνλμ§ μμ£Ό κ°λ΅νκ² μμλ΄€μ΅λλ€. μ΄λ² μκ°μλ μλ²κ° ν΄μ£Όλ μΌμ μ‘°κΈ λ μμΈν μ΄ν΄λ³΄κ³ , μ€νλ§, μ€νλ§λΆνΈμ λν μκ°λ₯Ό κ°λ μκ°μ κ°μ Έλ³΄λ©΄ μ’μ κ² κ°μ΅λλ€.
π€ Issue : μλΉμ€μ κ·λͺ¨κ° 컀μ§λ©΄ μ°λ¦¬κ° flask μλ²μμ μμ±νλ κ² κ³Ό κ°μ΄ νλ‘κ·Έλλ°μ ν μ μμ΅λλ€.
μλΉμ€ λ‘μ§μ΄ μ»€μ Έκ°μλ‘ μ°κ΄λ λ°μ΄ν°λ ν¨μ¬ λ λ§μμ§κ³ , μ²λ¦¬ν΄μΌ ν λ‘μ§μ λ 볡μ‘ν΄μ§κ³ , μ¬μ§μ΄λ μ΄κ²λ€μ΄ λ§λ¬Όλ € νλ‘κ·Έλ¨μ 볡μ‘λλ κΈ°νκΈμμ μΌλ‘ μ¬λΌκ°λλ€. νΉν νλ‘κ·Έλ¨μ λ‘μ§μ΄ μμ λμ΄μΌ νκ±°λ μ΄λ―Έ λμνλ μλ²μμ μλ‘μ΄ κΈ°λ₯μ μΆκ°νλ건 μ¬μ€μ λΆκ°λ₯ν΄μ§λ μμ μ λλ¬νκ²λκ³ , κ²°κ΅ μ€ν¨λ₯Ό μΈμ νκ³ μμ μλ²λ νλ‘κ·Έλ¨μ μλ‘ λ§λλ μΌλ μ¬μ¬μΉ μκ² μΌμ΄λ©λλ€.
κ·Έλλ§ λ€νμΈ μ μ, μ°λ¦¬μ μ λ°° κ°λ°μλ€μ΄ μ΄μ κ°μ μ€ν¨λ‘ μ»μ κ΅νμ΄ νλμ§ μκ² λ§μ μλ£μ μ¬λ‘λ₯Ό λ¨κ²¨λμκ³ , μ§κΈμ “~~ν¨ν΄” λλ “~~μν€ν μ³λ‘’ λΆλ¦¬μ°κ³ μμ΅λλ€. μ°λ¦¬λ μ΄λ¬ν κ²λ€μ 곡λΆνλ κ² λ§μΌλ‘λ κ·Έλ€μ΄ νμλ μ€μλ₯Ό λ°λ³΅νμ§ μκ³ κ°μΈμ μμ²μκ°, λλ£λ€μ μλ§μκ°μ μλ μ μμ΅λλ€.
μννΈμ¨μ΄ λμμΈ ν¨ν΄(software design pattern)μ μννΈμ¨μ΄ 곡νμ μννΈμ¨μ΄ λμμΈμμ νΉμ λ¬Έλ§₯μμ 곡ν΅μ μΌλ‘ λ°μνλ λ¬Έμ μ λν΄ μ¬μ¬μ© κ°λ₯ν ν΄κ²°μ± μ΄λ€. μμ€λ κΈ°κ³ μ½λλ‘ λ°λ‘ μ νλ μ μλ μμ±λ λμμΈμ μλλ©°, λ€λ₯Έ μν©μ λ§κ² μ¬μ©λ μ μλ λ¬Έμ λ€μ ν΄κ²°νλλ°μ μ°μ΄λ μμ μ΄λ ν νλ¦Ώμ΄λ€. λμμΈ ν¨ν΄μ νλ‘κ·Έλλ¨Έκ° μ΄ν리μΌμ΄μ μ΄λ μμ€ν μ λμμΈν λ 곡ν΅λ λ¬Έμ λ€μ ν΄κ²°νλλ°μ μ°μ΄λ νμν λ κ°μ₯ μ’μ κ΄νμ΄λ€.
Software Architecture Patterns
μννΈμ¨μ΄ μν€ν μ² ν¨ν΄
π€ λμμΈ ν¨ν΄μ 곡λΆνλ κ² μμ λ§€μ° μ€μν μ£Όμ μ΄μ§λ§, μμΉ« λ무 λ§Ήμ νλ €κ³ λ€λ©΄ λ μ€νλ € λ§€μ° ν° μν¨κ³Όλ₯Ό λ§μ£Όνλ€κ³ ν©λλ€. μ§κΈ λΉμ₯μ λ μ€μν λ°°μΈκ±°λ¦¬κ° λ§κΈ°λ νκ³ νΉμ ν¨ν΄λ±μ λ§μ£Ό ν λ λ§λ€ νμ€ν μ΄ν΄νκ³ μΈμ§νκ³ λμ΄κ°λ μ λμ 곡λΆκ° μ§κΈμ κ°μ₯ μ’μ κ² κ°μ΅λλ€.
볡μ‘ν λ¬Έμ λ₯Ό ν΄κ²°νλ λ°©λ²- λ¬Έμ λ₯Ό λλμ!
μ€μ λ‘ λ³΅μ‘ν λ¬Έμ λ₯Ό μν€ν μ² μ μΌλ‘ ν΄κ²°νλ λ°©λ²μ λ§€μ° λ€μνμ§λ§ μ£Όλ‘ λ¬Έμ λ₯Ό λλλ λ°©μμ΄ κ°μ₯ μ μ©λ©λλ€. μ§λ μκ°μ μ΄μΌκΈ°λ€κ³Ό μΉκ°λ° νλ¬μ€ κ°μλ₯Ό ν΅ν΄ μ¬λ¬λΆλ€μ΄ ꡬνν΄λ μμλ‘ μκ²λ λ΄μ©μ μλ κ·Έλ¦Όκ³Ό κ°μ΅λλ€. μ°λ¦¬μ μλ²λ “μλ‘μ΄ λ°μ΄ν°λ₯Ό μ²λ¦¬νλ λΆλΆ”, “μλΉμ€ λ‘μ§μ μ²λ¦¬νλ λΆλΆ”, **“κΈ°μ‘΄μ λ°μ΄ν°λ₯Ό μ΄μ©νλ λΆλΆ”**μΌλ‘ λμ΄ μμ΅λλ€. μ€μ λ‘ κ° λΆλΆμ μ€νλ§κ³Ό μ€νλ§λΆνΈμμ κ°κ°μ λ μ΄μ΄λ‘ λλμ΄μ Έ μμ΅λλ€.
λ μ΄μ΄λ μν€ν μ² ν¨ν΄
μΆμ² : https://jojoldu.tistory.com/603
Presentation κ³μΈ΅
μ¬μ©μμ μνΈ μμ© μ²λ¦¬ κ³μΈ΅
CLI, HTTP μμ², HTML μ²λ¦¬ λ±μ λ΄λΉνλ€.
HTTP μμ² μ²λ¦¬ λ° HTML λ λλ§μ λν΄ μκ³ μλ μΉ κ³μΈ΅
νν λ§νλ MVC (Model / View / Controller) λ μ΄ κ³μΈ΅μ μνλ€.
μ°λ¦¬κ° URLμ 맀νν΄μ νΉμ λ©μλκ° ν΄λΉ URLλ‘ μμ²μ΄ μ¬ λλ§λ€ νΈμΆλκ² νλ‘κ·Έλλ° νμμ£ ? κ·Έ κ³μΈ΅μ λ§νλ κ²μ΄λ©°, μ€νλ§μμλ @Controller μ΄λ Έν μ΄μ μ μ¬μ©νμ¬ ννν©λλ€!
Domain(Business or Service) κ³μΈ΅
μλΉμ€/μμ€ν μ ν΅μ¬ λ‘μ§
μ ν¨μ± κ²μ¬ λ° κ³μ°μ ν¬ν¨νλ Business λ Όλ¦¬ κ³μΈ΅
μ ν리μΌμ΄μ μ΄ μνν΄μΌνλ λλ©μΈκ³Ό κ΄λ ¨λ μμ λ€μ λ΄λΉνλ€.
μ λ ₯/μ μ₯λ λ°μ΄ν°λ₯Ό κΈ°λ°μΌλ‘ κ³μ°
Presentation κ³μΈ΅μμ λ°μ λ°μ΄ν°μ μ ν¨μ± (Validation) κ²μ¬
μ΄λ€ Data Access λ₯Ό μ νν μ§ κ²°μ
μ°λ¦¬μ μλ² νλ‘κ·Έλ¨μ΄ 볡μ‘ν΄μ§λ©΄, λΉμ¦λμ€ λ‘μ§μ μννκΈ° μν λ³λμ κ³μΈ΅(Layer)μ΄ νμν©λλ€. μ¬μ€ λ μ΄μμ μΌλ‘λ μ λ₯ν μλ² νλ μμν¬λ₯Ό μ¨μ Presentaion, Data Accessκ³μΈ΅μλ λ³λ‘ ν μΌμ΄ μκ³ , λλ©μΈ κ³μΈ΅μ΄ λΉλν΄μ§λκ² κ°μ₯ μ’μ΅λλ€. μ€νλ§μμλ @Service μ΄λ Έν μ΄μ μ μ¬μ©ν΄μ ννν©λλ€!
Data Access(Persistence) κ³μΈ΅
DAO κ³μΈ΅
Database / Message Queue / μΈλΆ APIμμ ν΅μ λ± μ²λ¦¬
λ°μ΄ν°λ² μ΄μ€ λλ μ격 μλΉμ€μμ μꡬ λ°μ΄ν°λ₯Ό κ΄λ¦¬νλ λ°©λ²μ λΆλ₯νλ λ°μ΄ν° μ κ·Ό κ³μΈ΅
μ°λ¦¬μ λ°μ΄ν°λ² μ΄μ€, νΉμ λ°μ΄ν°λ₯Ό μ μ₯νλ λ°μ΄ν° μμ€λ μλ² μΈλΆμ λ³κ°λ‘ μ‘΄μ¬νλ κ²½μ°κ° λ§€μ° λ§κ³ , κ·Έλ¬ν λ°μ΄ν° μμ€μμ μν΅μ ν΄μ£Όλ κ³μΈ΅μ΄λΌκ³ μκ°νμλ©΄ λ κ² κ°μ΅λλ€. μ€νλ§μμλ @Repository μ΄λ Έν μ΄μ μ μ¬μ©ν΄μ ννν©λλ€.
π μλ κ·Έλ¦Όμ μλ²λ₯Ό λ μ€ν λμΌλ‘ λΉμ ν μμμ΄λ©°, μ΄ κ·Έλ¦Όμ ν΅ν΄ κ°κ°μ κ³μΈ΅κ³Ό μ€νλ§μμμ ν΄λΉ μ΄λ Έν μ΄μ μ΄ μ΄λ ν μΌμ νλμ§ κ°μ μ‘μΌλ©΄ μ’μ κ² κ°μ΅λλ€.
Controller, Service, Respository μ€μ μ½λλ€
π κ°κ°μ λ μ΄μ΄μ μ€μ μ½λλ€μ νλνλ μμΈν μ΄ν΄λ³Ό μμ μ λλ€! μ§κΈμ μ΄λ°κ² μλ€λ μκ°μΌλ‘ κ°λ³κ² λ΄μ£Όμκ³ μ€μ μ€μ΅μμ μμ κ°μ μ½λλ€μ μ§μ μ³λ³΄λ©΄μ νμ΅ ν μμ μ λλ€.
Controller μμ μ½λ
@Controller // #1
public class ContentController {
private final ContentService contentService; // #2
@GetMapping("/content/{contentId}") // #3
public Content getContent(@PathVariable Long contentId) { // #4
Content content = contentService.getContent(requestDto); //#2-1
return "/contentPage";
}
@PostMapping("/content") //#5
@ResponseBody// #6
public Content createContent(@RequestBody ContentRequestDto requestDto) {
Content content = contentService.createContent(requestDto);
return content;
}
}
#1 : μ΄ μλ° κ°μ²΄κ° 컨νΈλ‘€λ¬ μν μ νλ κ°μ²΄λΌλ κ²μ μλ €μ£Όλ μ΄λ Έν μ΄μ μ λλ€!
#2 : κ°κ°μ λ μ΄μ΄λ “μΌλ°μ μΌλ‘” μκΈ°μ μΈμ ν λ μ΄μ΄μ μ§μ μν΅ν©λλ€, μ΄ κ²½μ° ContentServiceκ°μ²΄λ₯Ό κ°μ§κ³ μμ΄, 컨νΈλ‘€λ¬ λ¨μμ μλΉμ€ λ¨μΌλ‘ μλ‘ λ°μμ¨ λ°μ΄ν°λ₯Ό μ λ¬νκ±°λ μλΉμ€ λ‘μ§μ νΈμΆ ν μ μμ΅λλ€. μλ₯Όλ€μ΄ #2-1 μ²λΌ λ§μ΄μ£ !
#3 : νλΌμ€ν¬μ @app.route(”/”)μ λΉμ·ν΄μ μ΄λ―Έ μ§μνμ ¨κ² μ§λ§, νΉμ μμ²μ νΈμΆλ λ©μλλ₯Ό μ§μ ν΄μ£Όλ μ΄λ Έν μ΄μ μ λλ€!
#4 : ν΄λΉ λ©μλμ λκΈ°λ μΈμκ°μ μμ½κ² λκΈ°λλ‘ μμ κ°μ μ΄λ Έν μ΄μ μ μ¬μ© ν μ μμ΅λλ€, μ΄λ¬ν μ΄λ Έν μ΄μ μ΄ μμΌλ©΄ μλμΌλ‘ μΌμΉνλ λ³μκ°μ λ©μλ νΈμΆλλ μμ μ κ°μ΄ λ겨μ€λλ€. (μ‘°κΈ λ€μ μ΄ν΄νμ λ μ’μ΅λλ€!)
#5 : #3κ³Ό #5κ° λ€λ₯Έ μ΄μ λ HttpMethodμ λ°λΌμ λ€λ₯Έ Controller λ©μλλ₯Ό μ°κ²°ν΄μ€ μ μκΈ° λλ¬Έμ λλ€, κ°μ μ£Όμλ‘ μ¨ GET μμ²κ³Ό POSTμ λλ μ κ°κ° μ²λ¦¬νκΈ°μ μ©μ΄νκ² μ£ ?
#6 : μμ λ©μλμ μλμ λ©μλλ μ΄μ μ λ°°μ λ, λ·°κΉμ§ κ°μ΄ λ°ννλλ, νΉμ JSON νμμΌλ‘ λ°μ΄ν°λ§ λ°ννλλμ μ°¨μ΄κ° μμ΅λλ€. μ΄ λΆλΆλ λμ€μ μμΈν νμ΅νκ² μ΅λλ€.
Service μμ μ½λ
@Service // #1
public class ContentService {
private final ContentRepository contentRepository; //#2
public ReturnDto getContent(Long id) {
ReturnDto returnDto = contentRepository.findById(id);
return returnDto; //#3
}
public Content createContent(ContentRequestDto contentRequestDto) {
Content content = new Content(contentRequestDto);
contentRepository.save(content);
return content;
}
}
#1 : λ§μ°¬κ°μ§λ‘ μ΄ μλ° κ°μ²΄κ° μλΉμ€ μν μ νλ κ°μ²΄λΌλ κ²μ μλ €μ£Όλ μ΄λ Έν μ΄μ μ λλ€!
#2 : μΈμ ν κ³μΈ΅μΈ Repository κ°μ²΄λ₯Ό κ°μ§κ³ μμ΄μΌ κ² μ£ ?
#3 : μ¬μ€ μ΄ λΆλΆ μμ μΈμ ν κ³μΈ΅μΌλ‘ λ°μ΄ν°λ₯Ό μ λ¬νλ μ€ μ λλ€. μ΄ν΄κ° μκ°μ λ€λ©΄ μ΄ νμ΄μ§μ λ΄μ©μ λ€μ μ½μ΄λ³΄μλ©΄ μ’μ κ² κ°λ€μ!
Repository μμ μ½λ
@Repository
public interface ContentRepository extends JpaRepository<Content, Long> {
}
#1 : λ§μ°¬κ°μ§λ‘ μ΄ μλ° κ°μ²΄κ° μλΉμ€ μν μ νλ κ°μ²΄λΌλ κ²μ μλ €μ£Όλ μ΄λ Έν μ΄μ μ λλ€!
#2 : μ¬μ€ 리ν¬μ§ν 리λ μλΉν λ€μν κΈ°μ κ³Ό μ½ν μκ³ λ€μν μΌμ΄μ€κ° μμ΄ μμ μ½λλ₯Ό 보μ¬λ리기λ μ‘°κΈ μ΄λ €μ΄ κ² κ°κΈ°λ ν©λλ€. κ·Έλλ μ°λ¦¬κ° μ§μ μ¬μ©νκ² λ SpringDataJpa μ JpaRepositoryλ μ΄μ λλ‘ μκ²Όλ€μ
Outro
Outro 1. IOC? DI?
private final ContentService contentService; // #2
private final ContentRepository contentRepository; //#2
μλ°λ₯Ό μ λ§ μ΄μ¬ν 곡λΆνμκ³ , μ€νλ§λ§ μ²μμ΄λΌλ©΄ μμ κ°μ μ½λμ μνκ°μ λλΌμ ¨μ κ²λλ€.
λΆλͺ ν΄λΉ κ°μ²΄μ λ©μλλ νΈμΆνκ³ μλλ°, ν΄λΉ κ°μ²΄λ μ΄λμ μ΄λ»κ² λ€μ΄μμμκΉμ?
μ΄μΈμλ μμΌλ‘ μ§μ½μ μΈ μ»¨νΈλ‘€λ¬λ 리ν¬μ§ν 리 μλΉμ€μͺ½ μ½λλ₯Ό 보κ²λλ€ λ³΄λ©΄
μλ° λ¬Έλ²κ³Ό λ¬νκ² λ€λ₯Έ λΆλΆλ€μ΄ λ³΄μΌ κ²λλ€.
λλ‘ μ΄λ ν μ§μμ λ€μ λ΄μ©μ μμμΌ μ΄ν΄κ° λ μ¬μ΄ κ²½μ°κ° μμ΄ μ§κΈ μ€λͺ νμ§λ μκ² μ΅λλ€.
μμκ°μ΄ κΈ°μ‘΄κΉμ§ μκ³ κ³μλ μλ° λ¬Έλ²κ³Ό λ€λ₯Έ λΆλΆμ κΌ λ©λͺ¨λ₯Ό νμκ³ μμν΄ νμλ μ΅κ΄μ κ°μ§μλ©΄,
μ΄ν IOC, DI λ± μ€κ³ μ² ν λ±μ λ°°μ°κ³ μ΄ν΄νλλ° ν° μμ°μ΄ λ κ² κ°μ΅λλ€.
Outro 2. μ€νλ§/μ€νλ§λΆνΈλ₯Ό μ¬μ©νλ μ΄μ ?
μ΄ λΆλΆλ μ§κΈμ μλΏκΈ° μ΄λ €μ΄ μ΄μ μΌ μ μμ΅λλ€.
λ€λ§ μ§κ²Ήκ³ 곡λΆν΄μΌ ν λ§μ λΆλΆλ€μ΄ μ λΆ κ³΅λΆν΄μΌ ν μ΄μ κ° μμ΅λλ€.
κ²°λ‘ μ μΌλ‘λ μμ μ λΆνΈνλ κ²λ€μ μ λ§ νκΈ°μ μΌλ‘ νΈνκ² ν΄μ€¬κΈ° λλ¬Έμ μ€νλ§ νλ μμν¬λ₯Ό μ¬μ©νλλ°,
ꡬ체μ μΈ μ€νλ§μ κ΄λ ¨λ λ΄μ©μ νμ΅νλ€ λ³΄λ©΄ μ μ€νλ§μ΄ νΈνμ§λ₯Ό μκ°μμΌλ리λ κ³κΈ°κ° μμ κ² κ°μ΅λλ€.
π€ κ·Έλλ μΌλ°μ μΌλ‘ κ°μ₯ λ§μ΄ κΌ½λ μ΄μ λ‘λ, λ¨μ λ°λ³΅μμ λΆλΆμ΄ λ§μλ Controllerμ Repositoryμͺ½μ κ°λ° κ΄μ μμ λ§€μ° μ½κ³ νΈνκ² μ²λ¦¬ν΄μ€ κ°μ₯ μ€μν ν΅μ¬ λΉμ¦λμ€ λ‘μ§μΈ Service λ μ΄μ΄μ λ μ§μ€ ν μ μλλ‘ νκ² ν΄μ€λ€λ μ΄μ λ₯Ό κΌ½κΈ°λ ν©λλ€.
'κ°λ° > Spring' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
spring μλ² μ°κ²° λ©λͺ¨λ§λ€κΈ° (0) | 2023.02.04 |
---|---|
mvc (0) | 2023.02.04 |
JPA μ°μ΅! (0) | 2023.02.04 |
SQL μ€μ λ° μ°μ΅! (0) | 2023.02.03 |
μΉ λμλ°©μ μ΄ν΄νκΈ° (1) | 2023.02.03 |