[스프링&JPA 스터디] #1 스프링, 다형성, SOLID, 예제(only자바)

오예찬·2023년 7월 10일
0

spring&jpa 스터디

목록 보기
1/15

스프링이란?

  • 스프링은 자바 언어 기반의 프레임워크
  • 스프링은 좋은 객체 지향 어플리케이션을 개발할 수 있게 도와주는 프레임워크

다형성

  • 좋은 객체 지향 프로그래밍은 "다형성"을 만족시킨다.

  • 운전자-자동차로 보는 다형성: 자동차가 바뀌어도 운전자는 바뀔 필요가 없다.(역할과 구현으로 세상을 구분)

  • 역할과 구현을 분리: 역할과 구현으로 구분하면 세상이 단순해지고, 유연해지며, 변경도 편리해진다.

  • 객체를 설계할 때 역할과 구현을 명확히 분리(역할=인터페이스, 구현=인터페이스를 구현한 클래스, 구현 객체)

  • 객체 설계시 역할(인터페이스)을 먼저 부여하고, 그 역할을 수행하는 구현 객체 만들기


좋은 객체 지향 설계의 5가지 원칙(SOLID)


SRP: 단일 책임 원칙[★★★★☆]

  • 한 클래스는 하나의 책임만 가져야 한다.

OCP: 개방-폐쇄 원칙[★★★★★]

  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다
  • 다형성을 활용

LSP: 리스코프 치환 원칙[★★★☆☆]

  • 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙
  • 예)자동차 인터페이스의 엑셀은 앞으로 가라는 기능을 가져야 한다. 뒤로 가면 LSP 위반

ISP: 인터페이스 분리 원칙[★★★★☆]

  • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
  • 예) 통장쪼개기

DIP: 의존관계 역전 원칙[★★★★★]

  • OCP와 비슷. 추상화에 의존해야지, 구체화에 의존하면 안됨
  • 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻



스프링 예제1 _only java


비즈니스 요구사항과 설계

회원 도메인 협력 관계

회원 클래스 다이어그램

회원 서비스 구현체

package hello.core.member;

public class MemberServiceImpl implements MemberService{
//의존 관계가 구현까지 발생함(DIP에 어긋남)
    private final MemberRepository memberRepository = new MemoryMemberRepository();


    @Override
    public void join(Member member) {
        memberRepository.save(member);
    }

    @Override
    public Member findMember(Long memberId) {
        return memberRepository.findById(memberId);
    }
}

  • 의존 관계가 인터페이스 뿐만 아니라 구현까지 모두 의존하는 문제점이 있음
  • DIP를 잘 지키지 못함

주문 도메인 전체



  • 역할과 구현을 분리해서 자유롭게 구현 객체를 조립할 수 있게 설계했다. 덕분에 회원 저장소는 물론이고, 할인 정책도 유연하게 변경할 수 있다.

주문 도메인 클래스 다이어그램


주문 서비스 구현체

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;

public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository = new MemoryMemberRepository();
    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);
		//DIP 에 따라 잘 설계되었다.
        return new Order(memberId, itemName, itemPrice, discountPrice);
    }
}

  • 주문 생성 요청이 오면, 회원 정보를 조회하고, 할인 정책을 적용한 다음 주문 객체를 생성해서 반환한다.
  • 메모리 회원 리포지토리와, 고정 금액 할인 정책을 구현체로 생성한다.
  • 할인에 대한 변경이 필요하면 할인만 고치면 됨 (주문까지 고칠 필요 X) -> DIP 원칙을 준수.

참고

스프링 핵심 원리 - 기본편 (김영한)

profile
개발자를 그만두기 전 알아야 하는 100가지 이야기

0개의 댓글