본문 바로가기

멋쟁이사자처럼 자바 백엔드 🦁

멋쟁이사자처럼 데일리 복습 - 스프링 개요 [25.05.12]

 

인정할 것은 솔직히 인정하자. 그간 공부한 것들을 복습하며 글로 남기는 일에 소홀했다. 

변명을 해보자면, 문법 숙달을 위한 코딩 실습과 미니 프로젝트를 진행하는 동안에는 도저히 생각들을 글로 정리할 여유가 없었다. 

자, 그럼 이제 프로젝트가 끝났으니 여유를 되찾았냐고? 

그런 것은 또 아니다. 여유로운 듯한 착시 속에서 스프링과 스프링부트라는 또다른 여정이 오늘 부로 시작되었기 때문이다. 

 

 

[오늘의 학습 목표]

  1. GoF 디자인 패턴 23가지를 Creational, Structural, Behavioral 유형으로 구분하여 그 목적과 사용 시점을 이해할 수 있다.
  2. 주어진 요구사항에 맞는 디자인 패턴을 식별하고, 해당 패턴을 활용해 유연하고 확장 가능한 객체지향 구조를 설계할 수 있다.

    ex) 다양한 객체 생성을 캡슐화하기 위해 Factory Method 패턴을 적용한다.
  3. 디자인 패턴 간의 관계와 차이점을 이해하고, 적절한 조합을 통해 재사용성과 유지보수성이 높은 아키텍처를 설계할 수 있다. 
    ex) MVC 구조에서 Strategy + Observer 패턴을 결합하여 화면과 모델을 느슨하게 연결
  4. GoF 디자인 패턴을 Java 또는 Spring 기반 프로젝트에 적용하여 실제 소프트웨어 개발에 활용할 수 있다.

[GoF 디자인 패턴]

Gang of Four, 직역하면 4인방 디자인 패턴이다. 에리히 감마, 리처드 헬름, 랄프 존슨, 존 블리시데스가 공동 저술한 '디자인 패턴'에서 처음 제안된 개념으로, 소프트웨어 개발 과정에서 발생하는 문제들을 해결하기 위한 검증된 솔루션이다. 개발자들에게 '문제 해결을 위한 공용어'를 제시해 코드의 유지보수성과 확장성을 꾀하고 있다.

 

GoF 디자인 패턴은 크게 세 가지로 나눌 수 있으며, 총 23개의 항목으로 구성되어 있다.

  • 생성 패턴(Creational Patterns): 객체 생성 메커니즘을 유연하게 제어하여 상황에 맞는 객체를 만든다.
    • 추상 팩토리 패턴: 같은 주제의 다른 팩토리를 묶어 준다.
    • 싱글톤 패턴: 한 클래스에 한 객체만 존재하도록 제한한다.
    • 빌더 패턴: 생성(construction)과 표기(representation)를 분리해 복잡한 객체를 생성한다.
    • 팩토리 메서드 패턴: 생성할 객체의 클래스를 국한하지 않고 객체를 생성한다.
    • 프로토타입 패턴: 기존 객체를 복제함으로써 객체를 생성한다. 
  • 구조 패턴(Structural Patterns): 클래스와 객체를 더 큰 구조로 조합하며, 유연하고 효율적인 구조를 설계한다.
    • 어댑터 패턴: 인터페이스가 호환되지 않는 클래스들을 함께 이용할 수 있도록 다른 클래스의 인터페이스를 기존 것에 덮어씌운다.
    • 브리지 패턴: 추상화와 구현을 분리해 둘을 각각 따로 발전시킨다.
    • 합성 패턴: 0개, 1개 혹은 그 이상의 객체를 묶어 하나의 객체로 이용할 수 있다.
    • 데코레이터 패턴: 기존 객체의 메소드에 새로운 행동을 추가하거나 오버라이드할 수 있다.
    • 파사드 패턴: 대량의 코드에 접근할 수 있는 단순한 인터페이스를 제공한다.
    • 플라이웨이트 패턴: 다수의 유사한 객체를 생성, 조작하는 비용을 절감할 수 있다.
    • 프록시 패턴: 접근 조절, 비용 절감, 복잡도 감소를 위해 접근이 힘든 객체에 대한 대역을 제공한다.
  • 행위 패턴(Behavioral Patterns): 객체 간 상호작용과 책임 분배를 다루는 패턴으로, 객체간 소통을 개선한다.
    • 책임연쇄 패턴(Chain of responsibility): 책임들이 연결되어 있어, 내가 지지 못할 책임을 다음 책임자에게 자동으로 넘기는 구조.
    • 커맨드 패턴(Command Pattern): 위의 명령어를 하나씩 구현하는 대신 하나의 추상 클래스에 메소드를 하나 만들고, 각 명령이 들어오면 그에 맞는 서브 클래스가 선택되어 실행되는 것.
    • 해석자 패턴(Interpreter Pattern): 문법 규칙을 클래스화한 구조를 갖는 SQL, 통신 프로토콜 등을 개발할때 사용된다.
    • 반복자 패턴(Iterator Pattern): 반복이 필요한 자료구조를 모두 동일한 인터페이스를 통해 접근할 수 있도록 메서드를 이용해 자료구조 활용을 돕는다.
    • 옵저버 패턴: 어떤 클래스에 변화가 일어나면 이를 감지하여 다른 클래스에 통보해준다.
    • 전략 패턴: 알고리즘 군을 정의하고, 각각 하나의 클래스로 캡슐화한 다음, 필요할 때 서로 교환하여 사용할 수 있게 해준다.
    • 템플릿 메서드 패턴: 상위 클래스에서는 추상적으로 표현하고, 구체적인 내용은 하위 클래스에서 결정되는 디자인 패턴.
    • 방문자 패턴: 각 클래스의 데이터 구조로부터 처리 기능을 분리하여 별도의 방문자 클래스로 만든 후, 해당 클래스의 메소드가 각 클래스를 돌아다니며 특정 작업을 수행하도록 하는 것.
    • 중재자 패턴(Mediator Pattern): 클래스간의 복잡한 상호작용을 캡슐화하여 한 클래스에 위임하여 처리하는 디자인 패턴.
    • 상태 패턴(State Pattern): 동일한 동작을 객체의 상태에 따라 다르게 처리해야 할 때 사용하는 디자인 패턴.
    • 기념품 패턴(Memento Pattern): 클래스 설계 관점에서 객체의 정보를 저장한다. undo (ctrl+z)와 같은 기능을 개발할 때 유용하다.

 

