응집도(Cohesion)

응집도(Cohesion) 응집도는 하나의 모듈이 얼마나 단일한 목적에 집중되어 있는지를 나타낸다. 모듈 내부의 요소들이 서로 얼마나 밀접하게 관련되어 있는지를 측정하는 척도이다. 높은 응집도는 모듈이 하나의 명확한 책임을 가지고 있음을 의미하며, 이는 좋은 설계의 특징이다. 특징 및 기능 모듈의 독립성을 나타냄 유지보수성과 재사용성 향상에 기여 모듈의 품질을 평가하는 지표로 사용 응집도의 종류 낮은 응집도부터 높은 응집도 순 우연적 응집도(Coincidental Cohesion): 서로 관련 없는 기능들이 한 모듈에 모여있는 경우. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // 우연적 응집도의 예 class Utility { public void calculateTax() { } public void formatDate() { } public void validateEmail() { } public void connectToDatabase() { } } // 개선된 버전 - 각 책임을 분리 class TaxCalculator { public void calculateTax() { } } class DateFormatter { public void formatDate() { } } class EmailValidator { public void validateEmail() { } } 논리적 응집도(Logical Cohesion): 논리적으로 비슷한 기능을 수행하지만 실제로는 다른 작업들을 하나의 모듈에서 처리하는 경우. ...

October 28, 2024 · 4 min · Me

코드 중복도 (Code Duplication)

코드 중복도 (Code Duplication) 코드 중복도는 소프트웨어 내에서 동일하거나 유사한 코드가 반복되는 정도를 나타낸다. 중복된 코드는 유지보수를 어렵게 만들고, 버그 수정 시 여러 곳을 동시에 수정해야 하는 문제를 야기한다. 이는 일반적으로 바람직하지 않은 프로그래밍 관행으로 간주되며, 소프트웨어의 유지보수성과 확장성을 저해할 수 있다. 특징과 특성 유지보수 어려움: 중복된 코드는 변경 시 여러 곳을 동시에 수정해야 하므로 유지보수가 어려워진다. 버그 발생 가능성 증가: 한 곳의 수정을 다른 곳에 반영하지 않을 경우, 일관성이 깨지고 버그가 발생할 수 있다. 코드량 증가: 중복 코드는 전체 코드의 양을 증가시켜 가독성을 떨어뜨리고 디버깅을 어렵게 만든다. OCP(Open-Closed Principle) 위배: 중복 코드는 수정에 닫혀 있어야 한다는 SOLID 원칙에 위배된다. 중복 코드 감지 방법 수동 코드 리뷰: 개발팀이 협력하여 코드를 검토하고 중복을 식별한다. 코드 분석 도구 사용: SonarQube, PMD, ESLint 등의 도구를 활용하여 자동으로 중복 코드를 탐지한다. 버전 관리 시스템 활용: Git 등의 버전 관리 시스템을 통해 코드 변경 사항을 비교하여 중복을 식별한다. IDE 기능 활용: 대부분의 현대적인 IDE는 코드 중복을 찾는 기능을 내장하고 있다. 코드 중복의 유형 완전 중복(Exact Duplication): 동일한 코드가 그대로 복사되어 사용되는 경우. ...

October 28, 2024 · 4 min · Me

결합도 (Coupling)

결합도 (Coupling) 결합도는 서로 다른 모듈 간의 상호 의존성이나 연관성을 측정하는 지표이다. 낮은 결합도는 모듈이 독립적이며 변경 시 다른 모듈에 미치는 영향이 적음을 의미한다. 모듈이란 클래스, 컴포넌트, 패키지 등 코드의 논리적 단위를 의미한다. 특징 및 기능 모듈 간 상호작용 정도를 나타냄 소프트웨어 구조의 품질을 평가하는 지표로 사용 유지보수성, 재사용성, 테스트 용이성에 영향을 미침 결합도의 종류 낮은 결합도부터 높은 결합도 순 내용 결합도(Content Coupling): 가장 강한 형태의 결합도로, 한 모듈이 다른 모듈의 내부 동작에 직접 관여하는 경우이다. ...

October 28, 2024 · 3 min · Me

테스트 커버리지 (Test Coverage)

테스트 커버리지 (Test Coverage) 테스트 커버리지는 테스트 대상 시스템이나 소프트웨어에 대해 얼마나 충분한 테스트가 수행되었는지를 나타내는 척도. 즉, 작성된 테스트 코드가 실제 프로덕션 코드를 얼마나 검증하고 있는지를 백분율로 표현한다. 테스트 커버리지를 측정하기 위해서는 실제로 코드가 실행되어야 하므로 테스트 커버리지는 기본적으로 동적 테스팅에 해당한다. 그리고, 테스트 커버리지를 측정하기 위해서는 코드의 내부 구조를 알아야 한다. 예를 들어: 구문 커버리지를 측정하려면 어떤 코드 라인이 실행되었는지 알아야 한다. 분기 커버리지를 측정하려면 조건문의 각 분기가 실행되었는지 알아야 한다. 경로 커버리지를 측정하려면 코드의 모든 가능한 실행 경로를 알아야 한다. 이러한 특성 때문에 테스트 커버리지는 화이트박스 테스팅 기법으로 분류된다. 테스트 커버리지가 실제 코드 실행을 통해(동적) 코드의 내부 구조를 분석하여(화이트박스) 테스트의 완성도를 측정하는 도구이다. 테스트 커버리지 자체는 측정 도구이며, 이를 측정하는 과정에서 정적 분석 도구를 보조적으로 사용할 수 있다. ...

