객체 지ν–₯ 섀계와 μŠ€ν”„λ§

2022. 1. 26. 10:50ㆍBackend/🌿 Spring

μŠ€ν”„λ§ 핡심 원리 - 기본편 μˆ˜κ°• ν›„ μ •λ¦¬ν•œ ν¬μŠ€νŒ…μž…λ‹ˆλ‹€.
 

μŠ€ν”„λ§ 핡심 원리 - 기본편 - μΈν”„λŸ° | κ°•μ˜

μŠ€ν”„λ§ μž…λ¬Έμžκ°€ 예제λ₯Ό λ§Œλ“€μ–΄κ°€λ©΄μ„œ μŠ€ν”„λ§μ˜ 핡심 원리λ₯Ό μ΄ν•΄ν•˜κ³ , μŠ€ν”„λ§ κΈ°λ³ΈκΈ°λ₯Ό ν™•μ‹€νžˆ λ‹€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€., - κ°•μ˜ μ†Œκ°œ | μΈν”„λŸ°...

www.inflearn.com

 

 

1. μŠ€ν”„λ§μ΄λž€

 

μŠ€ν”„λ§μ˜ 핡심 νŠΉμ§•

1. μžλ°” μ–Έμ–΄ 기반의 ν”„λ ˆμž„μ›Œν¬

2. μžλ°”μ˜ 큰 νŠΉμ§•: 객체 지ν–₯ μ–Έμ–΄

3. 즉 객체 지ν–₯ μ–Έμ–΄κ°€ 가진 κ°•λ ₯ν•œ νŠΉμ§•μ„ μ‚΄λ €λ‚Ό 수 μžˆλŠ” ν”„λ ˆμž„μ›Œν¬ : Spring

4. μ •λ¦¬ν•˜μžλ©΄, 쒋은 객체 지ν–₯ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ°œλ°œν•  수 μžˆλ„λ‘ λ„μ™€μ£ΌλŠ” ν”„λ ˆμž„μ›Œν¬

 

 

쒋은 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ΄λž€?

 

1. 객체 지ν–₯의 μ •μ˜ : ν˜„μ‹€μ„Έκ³„λ₯Ό μ½”λ“œλ‘œ λ°˜μ˜ν•˜μ—¬, ν”„λ‘œκ·Έλž¨ κ΅¬ν˜„μ— ν•„μš”ν•œ 객체(ex ν˜„μ‹€μ˜ 사물, etc)λ₯Ό νŒŒμ•…ν•˜κ³  κ°μ²΄κ°„μ˜ 역할에 λ§žλŠ” μƒν˜Έμž‘μš©μ„ 톡해 ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“œλŠ” 것

2. μœ μ—°ν•˜κ³  변경이 μš©μ΄ν•¨ => λ‹€ν˜•μ„±(polymorphism)

 

 

λ‹€ν˜•μ„±μ˜ 싀세계 λΉ„μœ 

 

1. μžλ™μ°¨κ°€ λ°”λ€Œμ–΄λ„ μš΄μ „μžλŠ” μ—¬μ „νžˆ μš΄μ „μ„ ν•  수 μžˆλ‹€. 

2. μš΄μ „μžλŠ” μžλ™μ°¨λΌλŠ” μ—­ν• (μΈν„°νŽ˜μ΄μŠ€) μ—λ§Œ 집쀑/μ˜μ‘΄ν•˜κ³  μžˆλ‹€. μš΄μ „μžλŠ” μžλ™μ°¨ λ‚΄λΆ€ ꡬ쑰λ₯Ό λͺ°λΌλ„, μ„œλ‘œ λ‹€λ₯Έ μ’…λ₯˜μ˜ μžλ™μ°¨λ₯Ό μš΄μ „ν•  수 μžˆλ‹€.

3. ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 영ν–₯을 μ£Όμ§€μ•Šκ³  μƒˆλ‘œμš΄ κΈ°λŠ₯을 κ΅¬ν˜„ν•  수 μžˆλ‹€.

4. μƒˆλ‘œμš΄ μžλ™μ°¨κ°€ λ‚˜μ™€λ„ *ν΄λΌμ΄μ–ΈνŠΈλŠ” 아무 λ¬Έμ œκ°€ μ—†λ‹€.  => 이것이 μœ μ—°ν•˜κ³  λ³€κ²½ μš©μ΄ν•˜λ‹€λŠ” 뜻

 

