모바일 개발의 아키텍처 원칙: 정의, 유형 및 적용 방법

저자: IT Sectr 게시일: 2026-05-04 읽는 시간: 10 분

아키텍처 원칙 및 방법론 — 개발자가 유지 관리 가능하고 확장 가능하며 이해하기 쉬운 코드를 만드는 데 도움이 되는 규칙과 권장 사항의 집합입니다. TIOBE Index (2025)에 따르면 아키텍처 원칙을 따르는 프로젝트는 심각한 결함이 40% 적습니다. 이 기사에서는 SOLID, GRASP, DRY, KISS, YAGNI 및 기타 원칙을 다루고 기술 부채 및 Code Smell에 대해 논의합니다.

핵심 요점

  • SOLID — 객체 지향 설계의 다섯 가지 원칙: SRP, OCP, LSP, ISP, DIP. 품질 아키텍처의 기초.
  • DRY (Don't Repeat Yourself) — 코드 중복을 피하세요. KISS (Keep It Simple, Stupid) — 단순할수록 좋습니다. YAGNI — 지금 필요하지 않은 코드는 작성하지 마세요.
  • GRASP — 클래스 간 책임 할당의 9가지 패턴. Law of Demeter (LoD) — 최소 결합 원칙.
  • 관심사 분리 (SoC) 및 모듈성 — 시스템을 독립적인 모듈로 분할. 높은 응집도와 낮은 결합도 — 좋은 아키텍처의 목표.
  • 기술 부채 및 Code Smell — 원칙 위반의 불가피한 결과. 적시에 발견하고 제거하는 것이 프로젝트 건강의 핵심입니다.

SOLID 원칙

아키텍처 원칙 — 품질 코드의 기초입니다. SOLID는 로버트 마틴(«엉클 밥»)이 도입한 약어로 객체 지향 설계의 다섯 가지 원칙을 설명합니다. SOLID를 따르면 코드가 더 유연해지고 테스트 가능하며 변경에 강해집니다. 아키텍처 원칙 위반은 기술 부채의 주요 원인 중 하나입니다.

각 원칙을 살펴보겠습니다. Single Responsibility Principle (SRP) — 각 클래스는 변경 이유가 하나만 있어야 합니다. Open/Closed Principle (OCP) — 클래스는 확장에는 열려 있지만 수정에는 닫혀 있어야 합니다. Liskov Substitution Principle (LSP) — 하위 유형의 객체는 로직을 깨뜨리지 않고 기본 유형의 객체를 대체할 수 있어야 합니다. Interface Segregation Principle (ISP) — 하나의 일반 인터페이스보다 여러 개의 특화된 인터페이스가 더 좋습니다. Dependency Inversion Principle (DIP) — 구체적인 구현이 아닌 추상화에 의존해야 합니다.

SonarQube 분석(2025)에 따르면 SOLID 원칙 위반은 상업 프로젝트의 68%에서 발생합니다. 가장 일반적인 문제는 SRP 위반(35%)과 ISP 위반(22%)입니다. IT Sectr에서는 아키텍처 검토 단계에서 SOLID를 구현합니다. 이를 통해 문제가 기술 부채로 발전하기 전에 식별할 수 있습니다.

Single Responsibility Principle (SRP)

SRP(단일 책임 원칙) — 가장 중요하면서도 동시에 가장 자주 위반되는 SOLID 원칙입니다. 이 원칙은 다음과 같습니다: 클래스는 변경 이유가 하나만 있어야 합니다. 클래스가 너무 많은 일을 하면 테스트, 수정 및 이해가 어렵습니다.

일반적인 위반은 데이터를 처리하고 데이터베이스에 저장하며 이메일 알림을 보내는 세 가지 작업을 동시에 수행하는 클래스입니다. 아래 예제는 Kotlin에서 SRP 위반과 이를 수정하는 방법을 보여줍니다.

kotlin
// SRP 위반 — 클래스가 세 가지 다른 작업을 수행
class UserService {
    fun registerUser(email: String, name: String) {
        // 1. 데이터 검증
        if (!email.contains("@")) throw IllegalArgumentException("Invalid email")
        
        // 2. 데이터베이스에 저장
        val user = User(email, name)
        database.save(user)
        
        // 3. 알림 보내기
        emailService.sendWelcomeEmail(email, name)
    }
}

// 수정 — 세 개의 클래스로 분할
class UserRegistrationService {
    fun register(email: String, name: String) {
        UserValidator().validate(email)
        val user = User(email, name)
        UserRepository().save(user)
        NotificationService().sendWelcome(user)
    }
}

수정된 버전에서는 각 클래스가 자신의 작업을 담당합니다: UserValidator — 검증, UserRepository — 저장, NotificationService — 알림. 이렇게 하면 코드를 테스트 가능하고 재사용 가능하게 만들며, 검증 로직을 변경하지 않고 데이터베이스 구현을 교체할 수 있습니다.

GRASP 및 Law of Demeter

GRASP (General Responsibility Assignment Software Patterns) — Craig Larman이 설명한 객체 간 책임 할당의 9가지 아키텍처 원칙입니다. SOLID와 달리 GRASP는 «어떤 클래스가 이 메서드를 포함해야 하는가?»라는 질문에 답합니다. 주요 패턴: Information Expert, Creator, Controller, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations.

Law of Demeter (LoD, 최소 결합 원칙) — 간단한 규칙: 객체는 직접적인 이웃하고만 통신해야 합니다. a.getB().getC().doSomething()과 같이 작성해서는 안 됩니다. 이는 클래스 간 강한 결합을 만듭니다. LoD는 재사용성을 향상시키고 테스트를 단순화합니다.

IT Sectr에서는 코드 리뷰 중 LoD 준수 여부를 확인합니다. 메서드가 세 개 이상의 객체를 «통과»하면 아키텍처를 단순화해야 한다는 신호입니다. LoD 위반은 대규모 프로젝트에서 가장 흔한 Code Smell 중 하나입니다.

DRY / KISS / YAGNI

DRY (Don't Repeat Yourself), KISS (Keep It Simple, Stupid) 및 YAGNI (You Ain't Gonna Need It) — 모든 개발자에게 알려진 세 가지 기본 아키텍처 원칙입니다. 단순함에도 불구하고 위반은 지속적으로 발생합니다.

DRY — 코드를 중복하지 마세요. 동일한 로직이 두 곳에 나타나면 공통 메서드나 클래스로 추출하세요. 중복은 버그의 주요 원인입니다: 한 곳에서 수정한 내용을 다른 곳에 적용하는 것을 잊어버립니다. DRY는 유사한 코드를 가질 수 없다는 의미가 아닙니다 — 중요한 것은 비즈니스 로직이 반복되지 않는 것입니다.

KISS — 단순할수록 좋습니다. 많은 추상화와 상속이 있는 복잡한 솔루션은 종종 과도합니다. 간단한 솔루션으로 시작하고 필요할 때만 복잡하게 만드세요. YAGNI — «언젠가 나중에» 필요할 수 있는 기능을 위해 코드를 작성하지 마세요. 이는 코드베이스를 비대하게 만들고 유지 관리 복잡성을 증가시킵니다.

DRY — Don't Repeat Yourself

DRY — 단순히 복사-붙여넣기가 없다는 의미가 아닙니다. 이는 지식이나 로직의 모든 부분이 시스템에서 단일하고 명확한 표현을 가져야 한다는 원칙입니다. 중복은 명시적(복사된 코드)일 수도 있고 암시적(다른 계층의 동일한 로직)일 수도 있습니다.

IT Sectr에서는 코드 분석 메트릭을 사용하여 중복을 감지합니다. SonarQube 및 Detekt와 같은 도구는 중복 코드의 비율을 보여줍니다. 5% 이상의 값은 리팩토링의 이유가 됩니다. 그러나 잘못된 추상화를 희생하면서 DRY를 달성해서는 안 된다는 것을 기억하는 것이 중요합니다 — 두 개의 유사한 코드 조각을 결합하면 이해가 복잡해질 경우 그대로 두는 것이 더 나을 때도 있습니다.

관심사 분리 및 모듈성

관심사 분리 (SoC) — 시스템을 독립적인 부분(관심사)으로 나누고 각 부분이 자신의 작업을 해결하는 아키텍처 원칙입니다. 전형적인 예는 계층 분리입니다: 프레젠테이션, 비즈니스 로직, 데이터 액세스. 각 계층은 아래 계층에만 의존합니다.

모듈성 — 시스템을 모듈로 나눌 수 있는 정도입니다. 모듈은 잘 정의된 인터페이스를 가진 논리적으로 관련된 클래스 그룹입니다. 모듈은 느슨하게 결합(low coupling)되고 강하게 응집(high cohesion)되어야 합니다.

응집도 vs 결합도

응집도 (Cohesion) — 동일한 모듈 내의 요소들이 서로 얼마나 관련되어 있는지를 측정합니다. 높은 응집도는 좋습니다: 클래스가 한 가지 일을 하고 그것을 잘 수행합니다. 낮은 결합도 (Low coupling) — 모듈이 서로 얼마나 독립적인지를 측정합니다. 낮은 결합도는 좋습니다: 한 모듈의 변경이 다른 모듈을 깨뜨리지 않습니다.

이상적인 아키텍처는 높은 응집도와 낮은 결합도입니다. 실제로 이는 클래스가 동일한 데이터에 대해 작업하는 메서드를 포함하고(응집도), 구체적인 구현이 아닌 추상화에만 의존한다는 것을 의미합니다(결합도). 불균형은 «갓 오브젝트»나 «스파게티 코드»로 이어집니다.

기술 부채 및 Code Smell

기술 부채 (Technical Debt) — Ward Cunningham이 도입한 은유로, 팀이 최적이 아닌 아키텍처 결정과 아키텍처 원칙 위반에 대해 지불하는 «이자»를 설명합니다. 금융 부채와 마찬가지로 기술 부채는 의도적인 것(빠르게 진행하기로 결정하고 나중에 다시 작업)과 의도하지 않은 것(경험 부족으로 인한 나쁜 아키텍처)이 있을 수 있습니다.

Code Smell — 코드의 깊은 문제에 대한 표면적 징후입니다. 이 용어는 Martin Fowler가 그의 저서 «Refactoring»에서 대중화했습니다. 일반적인 Code Smell: 긴 메서드, 큰 클래스, 긴 호출 체인, 코드 중복, 과도한 주석 사용(명확한 코드 대신).

IT Sectr에서는 기술 부채를 Jira에서 별도의 작업으로 추적합니다. 각 스프린트마다 리팩토링 및 부채 상환에 20%의 시간을 할당합니다. 기술 부채에 대한 체계적인 작업은 새 기능을 추가하는 데 처음부터 개발하는 것보다 더 많은 시간이 걸리는 상황을 피하는 유일한 방법입니다.

자주 묻는 질문

가장 중요한 SOLID 원칙은 무엇인가요?

Single Responsibility Principle (SRP) — 가장 중요합니다. 그 위반이 자동으로 다른 원칙의 위반으로 이어지기 때문입니다. 여러 책임을 가진 클래스는 테스트, 확장 및 유지 관리가 어렵습니다. SRP부터 시작하세요 — 나머지는 따라올 것입니다.

응집도와 결합도의 차이는 무엇인가요?

응집도 (Cohesion) — 모듈 내부의 연결(높을수록 좋음). 결합도 (Coupling) — 모듈 간의 연결(낮을수록 좋음). 좋은 아키텍처는 높은 응집도와 낮은 결합도를 지향합니다.

항상 모든 SOLID 원칙을 따라야 하나요?

아니요, 원칙은 지침이지 절대적인 법칙이 아닙니다. 소규모 프로젝트나 프로토타입에서는 SOLID를 과도하게 따르면 오버엔지니어링으로 이어질 수 있습니다. «충분히 좋은» 아키텍처와 개발 속도 사이의 균형을 찾는 것이 중요합니다.

프로젝트에서 기술 부채를 어떻게 감지하나요?

정적 분석기(SonarQube, Detekt, ESLint), 코드 리뷰 및 코드 메트릭을 사용하세요. 부채의 징후: 코드 테스트가 어렵고, 한 곳의 변경이 다른 곳을 깨뜨리며, 새 기능을 추가하는 시간이 스프린트마다 증가합니다. 정기적인 리팩토링이 부채를 통제하는 유일한 방법입니다.

요약

  • SOLID — OOP의 다섯 가지 원칙: SRP(단일 책임), OCP(개방/폐쇄), LSP(리스코프 치환), ISP(인터페이스 분리), DIP(의존성 역전).
  • GRASP — 책임 할당의 9가지 패턴. Law of Demeter — 최소 객체 결합.
  • DRY — 코드를 중복하지 마세요. KISS — 단순할수록 좋습니다. YAGNI — «미래를 위해» 불필요한 코드를 작성하지 마세요.
  • 관심사 분리 — 시스템을 명확한 책임 영역을 가진 부분으로 분할.
  • 높은 응집도, 낮은 결합도 — 모든 아키텍처의 주요 목표. 모듈 내 응집도 — 높게, 모듈 간 — 낮게.
  • 기술 부채 — 속도의 불가피한 대가. 정기적인 리팩토링(20% 시간)이 성장을 방지합니다.
  • Code Smell — 코드 문제의 징후(긴 메서드, 큰 클래스, 중복). 코드 리뷰 및 정적 분석을 통해 식별됩니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의