[JAVA]OOP,SOLID

전두엽힘주기·2025년 12월 18일

Java

목록 보기
8/9

객체지향의 핵심은 관계와 다형성
상속은 최소화하고 컴포지션을 기본 전략
SOLID 원칙은 객체지향 설계가 망가지지 않도록 함


개념 등장 배경 — 왜 객체지향 설계를 배우는가

  • 기능 하나 추가했을 뿐인데 여러 클래스 수정
  • if–else가 끝없이 늘어나는 구조
  • 객체 생성 로직이 여기저기 흩어짐
  • 테스트하기 어려운 코드

AI에게 요구사항만 던지면, 돌아가긴 하는 스파게티 코드가 나온다.

즉,
문제의 본질은 설계 사고의 부재다.


객체지향 프로그래밍(OOP)의 핵심 관점

Class와 Object

  • Class: 데이터와 행위의 설계도
  • Object: 클래스로부터 생성된 실체

객체지향의 본질 ⭐⭐⭐

객체 자체보다 객체 간의 관계가 중요하다

코드는 결국 객체들이 어떻게 협력하는지를 표현한 것이다.

Person ── uses ──▶ Car
Car ── has ──▶ Engine
  • Person이 Car를 어떻게 쓰는지
  • Car가 Engine을 어떻게 소유하는지

👉 이 관계가 설계


OOP 4대 핵심 개념

1. 캡슐화 (Encapsulation)

  • 내부 구현을 외부로부터 숨김
  • 접근 제어자(private, protected 등)
  • Information Hiding

중요한 포인트는 이것이다.

“외부 접근을 통제하는 책임은 설계자에게 있다”


2. 상속 (Inheritance)

  • 부모–자식 관계
  • Is-a 관계
  • 코드 재사용 가능

하지만 강의에서 반복해서 강조된 점:

상속은 생각보다 위험하다

상속의 문제점

  • 강한 결합(Strong Coupling)
  • 컴파일 타임에 구조 고정
  • 잘못된 상속은 전체 설계 붕괴

3. 다형성 (Polymorphism) ⭐⭐⭐⭐⭐

  • 동일한 인터페이스
  • 다른 구현
  • 실행 시점에 동작 결정
Animal animal = new Dog();
animal.speak();

객체지향 설계의 핵심은 다형성

  • 기능 확장 시 기존 코드 수정 ❌
  • 새로운 구현 추가 ⭕

4. 추상화 (Abstraction)

  • 공통 개념을 상위로 뽑아냄
  • 다형성을 가능하게 하는 전제 조건

예:

  • 에어컨, 공기청정기 → Device

상속 vs 컴포지션

상속 (Inheritance)

  • Is-a
  • 강한 결합
  • 런타임 교체 불가
Car extends Engine ❌

엔진을 바꾸고 싶으면?
→ 클래스 구조부터 수정


컴포지션 (Composition) ⭐⭐⭐⭐⭐

  • Has-a 관계
  • 느슨한 결합
  • 런타임 교체 가능
class Car {
    Engine engine;
}

“기능 확장은 상속보다 컴포지션을 써라”


SOLID 원칙 — 객체지향 설계의 안전장치

SOLID는 패턴이 아니다.
객체지향 설계가 망가지지 않게 붙잡아 주는 기준이다.


S — Single Responsibility Principle (단일 책임)

개념

  • 클래스는 하나의 변경 이유만 가져야 한다

❌ SRP 위반 코드

class Report {
    void calculate() {}
    void print() {}
    void saveToFile() {}
}
  • 계산 변경
  • 출력 변경
  • 저장 변경
    → 전부 Report 수정

⭕ SRP 개선 코드

class ReportCalculator {
    void calculate() {}
}

class ReportPrinter {
    void print() {}
}

class ReportSaver {
    void save() {}
}

O — Open / Closed Principle

개념

  • 확장에는 열려 있고
  • 수정에는 닫혀 있어야 한다

❌ OCP 위반 코드

class Animal {
    void speak(String type) {
        if (type.equals("dog")) {}
        else if (type.equals("cat")) {}
    }
}

⭕ OCP 개선 코드

interface Animal {
    void speak();
}

class Dog implements Animal {
    public void speak() {}
}

기존 코드 수정 ❌
새 클래스 추가 ⭕


L — Liskov Substitution Principle

개념

  • 부모 타입 자리에 자식 타입을 문제없이 대체 가능해야

❌ 위반 예

class Car {
    void drive() {}
}

class Bicycle extends Car {
    void drive() {
        throw new UnsupportedOperationException();
    }
}

⭕ 개선 방향

interface Vehicle {
    void move();
}

이상한 상속을 하지 마라


I — Interface Segregation Principle

개념

  • 사용하지 않는 메서드에 의존하지 말라

❌ 위반 코드

interface Machine {
    void print();
    void scan();
    void fax();
}

⭕ 개선 코드

interface Printer {
    void print();
}

D — Dependency Inversion Principle ⭐⭐⭐

개념

구현이 아니라 추상화에 의존

❌ 위반 코드

class Zoo {
    Dog dog = new Dog();
}

⭕ 개선 코드

class Zoo {
    Animal animal;

    Zoo(Animal animal) {
        this.animal = animal;
    }
}
  • 테스트 쉬움
  • 교체 쉬움
  • 확장 쉬움

핵심 개념 요약

  • 객체지향 본질 = 객체 간 관계
  • OOP 핵심 = 다형성
  • 상속 ❌, 컴포지션 ⭕
  • SOLID = 설계 기준
  • 모든 원칙은 결합도 감소로 수렴

헷갈리기 쉬운 포인트 정리

개념핵심
상속구조 고정, 강한 결합
컴포지션런타임 교체, 유연성
OCPif 제거가 목적 아님
DIP추상화에 의존

마무리 정리

  1. 객체지향은 문법이 아니라 사고 방식
  2. SOLID는 설계를 지키는 가이드라인
  3. 이 위에서 디자인 패턴이 의미를 가진다

0개의 댓글