본문 바로가기
개발/기본) 알고리즘

알고리즘) SOLID 원칙 (솔리드 패턴)

by 테샤르 2023. 10. 19.

SOLID 원칙 (솔리드 패턴)

SOLID은 다섯 가지 기본 설계  원칙을 나타냅니다.

이 원칙들은 소프트웨어 디자인을 더 견고하고 유지보수하기 쉽게 만들기 위한 패턴으로 의미에 대해서 알고있으면 좋다.

실제 구현 방식에 대해서는 간략하게 정리한다.

 

 

반응형

 

< 단일 책임 원칙(Single Responsibility Principle - SRP) >

클래스는 단 하나의 책임만을 가져야 합니다. 여러가지 책임이 생기게되면  더 많은 기능이 추가되는 경우에는 해당 클래스를 확장해서 더 넓은 의미의 클래스로 재작성 및 리팩토링이 필요하다. (독립성)

 

< 개방-폐쇄 원칙(Open-Closed Principle - OCP) >

소프트웨어 엔터티(클래스, 모듈, 함수 등)는 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.

즉, 새로운 기능이 추가되면 기존 코드를 수정하지 않고도 확장이 가능해야 한다는 원칙이다.

 

예시 코드는 다음과 같다.

// 기존의 PaymentProcessor 클래스
public class PaymentProcessor
{
    public void ProcessPayment(decimal amount)
    {
        // 결제 처리 로직
        Console.WriteLine($"Payment processed for amount: {amount}");
    }
}

// 새로운 기능을 추가할 확장 클래스
public class NewPaymentProcessor : PaymentProcessor
{
    public void ProcessRefund(decimal amount)
    {
        // 환불 처리 로직
        Console.WriteLine($"Refund processed for amount: {amount}");
    }
}

// 클라이언트 코드
class Program
{
    static void Main()
    {
        PaymentProcessor paymentProcessor = new PaymentProcessor();
        paymentProcessor.ProcessPayment(100.0m);

        // 새로운 기능을 추가하더라도 기존 코드 수정 없이 사용 가능
        NewPaymentProcessor newPaymentProcessor = new NewPaymentProcessor();
        newPaymentProcessor.ProcessPayment(50.0m);
        newPaymentProcessor.ProcessRefund(20.0m);
    }
}

 

< 리스코프 치환 원칙(Liskov Substitution Principle - LSP) >

파생 클래스는 기본 클래스로 대체할 수 있어야 한다. 어떤 클래스의 인스턴스가 있다면 그것을 해당 클래스의 하위 클래스의 인스턴스로 대체해도 프로그램은 올바르게 동작해야 한다.

 

예시 코드는 다음과 같다.

// 기본 클래스
public class Bird
{
    public virtual void Fly()
    {
        Console.WriteLine("Flying...");
    }
}

// 파생 클래스
public class Sparrow : Bird
{
    // 기본 클래스의 메서드를 오버라이드
    public override void Fly()
    {
        Console.WriteLine("Sparrow flying...");
    }

    // 새로운 메서드 추가
    public void Chirp()
    {
        Console.WriteLine("Chirp chirp!");
    }
}

// 클라이언트 코드
class Program
{
    static void MakeBirdFly(Bird bird)
    {
        bird.Fly();
    }

    static void Main()
    {
        Bird bird = new Sparrow(); // 파생 클래스 인스턴스를 기본 클래스로 대체
        MakeBirdFly(bird); // LSP를 준수하여 Sparrow의 Fly 메서드가 호출됨

        Sparrow sparrow = new Sparrow();
        sparrow.Chirp(); // 파생 클래스의 추가된 메서드도 정상적으로 호출 가능
    }
}

 

<인터페이스 분리 원칙(Interface Segregation Principle - ISP) >

 

클라이언트는 자신이 사용하지 않는 메서드에 의존하면 안 된다.

어떤 클래스도 자신이 사용하지 않는 인터페이스의 메서드에 의존해서는 안 된다는 원칙이다.

 

예시 코드는 다음과 같다.

// 인터페이스
public interface IFlyable
{
    void Fly();
}

public interface IChirpable
{
    void Chirp();
}

// 구현 클래스
public class Sparrow : IFlyable, IChirpable
{
    public void Fly()
    {
        Console.WriteLine("Sparrow flying...");
    }

    public void Chirp()
    {
        Console.WriteLine("Chirp chirp!");
    }
}

// 클라이언트 코드
class Program
{
    static void MakeAnimalFly(IFlyable animal)
    {
        animal.Fly();
    }

    static void MakeAnimalChirp(IChirpable animal)
    {
        animal.Chirp();
    }

    static void Main()
    {
        Sparrow sparrow = new Sparrow();

        MakeAnimalFly(sparrow);
        MakeAnimalChirp(sparrow);
    }
}

 

<의존성 역전 원칙(Dependency Inversion Principle - DIP)>

고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 둘 모두 추상화에 의존해야 한다.

추상화된 것에 의존하도록 하는 것이 중요하다는 원칙이다.

 

예시 코드는 다음과 같다.

// 고수준 모듈 (추상화에 의존)
public interface IWorker
{
    void Work();
}

// 저수준 모듈 (추상화에 의존)
public class Worker : IWorker
{
    public void Work()
    {
        Console.WriteLine("Working...");
    }
}

// 고수준 모듈이 의존하는 저수준 모듈
public class Manager
{
    private IWorker _worker;

    // 의존성 주입
    public Manager(IWorker worker)
    {
        _worker = worker;
    }

    public void Manage()
    {
        _worker.Work();
    }
}

// 클라이언트 코드
class Program
{
    static void Main()
    {
        IWorker worker = new Worker(); // 저수준 모듈의 인스턴스 생성
        Manager manager = new Manager(worker); // 고수준 모듈이 의존성 주입을 통해 사용

        manager.Manage(); // 고수준 모듈이 저수준 모듈을 사용
    }
}

강제성이 있지는 않지만 코드를 작성하는 과정에서 SOLID 원칙에 의거해서 작성을 하게되면 재사용성과 독립성 그리고 확장성이 잘 고려된 코드로 작업의 효율성이 올라가고 휴먼이슈, 사이드 이펙트도 줄어들수 있다.

 

★★★★

 

반응형

댓글