본문 바로가기
Study/개념 정리

[Study] 객체지향 프로그래밍

by chobbo 2024. 7. 2.

SOLID 원칙

Single Responsibility Principle (단일 책임의 원칙)

- 각 클래스는 하나의 기능만 가지며, 이 하나의 기능(책임)을 수행하는데 집중해야 한다.

- SRP를 통해 프로그램의 유지보수성을 높일 수 있음

 

Open Close Principle (개방폐쇄의 원칙)

- 소프트웨어의 구성 요소는 확장에는 열려있고 수정에는 닫혀있어야 한다.

- 새로운 기능을 추가할 때 기존 코드를 수정하지 않고 기능을 추가할 수 있도록 설계해야 한다.

- 추상화나 다형성을 통해 구현 가능

 

Liskov Substitution Principle (리스코브 치환의 원칙)

- 자식 클래스는 언제나 부모 클래스로 교체(업캐스팅)할 수 있어야 한다.

- 즉 자식클래스에게 정말 필요한 기능만 부모 클래스에 존재해야한다.

- 다형성을 의미한다

 

Interface Segregation Principle (인터페이스 분리의 원칙)

- 클래스는 사용하지 않는 인터페이스는 구현하지 않아야 한다.

- 인터페이스를 용도에 맞게 잘 분리하는 것, 각 인터페이스가 하나의 책임만 수행하는 것


Dependency Inversion Principle (의존성 역전의 원칙)

- 클래스를 참조할 때 직접 참조가 아닌 상위요소(추상클래스 or 인터페이스)로 참조해야 한다.

- 이를 통해 결합도를 낮출 수 있음

 

 

 

다형성

- 하나의 객체에 여러 타입을 가질 수 있는 것

- 같은 이름의 메서드나 연산자가 다른 클래스에 대해 다른 동작을 하는 것

- Overload, Override 등을 통해 구현 가능

 

다형성 설계의 장점

1. 코드 재사용성 - 동일 코드가 재사용될 수 있다.

2. 유연성 - 객체의 형식을 추상화하여 결합도를 낮출 수 있다.

3. 코드 가독성이 높아진다

 

다형성 설계의 단점

1. 다른 클래스에서 동일한 이름의 메서드를 사용하므로 코드의 복잡성이 증가

2. 오버헤드 - 성능 손실이 발생할 수 있다.

3. 디버깅이 어려워진다

 

 

Override & Overload

Override?

상속 관계에 있는 클래스 간에 같은 이름의 메서드를 재정의

Overload?

두 메서드가 같은 이름을 가지고 있으나 매개변수가 다른 경우

 

 

 

확장 메서드

- 클래스의 외부에서 클래스의 메서드처럼 사용할 수 있는 새로운 메서드를 만드는 기능

- 정적 메서드처럼 정의 & 인스턴스 메서드처럼 사용

 

static class ExtensionMethods {
    public static void Print(this string s) {
        Console.WriteLine(s);
    }
}

class Example1 
    public static void Main(string[] args) {
        string text = "Hello";
        
        // 아래의 두 줄의 실행 결과는 같다
        "Hello".Print();
        text.Print();
    }
}

 

 

 

예시

using System;

// 사각형 클래스
public class Rectangle
{
    public double Width { get; set; }
    public double Height { get; set; }

    public double CalculateArea()
    {
        return Width * Height;
    }
}

// 원 클래스
public class Circle
{
    public double Radius { get; set; }

    public double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}

// 면적 계산기 클래스
public class AreaCalculator
{
    public double CalculateRectangleArea(Rectangle rectangle)
    {
        return rectangle.CalculateArea();
    }

    public double CalculateCircleArea(Circle circle)
    {
        return circle.CalculateArea();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Rectangle rectangle = new Rectangle { Width = 5, Height = 10 };
        Circle circle = new Circle { Radius = 3 };

        AreaCalculator calculator = new AreaCalculator();

        double rectangleArea = calculator.CalculateRectangleArea(rectangle);
        double circleArea = calculator.CalculateCircleArea(circle);

        Console.WriteLine($"Rectangle Area: {rectangleArea}");
        Console.WriteLine($"Circle Area: {circleArea}");
    }
}

 

1. 위 코드에서 삼각형 Triangle 클래스를 새로 작성한다고 했을 때, AreaCalculator의 코드를 수정하지 않고 AreaCalculator가 삼각형의 넓이를 계산하도록 만들 수 있을까?

: 만들 수 없다.

 

 

2. 위 코드가 유지보스 측면이 어려운 부분

: 새로운 도형 클래스를 작성할 때 마다 AreaCalculator에 내용을 추가해야한다.

 

 

실습 코드

using System;

namespace ArrayExtensions
{
    public static class ArrayExtension
    {
        public static double CalculateAverage(this int[] array)
        {
            // TODO: 확장 메서드 CalculateAverage를 구현하세요
            double sum = 0f;
            for (int i = 0; i < array.Length; i++)
            {
                sum += array[i];
            }
            sum = sum / array.Length;
            return sum;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 1, 2, 3, 4, 5 };
            
            // 확장 메서드를 사용하여 배열의 평균값을 계산하고 출력
            double average = numbers.CalculateAverage();
            Console.WriteLine($"The average is: {average}");
        }
    }
}

'Study > 개념 정리' 카테고리의 다른 글

[Study] 스택 메모리 , 힙 메모리  (0) 2024.07.03
[Study] 콜백, delegate, event  (0) 2024.07.03
[Study] 객체와 한정자  (0) 2024.07.01
[Study] 응집도 & 결합도  (0) 2024.05.27
[Study] 동기 & 비동기  (0) 2024.05.27