6_oHji
6_oHji
ν™˜μ˜ν•©λ‹ˆλ‹€☺
GitHub   Gmail
전체 방문자
였늘
μ–΄μ œ
  • λΆ„λ₯˜ 전체보기 (62)
    • πŸ’‘ DEEP DIVE (17)
      • PATTERN (17)
    • πŸ“ 끄적끄적 (4)
    • 🌈 EXPERIENCE (3)
    • πŸ’» PROJECT (3)
    • πŸ“’ STUDY (34)
      • ALGORITHM (1)
      • JAVA (5)
      • FRONT-END (7)
      • BACK-END (10)
      • SPRING (7)
      • NETWORK (3)
      • CLOUD (1)

λΈ”λ‘œκ·Έ 메뉴

  • ν™ˆ
  • νƒœκ·Έ

곡지사항

인기 κΈ€

졜근 λŒ“κΈ€

졜근 κΈ€

ν‹°μŠ€ν† λ¦¬

κ°œμΈμ •λ³΄

  • ν‹°μŠ€ν† λ¦¬ ν™ˆ
  • μŠ€ν† λ¦¬
  • 포럼
  • 둜그인
hELLO Β· Designed By μ •μƒμš°.
6_oHji
6_oHji
Deep Dive Into Design Patterns - ν”„λ‘μ‹œ νŒ¨ν„΄
πŸ’‘ DEEP DIVE/PATTERN

Deep Dive Into Design Patterns - ν”„λ‘μ‹œ νŒ¨ν„΄

2024. 5. 10. 15:07

πŸ’‘ ν”„λ‘μ‹œ νŒ¨ν„΄μ΄λž€?

λŒ€μƒ 원본 객체λ₯Ό λŒ€λ¦¬ν•˜μ—¬ λŒ€μ‹  μ²˜λ¦¬ν•˜κ²Œ ν•¨μœΌλ‘œμ¨ 둜직의 흐름을 μ œμ–΄ν•˜λŠ” 행동 νŒ¨ν„΄μž…λ‹ˆλ‹€. “ν”„λ‘μ‹œ”의 사전적인 의미인 ‘λŒ€λ¦¬μΈ’처럼, ν΄λΌμ΄μ–ΈνŠΈκ°€ λŒ€μƒ 객체λ₯Ό 직접 μ‚¬μš©ν•˜λŠ” 게 μ•„λ‹ˆλΌ 쀑간에 ν”„λ‘μ‹œ(λŒ€λ¦¬μΈ)을 κ±°μ³μ„œ μ‚¬μš©ν•˜λŠ” μ½”λ“œ νŒ¨ν„΄μž…λ‹ˆλ‹€.

 

λ”°λΌμ„œ λŒ€μƒ 객체(Subject)의 λ©”μ†Œλ“œλ₯Ό 직접 μ‹€ν–‰ν•˜λŠ” 것이 μ•„λ‹Œ, λŒ€μƒ 객체에 μ ‘κ·Όν•˜κΈ° 전에 ν”„λ‘μ‹œ(Proxy) 객체의 λ©”μ„œλ“œλ₯Ό μ ‘κ·Όν•œ ν›„ 좔가적인 λ‘œμ§μ„ μ²˜λ¦¬ν•œλ’€ μ ‘κ·Όν•˜κ²Œ λ©λ‹ˆλ‹€. ν”„λ‘μ‹œλŠ” μ‹€μ œ 객체에 μ•‘μ„ΈμŠ€ν•˜μ§€ μ•Šκ³ , 정상적 λ˜λŠ” 비정상적인 λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•  수 μžˆκ²Œλ” ν•©λ‹ˆλ‹€.

 

πŸ’‘ ν”„λ‘μ‹œ νŒ¨ν„΄μ„ μ“°λŠ” 이유

