프로그래밍
SOLID
은율실험실
2024. 4. 12. 00:00
반응형
SOLID 은(는) SRP/OCP/LSP/DIP/ISP 원칙의 앞글자를 모은 것으로
객채지향 5대 원칙이라고도 불리우는 객체지향 설계에서 권장되는 원칙들을 의미해요.
SRP
SRP 은(는) 단일 책임 원칙(Single Responsibility Principle)의 축약어에요.
하나의 객체는 하나의 책임을 가져야 한다.
이는 객체가 복합적인 역할을 수행하면 안 된다는 것을 의미해요.
Bad
final class Generalist
{
public void cook()
{
System.out.println("Let me cook!");
}
public void paint()
{
System.out.println("Let's beat the devil out of it!");
}
}
Good
final class Chef
{
public void cook()
{
System.out.println("Let me cook!");
}
}
final class Painter
{
public void paint()
{
System.out.println("Let's beat the devil out of it!");
}
}
OCP
OCP 은(는) 개방-폐쇄 원칙(Open-Closed Principle)의 축약어에요.
확장(Extenension)은 허용하지만 수정(Modification)은 불가능해야 한다.
이는 기존의 코드를 변경하지 않고 기능을 추가할 수 있어야 한다는 것을 의미해요.
Bad
final class Animal
{
public void growl(String animal)
{
switch (animal)
{
case "cat" ->
{
System.out.println("Meow Meow!");
}
case "dog" ->
{
System.out.println("Bark Bark!");
}
case "pokemon" ->
{
System.out.println("Growls cutely to reduce the foe's ATTACK.");
}
}
}
}
Good
abstract class Animal
{
public abstract void growl();
}
final class Cat extends Animal
{
@Override
public void growl()
{
System.out.println("Meow Meow!");
}
}
final class Dog extends Animal
{
@Override
public void growl()
{
System.out.println("Bark Bark!");
}
}
final class Pokemon extends Animal
{
@Override
public void growl()
{
System.out.println("Growls cutely to reduce the foe's ATTACK.");
}
}
LSP
LSP 은(는) 리스코프 치환 원칙(Listov Substitution Principle)의 축약어에요.
하위 객체(Sub Class)는 상위 객체(Super Class)를 대체 가능해야 한다.
이는 의존관계를 맺는 객체가 공유하는 기능은 서로 동치여야 한다는 것을 의미해요.
Bad
@Getter @Setter @AllArgsConstructor
class Rectangle
{
int width;
int height;
public final int getArea()
{
return this.width * this.height;
}
}
class Square extends Rectangle
{
@Override
public void setWidth(int width)
{
super.setWidth(width);
super.setHeight(height); // side-effect, that is not present on its super-class
}
@Override
public void setHeight(int height)
{
super.setWidth(height); // side-effect, that is not present on its super-class
super.setHeight(height);
}
}
Good
abstract class Shape
{
public abstract int getArea();
}
@Getter @Setter @AllArgsConstructor
final class Square extends Shape
{
int side;
@Override
public int getArea()
{
return this.side * this.side;
}
}
@Getter @Setter @AllArgsConstructor
final class Rectangle extends Shape
{
int width;
int height;
@Override
public int getArea()
{
return this.width * this.height;
}
}
ISP
ISP 은(는) 인터페이스 분리 원칙(Interface Segregation Principle)의 축약어에요.
자신이 직업 사용하지 않는 메소드(Method)와 의존 관계를 맺어서는 안 된다.
이는 불필요한 상속과 구현을 최대한 방지해야 한다는 것을 의미해요.
Bad
abstract class Media
{
public abstract void read();
public abstract void watch();
}
final class Anime
{
@Override
public void read()
{
throw new UnsupportedOperationException("You don't [read] anime.");
}
@Override
public void watch()
{
System.out.println("Sis peulla magica!");
}
}
final class Manga
{
@Override
public void read()
{
System.out.println("I'm dropping my 2 cents here, Manga > Anime.");
}
@Override
public void watch()
{
throw new UnsupportedOperationException("You don't [watch] manga.");
}
}
Good
abstract class Media
{
// code goes here
}
interface Video permits Media
{
public abstract void watch();
}
interface Novel permits Media
{
public abstract void read();
}
final class Anime extends Media implements Video
{
@Override
public void watch()
{
System.out.println("Sis peulla magica!");
}
}
final class Manga extends Media implements Novel
{
@Override
public void read()
{
System.out.println("I'm dropping my 2 cents here, Manga > Anime.");
}
}
DIP
DIP 은(는) 의존 역전 원칙(Dependency Inversion Principle)의 축약어에요.
상위 객체(Super Class)는 하위 객체(Sub Class)를 의존해서는 안 된다.
이는 구체적인 객채가 추상적인 객채를 종속시켜야 한다는 것을 의미해요.
Bad
@Getter @Setter @AllArgsConstructor
final class Salad
{
public Apple[] ingredients;
}
final class Apple
{
public void eat()
{
System.out.println("Sweet!");
}
}
Good
@Getter @Setter @AllArgsConstructor
final class Salad
{
public Ingredient[] ingredients;
}
abstract class Ingredient
{
public abstract void eat();
}
final class Apple extends Ingredient
{
@Override
public void eat()
{
System.out.println("Sweet!");
}
}
final class Lettuce extends Ingredient
{
@Override
public void eat()
{
System.out.println("Fresh!");
}
}
반응형