* ν΄λΌμ΄μ–ΈνŠΈ : ν΄λΌμ΄μ–ΈνŠΈ : 호좜, μ„œλ²„ : 응닡  ➑️ ν˜ΈμΆœλ˜λŠ” μ½”λ“œλ₯Ό μ„œλ²„μ½”λ“œλΌκ³  ν•˜λ©΄, μ„œλ²„ μ½”λ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” λͺ¨λ“  μ½”λ“œ(객체, 클래슀) κ°€ ν΄λΌμ΄μ–ΈνŠΈμ΄λ‹€.

 

μ—­ν• κ³Ό κ΅¬ν˜„μ„ 뢄리

 

μ—­ν• κ³Ό κ΅¬ν˜„μœΌλ‘œ κ΅¬λΆ„ν•˜λ©΄ 세상이 λ‹¨μˆœν•΄μ§€κ³ , μœ μ—°ν•΄μ§€λ©° 변경도 νŽΈλ¦¬ν•΄μ§„λ‹€.

  • μž₯점
    • ν΄λΌμ΄μ–ΈνŠΈλŠ”
      •  λŒ€μƒμ˜ μ—­ν• (μΈν„°νŽ˜μ΄μŠ€)만 μ•Œλ©΄ λœλ‹€.
      • κ΅¬ν˜„ λŒ€μƒμ˜ λ‚΄λΆ€ ꡬ쑰λ₯Ό λͺ°λΌλ„ λœλ‹€.(μžλ™μ°¨ ꡬ쑰)
      • κ΅¬ν˜„ λŒ€μƒμ˜ λ‚΄λΆ€ ꡬ쑰가 λ³€κ²½λ˜μ–΄λ„ 영ν–₯ 받지 μ•ŠλŠ”λ‹€.
      • κ΅¬ν˜„ λŒ€μƒ 자체λ₯Ό 변경해도 영ν–₯을 받지 μ•ŠλŠ”λ‹€.

 

μžλ°” μ–Έμ–΄μ˜ λ‹€ν˜•μ„±μ„ ν™œμš©

  • μ—­ν•  = μΈν„°νŽ˜μ΄μŠ€
  • κ΅¬ν˜„ = μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 클래슀, κ΅¬ν˜„ 객체 
  • μ€‘μš”ν•œ 점은, 객체 μ„€κ³„μ‹œ 역할을 λ¨Όμ € λΆ€μ—¬ν•˜κ³ , κ·Έ 역할을 μˆ˜ν–‰ν•˜λŠ” κ΅¬ν˜„ 객체 λ§Œλ“€ 것.

 

객체의 ν˜‘λ ₯μ΄λΌλŠ” 관계뢀터 생각

  • ν˜ΌμžμžˆλŠ” κ°μ²΄λŠ” μ—†λ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈ: μš”μ²­, μ„œλ²„: 응닡 이며, μˆ˜λ§Žμ€ 객체 ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„λŠ” ν˜‘λ ₯ 관계λ₯Ό 가진닀.

 

μžλ°” μ–Έμ–΄μ˜ λ‹€ν˜•μ„±

  • μ˜€λ²„λΌμ΄λ”© => μ˜€λ²„λΌμ΄λ“œ 된 λ©”μ„œλ“œκ°€ μ‹€ν–‰λœλ‹€.
  • λ‹€ν˜•μ„±μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 객체λ₯Ό μ‹€ν–‰ μ‹œμ μ— μœ μ—°ν•˜κ²Œ λ³€κ²½ν•  수 μžˆλ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³ , μ„œλ²„μ˜ κ΅¬ν˜„μ„ μœ μ—°ν•˜κ²Œ λ³€κ²½ν•  수 μžˆλ‹€. (JDBC <=> MemoryRepository)
    • ex) 기쑴에 jDBC에 μ €μž₯ν•˜λ˜ 데이터λ₯Ό MemoryRepository 에도 μ €μž₯ν•΄μ•Όν•  λ•Œ, λΉ„μ¦ˆλ‹ˆμŠ€λ‘œμ§μ„ λ³€κ²½ν•˜μ§€ μ•Šμ•„λ„, μœ μ—°ν•˜κ²Œ DB λ₯Ό ꡐ체할 수 μžˆλ‹€ (μœ μ—°μ„±)

 