ν”„λ‘μ‹œ νŒ¨ν„΄μ€ λŒ€μƒ ν΄λž˜μŠ€κ°€ λ―Όκ°ν•œ 정보λ₯Ό κ°€μ§€κ³  μžˆκ±°λ‚˜ μΈμŠ€ν„΄μŠ€ν™” ν•˜κΈ°μ— λ¬΄κ²κ±°λ‚˜ μΆ”κ°€ κΈ°λŠ₯을 κ°€λ―Έν•˜κ³  싢은데, 원본 객체λ₯Ό μˆ˜μ •ν• μˆ˜ μ—†λŠ” 상황일 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.

  1. λ³΄μ•ˆ(Security) : ν”„λ‘μ‹œλŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλŠ” κΆŒν•œμ΄ μžˆλŠ”μ§€ ν™•μΈν•˜κ³  검사 κ²°κ³Όκ°€ 긍정적인 κ²½μš°μ—λ§Œ μš”μ²­μ„ λŒ€μƒμœΌλ‘œ μ „λ‹¬ν•©λ‹ˆλ‹€.
  2. 캐싱(Caching) : ν”„λ‘μ‹œκ°€ λ‚΄λΆ€ μΊμ‹œλ₯Ό μœ μ§€ν•˜μ—¬ 데이터가 μΊμ‹œμ— 아직 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” κ²½μš°μ—λ§Œ λŒ€μƒμ—μ„œ μž‘μ—…μ΄ μ‹€ν–‰λ˜λ„λ‘ ν•©λ‹ˆλ‹€.
  3. 데이터 μœ νš¨μ„± 검사(Data validation) : ν”„λ‘μ‹œκ°€ μž…λ ₯을 λŒ€μƒμœΌλ‘œ μ „λ‹¬ν•˜κΈ° 전에 μœ νš¨μ„±μ„ κ²€μ‚¬ν•©λ‹ˆλ‹€.
  4. μ§€μ—° μ΄ˆκΈ°ν™”(Lazy initialization) : λŒ€μƒμ˜ 생성 λΉ„μš©μ΄ λΉ„μ‹Έλ‹€λ©΄ ν”„λ‘μ‹œλŠ” 그것을 ν•„μš”λ‘œ ν• λ•ŒκΉŒμ§€ μ—°κΈ°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  5. λ‘œκΉ…(Logging) : ν”„λ‘μ‹œλŠ” λ©”μ†Œλ“œ 호좜과 μƒλŒ€ 맀개 λ³€μˆ˜λ₯Ό μΈν„°μ…‰νŠΈν•˜κ³  이λ₯Ό κΈ°λ‘ν•©λ‹ˆλ‹€.
  6. 원격 객체(Remote objects) : ν”„λ‘μ‹œλŠ” 원격 μœ„μΉ˜μ— μžˆλŠ” 객체λ₯Ό κ°€μ Έμ™€μ„œ 둜컬처럼 보이게 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

πŸ’‘ 클래슀 λ‹€μ΄μ–΄κ·Έλž¨μœΌλ‘œ λ³Έ ν”„λ‘μ‹œ νŒ¨ν„΄

  1. Subject(Service Interface) : ν”„λ‘μ‹œ 객체와 μ„œλΉ„μŠ€ 객체λ₯Ό ν•˜λ‚˜λ‘œ λ¬ΆλŠ” μΈν„°νŽ˜μ΄μŠ€λ‘œ, ν΄λΌμ΄μ–ΈνŠΈκ°€ ν”„λ‘μ‹œμ™€ μ„œλΉ„μŠ€μ˜ 차이λ₯Ό μ˜μ‹ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€. λŒ€μƒ 객체와 ν”„λ‘μ‹œ 역할을 λ™μΌν•˜κ²Œ ν•˜λŠ” 좔상 λ©”μ†Œλ“œ operation() λ₯Ό μ •μ˜ν•œλ‹€. ν”„λ‘μ‹œκ°€ μ„œλΉ„μŠ€ 객체둜 μœ„μž₯ν•  수 있으렀면 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό 따라야 ν•œλ‹€.
  2. Real Subject(Service) : 원본 λŒ€μƒ 객체
  3. Proxy : λŒ€μƒ 객체λ₯Ό μ€‘κ³„ν•˜λŠ” λŒ€λ¦¬μž 객체둜, λŒ€μƒ 객체λ₯Ό ν•©μ„±(composition)ν•œλ‹€. μ„œλΉ„μŠ€ κ°μ²΄λ“€μ˜ 전체 수λͺ… μ£ΌκΈ°λ₯Ό κ΄€λ¦¬ν•˜μ§€λ§Œ, 흐름 μ œμ–΄λ§Œ ν•  뿐 결과값을 μ‘°μž‘ν•˜κ±°λ‚˜ λ³€κ²½μ‹œν‚€λ©΄ μ•ˆλœλ‹€.
  4. Client : μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•˜μ—¬ ν”„λ‘μ‹œ 객체λ₯Ό 생성해 μ΄μš©ν•œλ‹€.

 

πŸ’‘ ν”„λ‘μ‹œ νŒ¨ν„΄ κ΅¬ν˜„

interface ISubject {
    void operation();
}

class RealSubject implements ISubject {
    public void operation() {
        System.out.println("원본 객체 μ•‘μ…˜ !!");
    }
}

class Proxy implements ISubject {
    private RealSubject subject; // λŒ€μƒ 객체λ₯Ό composition
    boolean access; // μ ‘κ·Ό κΆŒν•œμœΌλ‘œ 보호 κ°€λŠ₯

    Proxy(RealSubject subject, boolean access) {
        this.subject = subject;
        this.access = access;
    }