October 28, 2024 · 3 min · Me

Halstead Complexity

Halstead Complexity Halstead 복잡도는 1977년 Maurice Howard Halstead가 제안한 소프트웨어 메트릭으로, 프로그램의 복잡성을 연산자(operators)와 피연산자(operands)의 수를 기반으로 측정한다. 이는 프로그램의 구현 난이도와 이해도를 정량적으로 평가하는 방법을 제공한다. 코드의 구현을 반영하지만 특정 플랫폼에서의 실행과는 독립적이다. 기본 측정 요소: 프로그램의 기본 요소는 다음과 같이 정의된다: n1: 고유 연산자의 수 n2: 고유 피연산자의 수 N1: 총 연산자의 출현 횟수 N2: 총 피연산자의 출현 횟수 예를 들어, 다음 코드를 살펴보자. 1 sum = a + b * 2; 이 코드에서: ...

October 28, 2024 · 2 min · Me

순환 복잡도 (Cyclomatic Complexity)

순환 복잡도 (Cyclomatic Complexity) 순환 복잡도는 1976년 Thomas McCabe가 제안한 메트릭으로, 프로그램의 논리적 복잡성을 정량적으로 측정하는 지표이다. 코드 내의 독립적인 경로의 수를 측정하여, 해당 코드를 완전히 테스트하기 위해 필요한 최소한의 테스트 케이스 수를 나타낸다. 순환 복잡도의 계산 방법은 다음과 같다: V(G) = E - N + 2P 여기서: E는 제어 흐름 그래프의 엣지(연결선) 수 N은 노드(구문) 수 P는 연결된 컴포넌트 수(일반적으로 1) 또는 더 간단하게: V(G) = 분기문의 수 + 1 여기서 분기문은 if, while, for, case 등의 조건문을 의미한다. ...

October 28, 2024 · 6 min · Me

Serialization and Deserialization

Serialization and Deserialization 직렬화(Serialization)와 역직렬화(Deserialization)는 객체 지향 프로그래밍, 데이터 저장, 네트워크 통신 등 다양한 분야에서 핵심적인 역할을 한다. 직렬화와 역직렬화의 개념 직렬화(Serialization)는 데이터 구조나 객체 상태를 저장하거나 전송할 수 있는 형식으로 변환하는 과정이다. 이 과정에서 객체의 상태는 바이트 스트림이나 텍스트 형식(예: JSON, XML)으로 변환된다. 직렬화는 복잡한 데이터 구조를 선형적인(linear) 형태로 “펼치는” 작업이라고 볼 수 있다. 역직렬화(Deserialization)는 직렬화의 반대 과정으로, 저장되거나 전송된 바이트 스트림이나 텍스트를 원래의 객체 구조로 다시 변환하는 작업이다. 이 과정을 통해 저장된 데이터를 애플리케이션에서 다시 사용할 수 있게 된다. ...

October 26, 2024 · 7 min · Me

데이터 불일치 (Data Inconsistency)