μŠ€ν”„λ§κ³Ό 객체 지ν–₯

  •  κ°μ²΄ 지ν–₯의 꽃은 λ‹€ν˜•μ„±!
  •  μŠ€ν”„링은 λ‹€ν˜•μ„±μ„ κ·ΉλŒ€ν™”ν•  수 있게 도와주기에, 레고 λΈ”λŸ­ μ‘°λ¦½ν•˜λ“―μ΄ κ°μ²΄κ°„μ˜ 관계λ₯Ό μœ μ—°ν•˜κ²Œ 섀계할 수 μžˆλ‹€.
  •  SOLID λΌλŠ” κ°œλ…μ„ μ•Œμ•„μ•Όν•œλ‹€. 

 


 

2. 쒋은 객체 지ν–₯ μ„€κ³„μ˜ 5가지 원칙 (SOLID)

SOLID: 쒋은 객체 지ν–₯ μ„€κ³„μ˜ 5가지 원칙

 

SRP: Single Responsibility Principle

  • ν•˜λ‚˜μ˜ ν΄λž˜μŠ€λŠ” ν•˜λ‚˜μ˜ μ±…μž„λ§Œ 가진닀.
  • ν•˜μ§€λ§Œ ν•˜λ‚˜μ˜ μ±…μž„μ΄λΌλŠ” λœ»μ€ λͺ¨ν˜Έν•˜λ‹€
    • μ±…μž„μ΄ 클 μˆ˜λ„ 있고, μž‘μ„ μˆ˜λ„ μžˆλ‹€.
    • λ¬Έλ§₯κ³Ό 상황에 따라 μ±…μž„μ€ λ‹¬λΌμ§ˆ 수 μžˆλ‹€.
  • 변경이 μžˆμ„ λ•Œ νŒŒκΈ‰νš¨κ³Όκ°€ 적으면 단일 μ±…μž„ 원칙을 잘 λ”°λ₯Έ 것.
  • λ„ˆλ¬΄ 크지도, μž‘μ§€λ„ μ•Šλ„λ‘ 적절히 μ±…μž„μ„ κ·œμ •ν•˜λŠ”κ²Œ 객체지ν–₯ μ„€κ³„μ˜ 묘미

 

OCP: Open/Closed Principle

  • μ†Œν”„νŠΈμ›¨μ–΄ μš”μ†ŒλŠ” ν™•μž₯μ—λŠ” μ—΄λ €μžˆμœΌλ‚˜, λ³€κ²½μ—λŠ” λ‹«ν˜€μžˆμ–΄μ•Όν•œλ‹€.
  • μ—­ν• κ³Ό κ΅¬ν˜„μ˜ 뢄리λ₯Ό μƒκ°ν•΄λ³΄μž. 

μ•„λž˜ μ½”λ“œλŠ”, λ³€κ²½ν•˜κΈ° μœ„ν•΄ 주석 μ²˜λ¦¬ν•˜κ³  μƒˆλ‘œμš΄ μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Όν•œλ‹€ (변경에 λ‹«ν˜€μžˆμ§€ μ•Šμ€ μƒνƒœ = 변경에 μ—΄λ €μžˆλ‹€ = ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό 직접 λ³€κ²½ν•΄μ•Όν•œλ‹€.)

public class MemberServiceImpl implements MemberService{

    // κΈ°μ‘΄
//    private final MemberRepository memberRepository = new MemoryMemberRepository();

    // λ³€κ²½
    private final MemberRepository memberRepository = new JdbcMemberRepository();
    
    ...
}

 

λΆ„λͺ… λ‹€ν˜•μ„±μ„ μ‚¬μš©ν–ˆμ§€λ§Œ, OCP 원칙을 지킬 수 μ—†λ‹€. (<= κ΅¬ν˜„ 객체λ₯Ό λ³€κ²½ν•˜λ €λ©΄, κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³€κ²½ν•΄μ•Όν•œλ‹€.)

객체λ₯Ό μƒμ„±ν•˜κ³ , 연관관계λ₯Ό λ§Ίμ–΄μ£ΌλŠ” λ³„λ„μ˜ 쑰립, μ„€μ •μžκ°€ ν•„μš”ν•˜λ‹€. => 이 역할을 μŠ€ν”„λ§μ΄ ν•΄μ€€λ‹€. (후에 배울 AppConfig 클래슀의 μ—­ν• )

 

 

