객체 지향 설계 5원칙(SOLID)

1. 단일 책임 원칙 (SRP, Single Responsibility Principle)

  • 하나의 클래스는 단 하나의 책임만 가져야 한다.
  • 변경을 기준으로 변경 시 파급효과가 적으면 단일 책임 원칙을 잘 따르는 것이다.

2. 개방-폐쇄 원칙 (OCP, Open/Closed Principle)

  • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
  • 기능을 변경하거나 확장할 수 있으면서 기능을 사용하는 코드는 수정하지 않는다.
  • 다형성을 활용하여 구현체가 아닌 추상화에 의존한다.

3. 리스코프 치환 원칙 (LSP, Liskov Substitution Principle)

  • 프로그램 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
  • 상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
  • 엑셀을 바꿨는데 엑셀 밟을때 앞으로 가야지 발 뗐을때 가서는 안된다.

4. 인터페이스 분리 원칙 (ISP, Interface Segregation Principle)

  • 범용 인터페이스 하나보다 특정 클라이언트를 위한 여러 개의 인터페이스로 구성하는 것이 좋다.
  • 범용 인터페이스를 클라이언트가 필요로 하는 개별의 인터페이스로 분리함으로써 각 클라이언트가 사용하지 않는 인터페이스에 변경이 있어도 영향을 받지 않도록 만들어야 한다.
  • 읽기와 쓰기 전용 인터페이스를 분리한다면 변경에 대한 영향을 더욱 세밀하게 제어할 수 있다.

5. 의존관계 역전 원칙 (DIP, Dependency Inversion Principle)

  • 추상화에 의존해야지 구체화에 의존하면 안된다.
  • 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안되고 저수준 모듈은 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.
  • 비즈니스와 관련된 부분이 세부 사항에 의존하지 않는 설계 원칙

객체 지향 설계 5원칙인 SOLID가 얘기하는 핵심은 결국 추상화와 다형성이다. 구체 클래스에 의존하지 않고 추상 클래스(또는 인터페이스)에 의존함으로써 우리는 유연하고 확장가능한 애플리케이션을 만들 수 있는 것이다.

 

 

참고 자료

 

[OOP] 객체지향 프로그래밍의 5가지 설계 원칙, 실무 코드로 살펴보는 SOLID

이번에는 객체 지향 프로그래밍의 5가지 핵심 원칙인 SOLID에 대해 알아보고자 합니다. 실제로 애플리케이션을 개발할 때 어떻게 적용할 수 있을지 구체적인 예시를 들어 살펴보고자 합니다. 아

mangkyu.tistory.com

 

객체 지향 프로그래밍의 특징

1. 추상화

  • 객체에서 공통된 속성과 행위를 추출 하는 것
  • 추상화는 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단하게 만드는 것

생성일자 ,수정일자 ,생성자, 수정자는 대부분의 엔티티에 필요한 'BaseEntity'에 해당된다. BaseEntity 라는 추상화 집합을 만들어두고 BaseEntity가 가진 공통적인 특징들을 만들어서 활용한다.

 

추상화가 왜 필요할까?

  • 개발을 하면서 추가 기능이 요구되어 엔티티가 추가될 수도 있다. 이때 추상화로 'BaseEntity'를 구현 해놓았다면 추상화 된 공통된 정보 외에 추가할 정보만 입력해주면 된다.
  • 중복 코드의 양을 줄일 수 있다.

2. 캡슐화

  • 데이터 구조와 데이터를 다루는 방법들을 결합 시켜 묶는 것 (변수와 함수를 하나로 묶는 것을 뜻함)
  • 낮은 결합도를 유지할 수 있도록 설계하는 것

 

 

접근제어자를 활용하면 getter/setter 혹은 객체의 내부 메서드를 통해서만 외부에서의 접근이 가능하도록 제한하여 정보은닉을 활용 할 수도 있다. 

(무분별하게 Setter를 열어두는건 좋지 않지만 예시로 사용하고자 한다.)

 

