SOLID Principles 다시는 잊지 않을
Source: Dev.to
Source: …
소개
SOLID는 깔끔하고 유지보수 가능하며 확장 가능한 코드를 작성하기 위한 설계 원칙 집합입니다. SOLID는 다음을 의미합니다:
단일 책임 원칙 (SRP)
클래스나 함수는 오직 하나의 책임만 가져야 합니다. 아래의 나쁜 예시에서는 CreateUser 함수가 이메일 관련 로직까지 처리하고 있습니다.
나쁜 예시
public class UserService {
public void CreateUser(string email) {
var user = new User(email);
_repository.Save(user);
var smtpClient = new SmtpClient("smtp.company.com");
var message = new MailMessage(
"no-reply@myapp.com", email, "Welcome!",
"Your account was created successfully."
);
smtpClient.Send(message);
}
}
좋은 예시
public class UserService {
public void CreateUser(string email) {
var user = new User(email);
_repository.Save(user);
_emailService.SendWelcome(email);
}
}
개방/폐쇄 원칙 (OCP)
코드는 확장에는 열려 있어야 하지만 수정에는 닫혀 있어야 합니다. 기존 코드를 변경하지 않고도 새로운 동작을 추가할 수 있어야 합니다.
나쁜 예시
public class DiscountService {
public double Calculate(string type) {
if (type == "VIP") return 0.2;
if (type == "Regular") return 0.1;
if (type == "Employee") return 0.3;
return 0;
}
}
좋은 예시
public interface IDiscount {
double Calculate();
}
public class VipDiscount : IDiscount {
public double Calculate() => 0.2;
}
public class RegularDiscount : IDiscount {
public double Calculate() => 0.1;
}
public class DiscountService {
public double Calculate(IDiscount discount) {
return discount.Calculate();
}
}
리스코프 치환 원칙 (LSP)
서브타입은 기반 타입을 대체할 수 있어야 하며, 시스템을 깨뜨리지 않아야 합니다. 서브클래스는 기본 클래스의 기대 동작을 변경해서는 안 됩니다.
나쁜 예시
public class Bird {
public virtual void Fly() { }
}
public class Penguin : Bird {
public override void Fly() {
throw new Exception("Penguins can't fly");
}
}
Bird bird = new Penguin();
bird.Fly(); // throws exception
좋은 예시
public abstract class Bird { }
public interface IFlyingBird {
void Fly();
}
public class Eagle : Bird, IFlyingBird {
public void Fly() { }
}
public class Penguin : Bird { }
인터페이스 분리 원칙 (ISP)
클라이언트는 사용하지 않는 메서드에 의존해서는 안 됩니다. 인터페이스는 세분화되어 구현 클래스가 실제로 필요로 하는 동작만 제공하도록 해야 합니다.
나쁜 예시
public interface IWorker {
void Work();
void Eat();
}
public class Robot : IWorker {
public void Work() { }
public void Eat() {
// forced to implement this method even though it doesn't use it
}
}
좋은 예시
public interface IWorkable {
void Work();
}
public interface IEatable {
void Eat();
}
public class Human : IWorkable, IEatable {
public void Work() { }
public void Eat() { }
}
public class Robot : IWorkable {
public void Work() { }
}
의존성 역전 원칙 (DIP)
고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 합니다. 다시 말해, 구현이 아닌 추상화에 의존해야 합니다.
나쁜 예시
public class UserService {
private EmailService _emailService = new EmailService();
public void CreateUser(string email) {
// logic
_emailService.Send(email);
}
}
좋은 예시
public interface IEmailService {
void Send(string email);
}
public class EmailService : IEmailService {
public void Send(string email) { }
}
public class UserService {
private readonly IEmailService _emailService;
public UserService(IEmailService emailService) {
_emailService = emailService;
}
I’m happy to help translate the passage for you, but I don’t see a Source line in the message you provided. Could you please share the full text (including the “> Source: …” line) that you’d like translated? Once I have that, I’ll keep the source line unchanged and translate the rest into Korean while preserving the original formatting.