LSP: Liskov Substitution Principle

  • ex) μžλ™μ°¨μ˜ μ—‘μ…€ μΈν„°νŽ˜μ΄μŠ€λŠ” 전진 κΈ°λŠ₯을 가지며, 이λ₯Ό λ’€λ‘œ κ°€κ²Œ κ΅¬ν˜„ν•˜λ©΄ LSP μœ„λ°˜ν•˜λŠ” 것이닀. (λŠλ¦¬λ”λΌλ„ μ•žμœΌλ‘œ κ°€μ•Όν•œλ‹€.)
  • κ°μ²΄λŠ” ν”„λ‘œκ·Έλž¨μ˜ 정확성을 κΉ¨λœ¨λ¦¬μ§€ μ•ŠμœΌλ©΄μ„œ ν•˜μœ„ νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λ°”κΏ€ 수 μžˆμ–΄μ•Όν•œλ‹€.

 

ISP: Interface Segregation Principle

  • νŠΉμ • ν΄λΌμ΄μ–ΈνŠΈλ₯Ό μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€ μ—¬λŸ¬κ°œκ°€ λ²”μš© μΈν„°νŽ˜μ΄μŠ€ ν•˜λ‚˜λ³΄λ‹€ λ‚«λ‹€.
  • (= μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ—¬λŸ¬κ°œ 섀계해라 = ν•˜λ‚˜μ˜ μΌλ°˜ν™”λœ μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹Œ λͺ©μ μ— λ§žλŠ” μ—¬λŸ¬κ°œμ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€μ–΄λΌ)
  • ν•˜λ‚˜μ˜ κ±°λŒ€ν•œ μΈν„°νŽ˜μ΄μŠ€ 보닀, ν•˜μœ„μ˜ μ—¬λŸ¬ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 잘 μ •μ˜ν•˜μ—¬ μƒμ„±ν•˜λŠ” 것이 λ‚«λ‹€λŠ” 뜻.
  • μžλ™μ°¨ μΈν„°νŽ˜μ΄μŠ€ ==> μš΄μ „ μΈν„°νŽ˜μ΄μŠ€, μ •λΉ„ μΈν„°νŽ˜μ΄μŠ€
  • μ‚¬μš©μž ν΄λΌμ΄μ–ΈνŠΈ ==> μš΄μ „μž ν΄λΌμ΄μ–ΈνŠΈ, 정비사 ν΄λΌμ΄μ–ΈνŠΈ
  • λΆ„λ¦¬ν•˜λ©΄ μ •λΉ„ μΈν„°νŽ˜μ΄μŠ€ μžμ²΄κ°€ 변해도, μš΄μ „μž ν΄λΌμ΄μ–ΈνŠΈμ— 영ν–₯을 주지 μ•ŠμŒ
  • μΈν„°νŽ˜μ΄μŠ€κ°€ λͺ…확해지고, λŒ€μ²΄ κ°€λŠ₯성이 높아진닀.

 

DIP: Dependency Inversion Principle (μ˜μ‘΄μ„± 'μ—­μ „' 원칙, Dependency 'Injection' 이 μ•„λ‹ˆλ‹€!)

  • ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” '좔상화에 μ˜μ‘΄ν•΄μ•Όμ§€, ꡬ체화에 μ˜μ‘΄ν•˜λ©΄ μ•ˆλœλ‹€.' ( = 역할에 μ˜μ‘΄ν•΄μ•Όμ§€, κ΅¬ν˜„μ— μ˜μ‘΄ν•˜λ©΄ μ•ˆλœλ‹€.)
  • μ˜μ‘΄μ„± μ£Όμž…(DI)은 이 원칙을 λ”°λ₯΄λŠ” 방법 쀑 ν•˜λ‚˜, (DI 와 DIP λŠ” λ³„κ°œ)
  • ν΄λž˜μŠ€μ— μ˜μ‘΄ν•˜μ§€ 말고, μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•˜λΌλŠ” 뜻
  • 즉 역할에 μ˜μ‘΄ν•΄μ•Ό ν•œλ‹€. (μ—­ν•  = μΈν„°νŽ˜μ΄μŠ€)

 

public class MemberServiceImpl implements MemberService{

    // κΈ°μ‘΄
//    private final MemberRepository memberRepository = new MemoryMemberRepository();