[스프링 프레임워크의 디자인 패턴]

 

스프링 프레임워크는 자바 웹 어플리케이션 개발에 자주 쓰이는 프레임워크다. 프레임워크는 틀, 뼈대에 비유할 수 있다. 짜여진 틀과 뼈대에 맞춰 소프트웨어를 개발하는 개념이다.

 

프레임워크의 장점

  • 뼈대에 살만 입히면 되는 만큼 개발이 효율적이다.
  • 다수의 개발자가 참여한 프로젝트라도, 단일한 체계를 기반으로 코드를 작성하기 때문에 일관성이 높고 유지보수가 간편하다.

프레임워크의 단점

  • 프레임워크 사용법을 먼저 익혀야 하기 때문에 코드 해석 및 학습에 시간이 소요된다.
  • 구조에서 크게 벗어날 수 없기 때문에 자유도와 유연성이 부족하다.

스프링 프레임워크에는 여러 디자인 패턴이 존재한다. 

 

  • 의존성 주입(Dependency Injection): 테스트가 용이하도록 객체 간 의존관계를 외부에서 주입하여 결합도를 낮추는 패턴.
  • 팩토리 패턴(Factory Pattern): BeanFactory와 ApplicationContext를 통해 객체 생성 로직을 캡슐화하는 패턴.
  • 싱글톤 패턴(Singleton Pattern): 기본적으로 모든 빈을 싱글톤으로 관리하여 리소스 효율성을 높이는 패턴.
  • 템플릿 메소드 패턴(Template Method): JdbcTemplate, RestTemplate 등에서 알고리즘의 골격을 정의하고 세부 구현을 하위 클래스에 위임하는 패턴.
  • 프록시 패턴(Proxy Pattern): AOP 구현에 활용되며, 원본 객체에 대한 접근을 제어하고 부가 기능을 추가하는 패턴.
  • 옵저버 패턴(Observer Pattern): 이벤트 처리와 리스너 메커니즘에 사용되는 패턴으로, ApplicationEvent와 ApplicationListener를 활용한다.

 

[스프링의 5대 핵심 모듈]

개발자는 필요에 따라 각 모듈을 조합하거나 독립적으로 사용할 수 있다.

모듈 명칭 주요 기능 핵심 컴포넌트
Spring Core IoC 컨테이너, DI 지원 BeanFactory, ApplicationContext
Spring AOP 관점 지향 프로그래밍 지원 Aspect, Advice, Pointcut
Spring MVC 웹 애플리케이션 개발 프레임워크 DispatcherServlet, Controller
Spring Data 데이터 액세스 기술 통합 Repository, JPA, JDBC
Spring Security 인증 및 권한 부여 프레임워크 Authentication, Authorization

 

* 모듈: 프로그램의 구성 요소로, 연관된 데이터와 함수를 하나로 묶은 단위를 말한다. 일반적으로 하나의 소스 파일에 모든 함수를 작성하지 않으며, 함수의 기능별로 별도의 모듈을 구성한다.

* 컴포넌트: 재사용이 가능한 독립된 각각의 모듈이다. 

* 관점 지향 프로그래밍?

 

개발자는 필요에 따라 각 모듈을 조합하거나 독립적으로 사용할 수 있다.

 

Continue