    public void operation() {
		    // 1. λ‘œκΉ… κΈ°λŠ₯ μΆ”κ°€
		    // 2. μ ‘κ·Ό κΆŒν•œμœΌλ‘œ 보호 κΈ°λŠ₯ μΆ”κ°€
		    if(!access) {
			    System.out.println("μ ‘κ·Ό κΆŒν•œ μ—λŸ¬!"); return;
		    }
			  // 3. μ§€μ—° μ΄ˆκΈ°ν™” κΈ°λŠ₯ μΆ”κ°€
        if(subject == null){
            subject = new RealSubject();
        }
        subject.operation(); // μœ„μž„
        /* do something */
        System.out.println("ν”„λ‘μ‹œ 객체 μ•‘μ…˜ !!");
    }
}

class Client {
    public static void main(String[] args) {
        ISubject sub = new Proxy(new RealSubject());
        sub.operation();
    }
}

 

πŸ’‘ 마무리

ν”„λ‘μ‹œ νŒ¨ν„΄μ€

  1. 접근을 μ œμ–΄ν•˜κ±°κ°€ κΈ°λŠ₯을 μΆ”κ°€ν•˜κ³  싢은데, 기쑴의 νŠΉμ • 객체λ₯Ό μˆ˜μ •ν•  수 μ—†λŠ” 상황일 λ•Œ
  2. μ΄ˆκΈ°ν™” μ§€μ—°, μ ‘κ·Ό μ œμ–΄, λ‘œκΉ…, 캐싱 λ“±, κΈ°μ‘΄ 객체 λ™μž‘μ— μˆ˜μ • 없이 κ°€λ―Έν•˜κ³  싢을 λ•Œ

에 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

ν”„λ‘μ‹œ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λ©΄ κΈ°μ‘΄ λŒ€μƒ 객체의 μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ κΈ°λŠ₯을 μΆ”κ°€ν•  수 있고(OCP μ€€μˆ˜), λŒ€μƒ κ°μ²΄λŠ” μžμ‹ μ˜ κΈ°λŠ₯μ—λ§Œ 집쀑 ν•˜κ³ , κ·Έ 이외 λΆ€κ°€ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” 역할을 ν”„λ‘μ‹œ 객체에 μœ„μž„ν•˜μ—¬ 닀쀑 μ±…μž„μ„ νšŒν”Ό ν•  수 μžˆμŠ΅λ‹ˆλ‹€(SRP μ€€μˆ˜).

 

 

ν”„λ‘μ‹œ νŒ¨ν„΄

/ λ””μžμΈ νŒ¨ν„΄λ“€ / ꡬ쑰 νŒ¨ν„΄ ν”„λ‘μ‹œ νŒ¨ν„΄ λ‹€μŒ μ΄λ¦„μœΌλ‘œλ„ λΆˆλ¦½λ‹ˆλ‹€: Proxy μ˜λ„ ν”„λ‘μ‹œλŠ” λ‹€λ₯Έ 객체에 λŒ€ν•œ λŒ€μ²΄ λ˜λŠ” μžλ¦¬ν‘œμ‹œμžλ₯Ό μ œκ³΅ν•  수 μžˆλŠ” ꡬ쑰 λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€. ν”„λ‘μ‹œλŠ” μ›λž˜ 객체

refactoring.guru

 

πŸ’  ν”„λ‘μ‹œ(Proxy) νŒ¨ν„΄ - μ™„λ²½ λ§ˆμŠ€ν„°ν•˜κΈ°

Proxy Pattern ν”„λ‘μ‹œ νŒ¨ν„΄(Proxy Pattern)은 λŒ€μƒ 원본 객체λ₯Ό λŒ€λ¦¬ν•˜μ—¬ λŒ€μ‹  μ²˜λ¦¬ν•˜κ²Œ ν•¨μœΌλ‘œμ¨ 둜직의 흐름을 μ œμ–΄ν•˜λŠ” 행동 νŒ¨ν„΄μ΄λ‹€. ν”„λ‘μ‹œ(Proxy)의 사전적인 μ˜λ―ΈλŠ” 'λŒ€λ¦¬μΈ'μ΄λΌλŠ” λœ»μ΄λ‹€. 즉, λˆ„

inpa.tistory.com

 

λ°˜μ‘ν˜•
μ €μž‘μžν‘œμ‹œ λΉ„μ˜λ¦¬ λ³€κ²½κΈˆμ§€ (μƒˆμ°½μ—΄λ¦Ό)
    'πŸ’‘ DEEP DIVE/PATTERN' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
    • Deep Dive Into Design Patterns - ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄
    • Deep Dive Into Design Patterns - μ±…μž„ 연쇄 νŒ¨ν„΄
    • Deep Dive Into Design Patterns - μ€‘μž¬μž νŒ¨ν„΄
    • Deep Dive Into Design Patterns - μ˜΅μ„œλ²„ νŒ¨ν„΄
    6_oHji
    6_oHji
    끄적끄적

    ν‹°μŠ€ν† λ¦¬νˆ΄λ°”