객체지향 방법론으로 설계하는 유지보수 가능한 소프트웨어
객체지향 방법론의 핵심 원칙과 OOAD, UML, SOLID를 바탕으로 유연하고 유지보수하기 쉬운 소프트웨어 설계 방식을 정리한다.
2026-08-14 · 최초 발행 2025-05-23
객체의 협력으로 문제를 모델링하는 방식
객체지향 방법론은 현실 세계의 개념과 개체(entity)를 객체(object)로 모델링해 소프트웨어를 개발하는 접근이다. 문제를 객체들의 상호작용으로 분석하고 설계하므로, 업무 영역의 구조를 비교적 직관적으로 표현할 수 있다.
구조적 방법론에서 발전한 이 방식은 데이터와 함수를 하나로 묶는다. 내부 구현을 각 객체에 두고 객체 간에는 필요한 인터페이스로만 협력하게 만들어, 대규모 시스템의 개발과 유지보수에 적합한 구조를 제공한다. 소프트웨어 위기(Software Crisis)에 대응하는 패러다임으로 1980년대부터 산업에 본격 적용됐다.
변경을 다루는 객체지향의 기본 성질
캡슐화로 내부 상태를 보호한다
캡슐화(Encapsulation)는 데이터와 함수를 하나의 단위로 묶어 객체를 구성하는 원칙이다. 외부에서는 정의된 인터페이스를 통해서만 객체에 접근하며, 내부 구현은 숨긴다. 이 정보 은닉(Information Hiding)은 모듈 간 의존성을 낮추고 유지보수성을 높인다.
은행 계좌를 예로 들면 잔액은 객체 내부에 두고, 입금과 출금 메서드로만 변경하도록 설계할 수 있다.
상속으로 계층 관계를 표현한다
상속성(Inheritance)은 기존 클래스의 속성과 기능을 새 클래스가 물려받는 메커니즘이다. 코드 재사용성을 높이는 동시에 부모 클래스와 자식 클래스 사이의 계층 관계를 표현한다.
저축계좌가 은행계좌라는 IS-A 관계는 다음과 같이 모델링할 수 있다.
같은 인터페이스에 다른 구현을 연결한다
다형성(Polymorphism)은 동일한 인터페이스를 통해 서로 다른 구현을 제공하는 능력이다. 메서드 오버라이딩(Method Overriding)과 오버로딩(Overloading)을 통해 구현하며, 확장 가능한 설계에 활용된다.
원, 사각형, 삼각형은 모두 area() 메서드를 가지지만 각자의 방식으로 면적을 계산할 수 있다.
추상화로 필요한 개념만 남긴다
추상화(Abstraction)는 복잡한 시스템에서 핵심 개념과 기능을 추출하는 과정이다. 관련된 특성만 모델에 포함하고 불필요한 세부 사항은 제외해 모델을 단순화한다. 인터페이스와 추상 클래스가 대표적인 구현 수단이다.
결제 시스템에서는 신용카드, 페이팔, 계좌이체처럼 서로 다른 결제 방식을 추상 Payment 인터페이스 아래로 통합할 수 있다.
분석에서 설계로 이어지는 OOAD
객체지향 분석 및 설계(OOAD)는 문제 영역을 이해하는 단계와 이를 구현 가능한 구조로 바꾸는 단계를 연결한다.
객체지향 분석(OOA)에서는 문제 영역의 객체와 클래스를 식별하고 관계를 정의한다. 도메인 모델(Domain Model)로 현실의 개념을 소프트웨어 모델에 매핑하며, 유스케이스(Use Case) 분석으로 시스템 요구사항을 정의한다. CRC(Class-Responsibility-Collaboration) 카드 기법도 이 과정에 활용된다.
객체지향 설계(OOD)는 분석에서 찾은 개념을 실제 구현 가능한 클래스로 전환하는 과정이다. 클래스와 객체의 상호작용 메커니즘을 설계하고, 필요에 따라 디자인 패턴을 적용한다. UML(Unified Modeling Language)은 이 설계 내용을 공유하고 검토하는 표현 수단이다.
UML로 구조와 상호작용을 기록한다
클래스 다이어그램(Class Diagram)은 클래스, 속성, 메서드, 관계를 통해 시스템의 정적 구조를 나타낸다.
시퀀스 다이어그램(Sequence Diagram)은 객체 사이의 메시지 흐름과 생명선(lifeline)을 시간 순서대로 표현한다.
유스케이스 다이어그램(Use Case Diagram)은 사용자와 시스템의 상호작용 및 시스템 기능 요구사항을 시각화한다. 상태 다이어그램(State Diagram)은 객체 상태의 변화와 전이 조건을 표현하며, 활동 다이어그램(Activity Diagram)은 시스템의 동적 행위와 워크플로우를 다룬다.
객체 단위로 나눴을 때 얻는 설계상 이점
객체지향 구조에서는 시스템을 독립적인 모듈인 객체로 분해할 수 있어 개발과 유지보수가 수월해진다. 클래스 라이브러리와 프레임워크를 통해 코드를 재사용할 수 있고, 기존 코드를 수정하지 않고 새 클래스를 추가하는 방식으로 기능을 확장할 수 있다.
인터페이스와 다형성은 설계의 유연성을 높인다. 실제 업무 프로세스와 유사한 구조로 모델링할 수 있으며, 객체 단위의 단위 테스트도 가능하다.
SOLID로 의존 관계를 제어한다
단일 책임 원칙(SRP: Single Responsibility Principle)은 클래스가 단 하나의 책임만 가져야 하며, 변경 이유도 오직 하나여야 한다는 원칙이다.
개방-폐쇄 원칙(OCP: Open-Closed Principle)은 확장에는 열려 있고 수정에는 닫혀 있어야 한다고 본다. 새 기능은 기존 코드를 수정하지 않고 추가할 수 있어야 한다.
리스코프 치환 원칙(LSP: Liskov Substitution Principle)은 상위 타입 객체를 하위 타입 객체로 치환해도 프로그램이 올바르게 동작해야 한다는 기준이다. 상속 관계를 설계할 때 중요한 원칙이다.
인터페이스 분리 원칙(ISP: Interface Segregation Principle)은 클라이언트가 사용하지 않는 메서드에 의존하지 않아야 한다고 말한다. 이를 위해 인터페이스를 작고 특화된 단위로 분리한다.
의존성 역전 원칙(DIP: Dependency Inversion Principle)은 상위 모듈과 하위 모듈이 서로의 구체 구현이 아니라 추상화에 의존하도록 요구한다. 구현 클래스보다 인터페이스나 추상 클래스에 의존하는 설계가 여기에 해당한다.
도메인별 객체지향 모델링
전자상거래 시스템에서는 사용자, 상품, 장바구니, 주문을 객체로 모델링할 수 있다. 결제 시스템은 인터페이스로 추상화해 다양한 결제 방식을 적용하고, 상품 카테고리는 상속 구조로 설계할 수 있다.
금융 시스템에서는 여러 계좌 유형을 클래스 계층구조로 구성하고, 거래(Transaction) 객체를 다형성으로 처리한다. 보안 정책은 캡슐화해 구현할 수 있다.
모바일 애플리케이션에서는 UI 컴포넌트를 객체로 모델링하며, 이벤트 처리는 옵저버 패턴으로 구현할 수 있다. 데이터 접근 계층은 인터페이스로 추상화한다.
컴포넌트와 애자일 개발로 확장되는 객체지향
객체지향 방법론은 재사용 가능한 컴포넌트 중심 개발로 이어지고, 마이크로서비스 아키텍처와도 연계된다. 애자일 방법론에서는 반복적·점진적 개발 과정과 지속적인 리팩토링을 통해 설계를 개선한다.
GoF(Gang of Four) 디자인 패턴은 객체지향 원칙을 구현하는 재사용 가능한 해결책으로 활용된다. 객체지향적 사고는 프로그래밍 기법에 그치지 않고, 복잡한 문제를 구조화하고 협력 관계로 풀어내는 방식이 된다.