본문 바로가기
CS (Computer Science)/독후감 : 면접을 위한 CS 전공지식 노트

독후감 : 면접을 위한 CS 전공지식 노트 2일차

by 우인입니다 2023. 12. 11.

1장 : 디자인 패턴

 

싱글톤부터 몇가지 패턴을 설명해준다.

중반에는 MVC, MVP, MVVM 패턴과 같은 애플리케이션 구성요소에서의 패턴을 설명했다.

앞부분에 나온 클래스 구성의 몇가지 패턴에 대해 처음접해서 정리하며 이해했다.

 

항상 무언가를 이해하려 할때 쉬운 말로 비유를 한마디로 하는 것을 목표로 한다.

그래서 아래 '한마디로' 를 포함하여 정리했다.


싱글톤

 

한마디로 : '인스턴스 하나 만들어서 사용하기'

인스턴스를 하나만 생성하기에 두번 생성하여 해시코드를 찍어보면 같아야 한다.

DB 모듈 연결에 실제로 사용된다.

의존성 주입을 통해 모듈 간의 결합을 조금 더 느슨하게 만들어줄 수 있다.

 

단점

TDD에 걸림돌이 된다. 한번 생성되면 계속 메모리에 남아있게 되고, 단위 테스트시 각 테스트마나 독립적인 인스턴스를 만들기 어렵기 때문.

결합이 강해져 싱글톤 하나의 구조만 변경되어도 다른 많은 곳에서 문제가 발생될 소지가 있다.

 


 

팩토리패턴

한마디로 : '주문을 받아서 그에 맞는 인스턴스를 생성해주는 팩토리 클래스가 있다.'

 

abstract class 커피

class 아메리카노 extends 커피 , class 라떼 extends 커피

 

위처럼 커피 추상클래스를 상속받는 각 커피 클래스가 있다.

class 커피팩토리 {
	public static 커피 getCoffee(String type, int price) {
    
    //입력값에 따라 그에 맞는 객체를 생성해준다.
    if ("라떼".equals(type)) return new 라떼(price);
    else if ("아메리카노".equals(type)) return new 아메리카노(price);
}

 

이 상태에서 커피팩토리 클래스는 요청에 맞는 클래스의 인스턴스를 생성해서 리턴해준다.

 


 

전략패턴

한마디로 : ''각 전략(전략 인터페이스를 구현한 각 클래스)를 입력해준다."

                 이 A 입력값에 이걸한다음 저걸하고 만약 저렇다면 그렇게 해서 ...

                -> A 입력값에 지금 적용된 전략 (3번) 사용. (따로 만들어 두었던 전략 3번 클래스를 참고하며)

 

전략을 바꾸면 그에 맞게 메소드가 작동되도록 한다.

그렇게 되면 전략을 따로 구현한 클래스를 추가, 수정하는 등의 확장성이 좋다.

그 이후 전략만 지정 혹은 바꿔주면 된다.

 


 

옵저버패턴

한마디로 : "옵저버들아 나 방금 업데이트 했다. 너네 하려던거 해라."

 

퍼블리셔와 구독자의 관계로 예시가 많다.

옵저버는 관찰, 즉 구독하고 알림설정한 것이다.

interface ISubject {
    void registerObserver(IObserver o);	// 옵저버 등록
    void removeObserver(IObserver o); 	// 옵저버 해제
    void notifyObserver(); 				// 옵저버들한테 알려주기
}

 

해당 인터페이스를 통해 필수 기능인 메소드를 강제해준다.

 

class SubjectImpl implements ISubject {
    // 관찰자들을 등록하여 담는 리스트
    List<IObserver> observers = new ArrayList<>();
	...
    // 옵저버에게 이벤트 송신
    @Override
    public void notifyObservers() {   
        this.observers.forEach(Observer::update); //Observer가 가지고 있는 update 메소드로 이후 동작을 넘긴다
    }
}

 

위의 notifyObservers 메소드가 인터페이스 구현을 위해 강제로 오버라이드 됐다.

그리고 여기에는 List에 객체로 등록되어 있던 옵저버들을 순회하며 각 옵저버가 가지고 있는 update( ) 를 실행시킨다.

여기서 직접 무슨 동작을 하는 것이 아닌 이후의 작업은 각자 옵저버 객체에 맡긴다.

 


 

프록시 패턴

한마디로 : "프록시가 일단 할거 다 하고 원본객체가 꼭 필요할때 불러."

 

예를 들어 10,000개의 프로필 객체에 여러가지 정보와 프로필 이미지가 있다고 하자.

처음에 여러가지 기본사항을 확인하고 그 이후에 프로필 이미지를 확인하고자 하려한다.

 

처음부터 프로필 이미지 10,000개를 로딩하지 않고 꼭 필요할 때 불러온다면 그 조회 비용이 훨씬 줄어들 것이다.

기본사항만 가지고 있고 프로필이미지는 요청이 왔을 때 그때 조회하는 식의 프록시 객체를 만들어 둔다면 조회 비용을 줄일 수 있다.

 

위 예시는 가상 프록시의 쓰임이지만 로깅, 보호 등의 목적으로 프록시 패턴을 사용할 수 있다.

 


 

 

이터레이터 패턴

한마디로 : "종류 상관없이 순서대로 그냥 순회하면서 처리하면 된다."

 

Map구조가 오면 그에 맞게 키-값을 리턴하면 되고

Set구조가 오면 앞에 있는 자료부터 리턴하면 되고

List구조가 오면 순서대로 앞에부터 리턴하면 되고

 

자바에선 해당 이터레이터가 구현되어 있고, 이러한 패턴이 쓰였겠구나 하고 이해하는 정도로 넘어갔다.

 


 

느낀 점

아직 표면적인 장단점, 특징을 파악하는 데에 그쳤다고 생각한다.

하지만 개념을 알고 있는 것이 추후에 큰 도움이 된다.

 

숙지해두고 활용할 시기가 되었을 때 더 깊이 공부할 수 있는 기반을 마련했다고 생각한다.

조만간 개인프로젝트에 있어서 전반적인 리팩토링을 해야할듯하고 그 때 도움이 되길 기대한다.