본문 바로가기
개발💻/C#

[C#] Coupling, Cohesion 1

by Sports Entrepreneur 2024. 8. 10.

결합도와 응집도의 중요성

  • 소프트웨어 설계에서 결합도(Coupling)와 응집도(Cohesion)는 모듈화와 관련하여 매우 중요한 개념
  • 시스템의 유지보수성, 확장성, 그리고 유연성을 좌우하는 핵심요소
  • 결합도는 낮을 수록 응집도는 높을 수록 이상적인 모듈화

 

결합도란 

 

결합도 (Coupling)는 모듈과 모듈 사이의 의존 정도를 의미합니다. 경할도가 높으면 모듈 간의 상호작용이 복잡해지고, 하나의 모듈을 수정할 때 다른 모듈에도 영향을 미칠 가능성이 커집니다. 따라서 결합도는 낮을수록 좋으며, 이는 모듈 간의 독립성을 높여 시스템의 유연성을 증가합니다.

  • 결합도가 높은 클래스의 문제점
    • 연관된 다른 클래스가 변경되면 더불어 변경해야 된다.
    • 수정하려는 클래스를 파악하기 위해 다른 클래스를 함께 파악해야된다.
    • 클래스를 재사용하기 어렵다.
  • 결합도가 낮은 클래스의 특징
    • OCP (Open Close Principle)의 원칙을 가진 클래스 : 확장에는 개방되고, 변경에는 폐쇄되어야 한다.
    • 다형성이 좋은 클래스

 

 결합도의 종류

결합도 종류 설명 특징 세기
자료 결합
(Data Coupling)
모듈 간에 단순한 데이터를 매개변수로 전달하는 경우 단순 데이터 전달, 정보 제공 역할만 수행
약함



















강함

스탬프 결합
(Stamp Coupling)
모듈 간에 복합 데이터 구조(예: 객체나 구조체)를 매개변수로 전달하는 경우 일부 데이터 구조만 사용, 특정 데이터 구조에 의존
제어 결합
(Control Coupling)
한 모듈이 다른 모듈의 동작을 제어하기 위해 제어 플래그를 전달하는 경우 제어 플래그로 동작 제어, 모듈 간 강한 의존성
외부 결합
(External Coupling)
두 모듈이 외부의 공통 자원을 공유할 때 발생 공통 자원 공유, 외부 환경에 의존
공유 결합
(Common Coupling)
두 모듈이 전역 데이터를 공유하는 경우 전역 데이터를 공유, 강한 의존성 및 데이터 무결성 문제 가능
내용 결합
(Content Coupling)
한 모듈이 다른 모듈의 내부 구현에 직접 접근하거나 수정하는 경우 다른 모듈의 내부에 직접 접근, 모듈 간의 매우 강한 의존성

 

1. 자료 결합 (Data Coupling)

  • 설명: 모듈 간에 단순한 데이터를 매개변수로 전달하는 경우
  • 예시 코드:
public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

public class Program
{
    public void Main()
    {
        Calculator calculator = new Calculator();
        int result = calculator.Add(5, 10); // 단순 데이터 전달
        Console.WriteLine(result);
    }
}

 

2. 스탬프 결합 (Stamp Coupling)

  • 설명: 모듈 간에 복합 데이터 구조(예: 객체나 구조체)를 매개변수로 전달하는 경우
  • 예시 코드:
public class Order
{
    public int OrderId { get; set; }
    public string ProductName { get; set; }
}

public class OrderProcessor
{
    public void ProcessOrder(Order order)
    {
        Console.WriteLine(order.ProductName);
    }
}

 

3. 제어 결합 (Control Coupling)

  • 설명: 한 모듈이 다른 모듈의 동작을 제어하기 위해 제어 플래그를 전달하는 경우
  • 예시 코드:
public class ReportGenerator
{
    public void GenerateReport(bool isDetailed)
    {
        if (isDetailed)
        {
            GenerateDetailedReport();
        }
        else
        {
            GenerateSummaryReport();
        }
    }

    private void GenerateDetailedReport()
    {
        // 상세 보고서 생성 로직
    }

    private void GenerateSummaryReport()
    {
        // 요약 보고서 생성 로직
    }
}

 

4. 외부 결합 (External Coupling)

  • 설명: 두 모듈이 외부의 공통 자원을 공유할 때 발생하는 결합도
  • 예시 코드:
public class ConfigManager
{
    public static string ConnectionString = "Database=MyDB;Server=MyServer;";
}

public class DatabaseService
{
    public void Connect()
    {
        string connString = ConfigManager.ConnectionString;
        // 데이터베이스 연결 로직
    }
}

 

5. 공유 결합 (Common Coupling)

  • 설명: 두 모듈이 전역 데이터를 공유하는 경우
  • 예시 코드:
public static class GlobalData
{
    public static int Counter = 0;
}

public class Incrementer
{
    public void Increment()
    {
        GlobalData.Counter++;
    }
}

public class Decrementer
{
    public void Decrement()
    {
        GlobalData.Counter--;
    }
}

 

6. 내용 결합 (Content Coupling)

  • 설명:  한 모듈이 다른 모듈의 내부 구현에 직접 접근하거나 수정하는 경우
  • 예시 코드:
public class DataStore
{
    private int _data = 42;

    public int GetData()
    {
        return _data;
    }
}

public class DataModifier
{
    public void ModifyData(DataStore store)
    {
        var field = store.GetType().GetField("_data", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        field.SetValue(store, 100);
        // DataStore의 내부 필드에 직접 접근하여 데이터를 수정
    }
}

 

 응집도란 

응집도(Cohesion)는 모듈이나 클래스 내에서 구성 요소들이 얼마나 밀접하게 관련되어 있는지를 나타내는 개념입니다. 응집도가 높을수록 모듈이나 클래스의 책임이 명확하고, 하나의 책임을 집중적으로 수행하게 됩니다. 이는 코드의 유지보수성을 높이고, 재사용성을 향상시킵니다.

  • 응집도가 낮은 클래스의 문제점
    • 여러 기능이 섞여 있어 클래스의 목적과 기능을 파악하기 어려움
    • 다양한 책임이 혼재되어 있어 특정 기능만을 재사용하거나 수정하기 힘듦
    • 여러 책임으로 인해 외부 변경에 영향을 많이 받아 버그 발생 가능성이 높아짐
  • 응집도가 높은 클래스의 특징
    • SRP (Single Responsibility Principle)의 원칙을 가진 클래스 : 하나의 명확한 역할만을 수행해 유지보수성과 확장성이 높아짐.
    • 다른 클래스와의 상호작용이 명확하고 간단해, 시스템의 복잡성을 줄이고 결합도를 낮춤

 

 응집도의 종류 

응집도 종류 설명 특징 세기
우연적 응집
(Coincidental Cohesion)
모듈 내의 기능들이 아무런 관련 없이 우연히 묶여있는 경우 기능들 간의 연관성이 없음 약함



















강함
논리적 응집
(Logical Cohesion)
비슷한 성격을 가진 기능들이 논리적으로 그룹화되어 있지만, 서로 독립적인 경우 기능들은 같은 그룹에 속하지만 직접적인 연관성은 없음
시간적 응집
(Temporal Cohesion)
특정 시간대에 수행해야 할 기능들이 한 모듈에 모여있는 경우 같은 시점에 실행되지만 각 작업의 목적은 다름
절차적 응집
(Procedural Cohesion)
기능들이 순차적으로 실행되며, 다음 단계의 작업을 위한 준비를 하는 경우 각 작업이 절차에 따라 연결됨
통신적 응집
(Communication Cohesion)
모듈 내의 기능들이 동일한 데이터를 사용하거나 조작하는 경우 기능들이 공통된 데이터에 대해 작업함
순차적 응집
(Sequential Cohesion)
한 기능의 출력이 다음 기능의 입력으로 사용되는 경우 순차적으로 연결된 작업들이 데이터를 전달하며 진행됨
기능적 응집
(Functional Cohesion)
모든 기능이 단일한 목적을 달성하기 위해 밀접하게 협력하는 경우 모듈이 하나의 명확한 책임을 가짐

 

 

1. 우연적 응집 (Coincidental Cohesion)

  • 설명: 모듈 내의 기능들이 아무런 관련 없이 우연히 묶여있는 경우
  • 예시 코드:
public class Utility
{
    public void PrintReport()
    {
        // 보고서 출력 로직
    }

    public void OpenFile(string filename)
    {
        // 파일 열기 로직
    }

    public void SaveData()
    {
        // 데이터 저장 로직
    }
}

 

2. 논리적 응집 (Logical Cohesion)

  • 설명: 비슷한 성격을 가진 기능들이 논리적으로 그룹화되어 있지만, 각 기능이 독립적임
  • 예시 코드:
public class ReportManager
{
    public void GenerateReport(string reportType)
    {
        if (reportType == "PDF")
        {
            GeneratePDFReport();
        }
        else if (reportType == "Excel")
        {
            GenerateExcelReport();
        }
    }

    private void GeneratePDFReport()
    {
        // PDF 보고서 생성 로직
    }

    private void GenerateExcelReport()
    {
        // Excel 보고서 생성 로직
    }
}

 

3. 시간적 응집 (Temporal Cohesion)

  • 설명: 특정 시간대에 수행해야 할 기능들이 한 모듈에 모여있는 경우
  • 예시 코드:
public class Startup
{
    public void Initialize()
    {
        LoadConfig();
        InitializeLogging();
        SetupDatabaseConnection();
    }

    private void LoadConfig()
    {
        // 설정 파일 로드
    }

    private void InitializeLogging()
    {
        // 로깅 초기화
    }

    private void SetupDatabaseConnection()
    {
        // 데이터베이스 연결 설정
    }
}

 

4. 절차적 응집 (Procedural Cohesion)

  • 설명: 기능들이 특정 절차를 따르며 순차적으로 실행되는 경우
  • 예시 코드:
public class OrderProcessor
{
    public void ProcessOrder(Order order)
    {
        ValidateOrder(order);
        ProcessPayment(order);
        ShipOrder(order);
    }

    private void ValidateOrder(Order order) { /* 주문 검증 로직 */ }
    private void ProcessPayment(Order order) { /* 결제 처리 로직 */ }
    private void ShipOrder(Order order) { /* 주문 발송 로직 */ }
}

 

5. 통신적 응집 (Communication Cohesion)

  • 설명: 모듈 내의 기능들이 동일한 데이터를 사용하거나 조작하는 경우
  • 예시 코드:
public class OrderProcessor
{
    public void ProcessOrder(Order order)
    {
        CalculateTotal(order);
        ApplyDiscount(order);
        UpdateInventory(order);
    }

    private void CalculateTotal(Order order) { /* 총액 계산 로직 */ }
    private void ApplyDiscount(Order order) { /* 할인 적용 로직 */ }
    private void UpdateInventory(Order order) { /* 재고 업데이트 로직 */ }
}

 

6. 순차적 응집 (Communication Cohesion)

  • 설명: 한 기능의 출력이 다음 기능의 입력으로 사용되는 경우
  • 예시 코드:
public class DataPipeline
{
    public void ProcessData(string input)
    {
        var formattedData = FormatData(input);
        var validatedData = ValidateData(formattedData);
        StoreData(validatedData);
    }

    private string FormatData(string input)
    {
        // 데이터 포맷팅
        return "Formatted Data";
    }

    private string ValidateData(string data)
    {
        // 데이터 검증
        return "Validated Data";
    }

    private void StoreData(string data)
    {
        // 데이터 저장
    }
}

 

7. 기적 응집 (Functional Cohesion)

  • 설명: 모듈 내의 모든 기능이 단일한 목적을 달성하기 위해 밀접하게 협력하는 경우
  • 예시 코드:
public class PaymentProcessor
{
    public void ProcessPayment(Order order)
    {
        AuthorizePayment(order);
        CapturePayment(order);
        GenerateReceipt(order);
    }

    private void AuthorizePayment(Order order)
    {
        // 결제 승인 로직
    }

    private void CapturePayment(Order order)
    {
        // 결제 처리 로직
    }

    private void GenerateReceipt(Order order)
    {
        // 영수증 생성 로직
    }
}

'개발💻 > C#' 카테고리의 다른 글

[C#] 구조체와 클래스의 차이  (0) 2024.10.06
[C#] readonly와 const의 차이  (0) 2024.10.05
[C#] Observer Pattern 1  (0) 2024.07.13
[C#] Delegate 2  (0) 2024.06.24
[C#] Delegate 1  (0) 2024.06.08