@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)  
public class Order {

==============================윗부분 생략==============================

//==생성 메서드==//  여기서 주문 생성 관련을 완결해놔서 나중에 추가할게 생겨도 이 부분만 바꾸면 됨
    public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems) {
        Order order = new Order();
        order.setMember(member);
        order.setDelivery(delivery);
        for (OrderItem orderItem : orderItems) {
            order.addOrderItem(orderItem);
        }
        order.setStatus(OrderStatus.ORDER);
        order.setOrderDate(LocalDateTime.now());
        return order;
    }

    /**
     * 주문 취소
     */
    public void cancel() {
        if (delivery.getStatus() == DeliveryStatus.COMP) {
            throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다.");
        }
        this.setStatus(OrderStatus.CANCEL);
        for (OrderItem orderItem : orderItems) {
            orderItem.cancel();
        }
    }

 

Order 엔티티 내에서 createOrder나 cancel과 같은 내부 메서드를 만들어서

객체 내부의 동작을 외부로의 노출을 최소화하여 각 객체의 자율성을 높이고, 객체 간 결합도를 낮추어 변경이 용이한 객체 지향의 핵심적인 이점을 잘 살리는 방법으로 프로그램을 설계할 수 있다.

3. 상속

  • 클래스의 속성과 행위를 하위 클래스에 물려주거나 하위 클래스가 상위 클래스의 속성과 행위를 물려받는 것을 말한다
  • 새로운 클래스가 기존의 클래스의 데이터와 연산을 이용할 수 있게 하는 기능

상속을 하게 된다면 장단점이 존재하는데 이는 다음과 같다.

 

장점                                                                               단점

- 재사용으로 인한 코드가 줄어든다
- 범용적인 사용이 가능하다
- 자료와 메서드의 자유로운 사용 및 추가가 가능하다
- 상위 클래스의 변경이 어려워진다
- 불필요한 클래스가 증가할 수 있다
- 상속이 잘못 사용될 수 있다


4. 다형성

  • 하나의 변수명, 함수명이 상황에 따라 다른 의미로 해석 될 수 있는 것
  • 어떠한 요소에 여러 개념을 넣어 놓는 것

객체 지향 프로그래밍은 하나의 클래스 내부에 같은 이름의 행위를 여러개 정의하거나 상위 클래스의 행위를 하위 클래스에서 재정의하여 사용할 수 있기 때문에 다형성이라는 특징을 갖는다.

 

오버라이딩

  • 상위 클래스가 가지고 있는 메소드를 하위 클래스가 재정의해서 사용하는 것

오버로딩

  • 같은 이름의 메서드가 인자의 개수나 자료형에 따라 다른 기능을 하는 것
  • 생성자 오버로딩을 생각하면 쉽다

다형성의 본질

  • 인터페이스를 구현한 객체 인스턴스를 실행 시점유연하게 변경할 수 있다
  • 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다

객체 지향 프로그래밍

OOP(Object-Oriented Programming)란 프로그램 설계방법론이자 개념의 일종이다.

프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라,

프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호작용으로 서술하는 방식이다.

객체

객체는 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미하며

하나의 역할을 수행하는 '메소드와 변수(데이터)'의 묶음라고 할 수 있다.

레고에 빗대 표현하자면 객체는 레고의 조각이고 레고를 조립해서 무언가를 만들어 내는 것이 객체 지향 프로그래밍이라고 할 수 있다.

 

 

객체 지향 프로그래밍의 특징

객체 지향 프로그래밍은 크게 추상화, 캡슐화 ,상속 ,다형성 의 네가지 특징을 가진다.

SOLID (객체 지향 설계 원칙)

객체 지향적으로 설계하기 위해 SOLID 라 불리는 다섯 가지 원칙이 있다.

 

1. 단일 책임 원칙 (SRP, Single Responsibility Principle)

2. 개방-폐쇄 원칙 (OCP, Open/Closed Principle)

3. 리스코프 치환 원칙 (LSP, Liskov Substitution Principle)

4. 인터페이스 분리 원칙 (ISP, Interface Segregation Principle)

5. 의존관계 역전 원칙 (DIP), Dependency Inversion Principle)

 

+ Recent posts