데이터 불일치 (Data Inconsistency) 동일한 데이터가 데이터베이스 내의 여러 위치에서 서로 다른 형식이나 값으로 존재하는 상황 Source: https://www.geeksforgeeks.org/what-is-data-inconsistency-in-dbms/ 발생 조건 데이터 불일치가 발생하는 주요 조건: 동시성 작업 여러 프로세스나 스레드가 동시에 데이터를 수정할 때 트랜잭션이 적절히 관리되지 않을 때 분산 환경 네트워크 지연이나 실패가 발생할 때 데이터 복제 과정에서 시간 차이가 발생할 때 캐싱 문제 캐시 무효화가 제대로 이루어지지 않을 때 캐시와 원본 데이터 간의 동기화 실패 시스템 오류 하드웨어 오류, 네트워크 문제, 소프트웨어 버그 등으로 인해 발생할 수 있다. 데이터 통합 문제: 서로 다른 소스의 데이터를 통합할 때 발생할 수 있다 해결책 및 방지책 데이터 표준화: 데이터 형식, 값, 표현을 일관되게 만든다. 데이터 검증: 데이터 입력 시 유효성 검사를 수행한다. 데이터 정제: 오류를 식별하고 수정하는 과정을 거친다. 데이터 거버넌스: 데이터 관리에 대한 명확한 정책과 절차를 수립한다. 동기화 메커니즘: 분산 시스템에서 데이터 동기화를 위한 알고리즘을 사용한다. 실제 시스템에서의 예방책 데이터 감사: 정기적인 데이터 감사를 통해 불일치를 식별한다. 자동화 도구 사용: 데이터 품질 관리 도구를 활용하여 불일치를 자동으로 탐지한다. 데이터 프로파일링: 데이터의 특성을 이해하고 잠재적 문제를 파악한다. 버전 관리: 데이터 변경 이력을 추적하여 불일치 발생 시 원인을 파악한다. 고려사항 및 주의사항 성능 영향: 데이터 일관성 유지 메커니즘이 시스템 성능에 미치는 영향을 고려해야 한다. 확장성: 대규모 분산 시스템에서의 데이터 일관성 유지 방법을 고려해야 한다. 사용자 교육: 데이터 입력 및 수정 시 주의사항에 대해 사용자를 교육해야 한다. 비즈니스 규칙 반영: 데이터 일관성 규칙에 비즈니스 로직을 반영해야 한다. 주의 사항 및 모범 사례 버전 관리 모든 데이터 변경에 버전 번호 부여 낙관적 락킹 구현 충돌 감지 및 해결 메커니즘 구축 캐시 전략 Cache-Aside 패턴 사용 적절한 TTL(Time-To-Live) 설정 캐시 무효화 전략 수립 동기화 메커니즘 분산 락 사용 이벤트 기반 동기화 멱등성 보장 모니터링 및 감사 버전 이력 관리 변경 로그 기록 불일치 감지 알림 실제 구현시 고려사항 확장성 수평적 확장을 고려한 설계 샤딩 전략 수립 복제 지연 관리 성능 캐시 적중률 최적화 인덱스 전략 수립 배치 처리 활용 복구 전략 백업 및 복구 계획 롤백 메커니즘 데이터 정합성 검증 모범 사례 단일 진실 소스(Single Source of Truth) 유지 데이터 품질 메트릭 정의 및 모니터링 데이터 소유권 및 책임 명확화 지속적인 데이터 품질 개선 프로세스 구축 데이터 불일치 해결을 위한 명확한 워크플로우 수립 파이썬 예제로 보는 데이터 불일치 다음은 데이터 불일치가 발생할 수 있는 상황과 이를 해결하는 방법을 보여주는 예제 ...

October 25, 2024 · 5 min · Me

Metric

Metric Metric는 시스템의 상태와 성능을 수치화하여 측정하는 중요한 관측 도구이다. Metric는 시스템의 상태, 동작, 성능 등을 나타내는 수치화된 측정값이다. 예를 들어, 웹 서버의 응답 시간, CPU 사용률, 메모리 사용량 등이 Metric가 될 수 있다. 장점 효율적인 저장: 숫자 데이터는 저장 공간을 적게 차지한다. 빠른 쿼리: 시계열 데이터베이스를 사용하여 빠른 검색과 분석이 가능하다. 장기 추세 분석: 오랜 기간 동안의 데이터를 저장하고 분석할 수 있다. 시각화 용이성: 그래프나 대시보드로 쉽게 표현할 수 있다. 단점 초기 설정에 시간과 노력이 필요하다 너무 많은 Metric는 오히려 혼란을 줄 수 있다 저장 공간과 처리 리소스가 필요하다 Metric의 중요성 성능 모니터링: 시스템의 전반적인 성능을 지속적으로 모니터링할 수 있다. 문제 감지: 비정상적인 패턴이나 임계값 초과를 빠르게 감지할 수 있다. 용량 계획: 리소스 사용량 추세를 분석하여 미래의 용량을 계획할 수 있다. 최적화: 성능 병목 현상을 식별하고 최적화할 수 있는 기회를 제공한다. Metric의 구성 요소 일반적인 Metric는 다음 요소로 구성된다: ...

September 28, 2024 · 3 min · Me

Trace

Trace Trace는 분산 시스템에서 요청의 흐름을 추적하고 시각화하는 데 사용된다. Trace는 분산 시스템에서 요청이나 트랜잭션이 여러 서비스와 컴포넌트를 통과하는 전체 여정을 기록한 것이다. 각 Trace는 하나 이상의 span으로 구성되며, 첫 번째 span은 root span이라고 한다. Trace의 목적 분산 시스템에서의 요청 흐름 이해 성능 병목 지점 식별 서비스 간 의존성 파악 오류 및 지연의 근본 원인 분석 Trace의 구성 요소 트레이스는 다음과 같은 구성 요소들로 이루어진다: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // 트레이스 시작 Span rootSpan = tracer.spanBuilder("checkout-process") .setSpanKind(SpanKind.SERVER) .startSpan(); try (Scope scope = rootSpan.makeCurrent()) { // 자식 스팬 생성 Span paymentSpan = tracer.spanBuilder("process-payment") .setParent(Context.current().with(rootSpan)) .startSpan(); try { processPayment(); paymentSpan.setStatus(StatusCode.OK); } catch (Exception e) { paymentSpan.setStatus(StatusCode.ERROR, e.getMessage()); throw e; } finally { paymentSpan.end(); } } finally { rootSpan.end(); } 트레이스 구성의 핵심 요소들: ...

September 28, 2024 · 3 min · Me