    // λ³€κ²½
    private final MemberRepository memberRepository = new JdbcMemberRepository();
    
    ...
}

 

μœ„ μ½”λ“œ μ—­μ‹œ κ²°κ΅­, μΈν„°νŽ˜μ΄μŠ€ 뿐만 μ•„λ‹ˆλΌ κ΅¬ν˜„ ν΄λž˜μŠ€λ„ λ™μ‹œμ— 의쑴 ν•˜λŠ” μƒνƒœμ΄λ‹€ (DIP μœ„λ°˜) => MemoryMemberRepository(), JdbcMemberRepository()

 

객체 지ν–₯의 핡심은 λ‹€ν˜•μ„±μ΄μ§€λ§Œ, λ‹€ν˜•μ„±λ§ŒμœΌλ‘œλŠ” μ‰½κ²Œ λΆ€ν’ˆ κ°ˆμ•„λΌλ“― κ°œλ°œν•  수 μ—†λ‹€.

λ‹€ν˜•μ„± λ§ŒμœΌλ‘œλŠ” OCP, DIP λ₯Ό 지킬 수 μ—†κΈ° λ•Œλ¬Έμ— λ‹€λ₯Έ μž₯μΉ˜κ°€ λ” ν•„μš”ν•˜λ‹€ => μŠ€ν”„링

 


 

 

3. 객체 지ν–₯ 섀계와 μŠ€ν”„λ§

μŠ€ν”„λ§μ€ μ•„λž˜ κΈ°μˆ μ„ μ‚¬μš©ν•¨μœΌλ‘œ λ‹€ν˜•μ„± + OCP, DIP λ₯Ό κ°€λŠ₯ν•˜κ²Œ μ§€μ›ν•œλ‹€.

  • DI (Dependency Injection) : μ˜μ‘΄κ΄€κ³„, μ˜μ‘΄μ„± μ£Όμž…
  • DI μ»¨ν…Œμ΄λ„ˆ

κ·Έλ¦¬ν•˜μ—¬ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œ 변경없이 κΈ°λŠ₯을 ν™•μž₯ν•  수 있고, λΆ€ν’ˆ κ΅μ²΄ν•˜λ“― κ°œλ°œν•  수 μžˆλ‹€.

 

정리

  • λͺ¨λ“  섀계에 μ—­ν• κ³Ό κ΅¬ν˜„μ„ λΆ„λ¦¬ν•˜μž.
  • 곡연을 μ„€κ³„ν•˜λ“―, λ°°μ—­λ§Œ λ§Œλ“€μ–΄λ‘κ³  λ°°μš°λŠ” μ–Έμ œλ“ μ§€ μœ μ—°ν•˜κ²Œ λ³€κ²½ν•  수 μžˆλ„λ‘ λ§Œλ“œλŠ” 것이 쒋은 객체지ν–₯ 섀계.
  • μ΄μƒμ μœΌλ‘œλŠ” λͺ¨λ“  섀계에 μΈν„°νŽ˜μ΄μŠ€λ₯Ό λΆ€μ—¬ν•˜λŠ” 것이 μ’‹λ‹€.

싀무 κ³ λ―Ό

  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ„μž…ν•˜λ©΄ μΆ”μƒν™”λΌλŠ” λΉ„μš©μ΄ λ°œμƒ => κ°œλ°œμžκ°€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν•œλ²ˆ 더 타고 λ“€μ–΄κ°€μ•Όν•œλ‹€. (μΌμ’…μ˜ 단점)
  • κΈ°λŠ₯을 ν™•μž₯ν•  κ°€λŠ₯성이 μ—†λ‹€λ©΄ ꡬ체 클래슀λ₯Ό λ°”λ‘œ μ‚¬μš©ν•œλ‹€.
  • ν–₯ν›„ κΌ­ ν•„μš”ν•  λ•Œ λ¦¬νŒ©ν„°λ§ν•˜μ—¬ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ„μž…ν•˜λŠ” 것도 방법이닀.
  • 즉, λͺ¨λ“  κΈ°λŠ₯에 λ¬΄μž‘μ • μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ„μž…ν•  것이 μ•„λ‹ˆλΌ, 상황을 보고 좔상화λ₯Ό ν•  것인지 νŒŒμ•…ν•΄μ•Όν•œλ‹€.