Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C#으로 개방-폐쇄 원칙(OCP)을 구현하는 방법

클래스, 모듈, 함수와 같은 소프트웨어 엔티티는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 합니다.

개방-폐쇄 원칙이란?

개방-폐쇄 원칙(Open Close Principle, OCP)은 SOLID 설계 원칙 중 하나로, 기존 코드를 최소한으로 변경하면서 새로운 기능을 추가할 수 있도록 코드를 설계하고 작성해야 한다는 원칙입니다. 즉, 새로운 기능은 새로운 클래스 형태로 추가하되, 가능한 한 기존 코드는 그대로 유지하는 방식으로 설계해야 합니다.

예제

개방-폐쇄 원칙 적용 전 코드

아래 코드에서는 도형의 종류를 확인하기 위해 조건문(if)을 사용합니다. 따라서 새로운 도형(예: 삼각형)이 추가될 때마다 계산기 클래스의 내부 로직을 직접 수정해야 하는 문제가 있습니다.

using System;
using System.Net.Mail;
namespace SolidPrinciples.Open.Closed.Principle.Before{
    public class Rectangle{
        public int Width { get; set; }
        public int Height { get; set; }
    }
    public class CombinedAreaCalculator{
        public double Area (object[] shapes){
            double area = 0;
            foreach (var shape in shapes){
                if(shape is Rectangle){
                    Rectangle rectangle = (Rectangle)shape;
                    area += rectangle.Width * rectangle.Height;
                }
            }
            return area;
        }
    }
    public class Circle{
        public double Radius { get; set; }
    }
    public class CombinedAreaCalculatorChange{
        public double Area(object[] shapes){
            double area = 0;
            foreach (var shape in shapes){
                if (shape is Rectangle){
                    Rectangle rectangle = (Rectangle)shape;
                    area += rectangle.Width * rectangle.Height;
                }
                if (shape is Circle){
                    Circle circle = (Circle)shape;
                    area += (circle.Radius * circle.Radius) * Math.PI;
                }
            }
            return area;
        }
    }
}

위 예제에서 원(Circle)이라는 새로운 도형을 지원하기 위해 CombinedAreaCalculatorChange처럼 기존 클래스를 복사하거나 수정해야 했습니다. 이는 확장에 열려 있지 않은 구조로, 도형이 늘어날수록 코드 중복과 오류 가능성이 커집니다.

개방-폐쇄 원칙 적용 후 코드

개방-폐쇄 원칙을 적용하면 추상 클래스(또는 인터페이스)를 활용해 각 도형이 자신의 넓이를 스스로 계산하도록 만들 수 있습니다. 이렇게 하면 새로운 도형이 추가되더라도 기존 계산기 코드는 전혀 수정할 필요가 없습니다.

namespace SolidPrinciples.Open.Closed.Principle.After{
    public abstract class Shape{
        public abstract double Area();
    }
    public class Rectangle: Shape{
        public int Width { get; set; }
        public int Height { get; set; }
        public override double Area(){
            return Width * Height;
        }
    }
    public class Circle : Shape{
        public double Radius { get; set; }
        public override double Area(){
            return Radius * Radius * Math.PI;
        }
    }
    public class CombinedAreaCalculator{
        public double Area (Shape[] shapes){
            double area = 0;
            foreach (var shape in shapes){
                area += shape.Area();
            }
            return area;
        }
    }
}

정리

리팩토링 후에는 Shape라는 추상 클래스를 통해 다형성을 활용합니다. 삼각형이나 육각형 같은 새로운 도형이 필요해지면 Shape를 상속받아 Area() 메서드만 구현하면 되며, CombinedAreaCalculator는 어떠한 변경도 없이 새 도형을 처리할 수 있습니다. 이것이 바로 개방-폐쇄 원칙의 핵심으로, 코드의 유지보수성과 확장성을 크게 향상시킵니다.