🔥딱 8일간! 인프런x토스x허먼밀러 역대급 혜택

Day4 SOLID

image

SOLID 5가지 원칙

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

  1. 하나의 클래스는 하나의 책임만 가진다.

ex) 사용자 삭제하는 클래스는 삭제하는 기능만 가진다 다른 사용자 등록, 조회,수정기능등의 여러가지를 집어넣지 않는다 최근에 전화번호부관리 장난감프로젝트를 만들었습니다.

각각의 클래스는 일반인, 대학생, 회사원으로 각각 만들고 메뉴는 3가지로 1번은 입력 2번은 검색 3번은 삭제로 입력방식을 분류하였습니다.

-MenuViewer클래스는 메뉴종류기능만 입력하는형식

public class MenuViewer {

  public static Scanner keyboard=new Scanner(System.in);

  public static void showMenu(){
    System.out.println("선택하세요...");
    System.out.println("1. 데이터 입력");
    System.out.println("2. 데이터 검색");
    System.out.println("3. 데이터 삭제");
    System.out.println("4. 프로그램 종료");
    System.out.print("선택 : ");
  }
}

-전화번호부정보자메서드는 지우기 기능만합니다.

public boolean deleteData() throws MenuChoiceException {
  System.out.println("데이터 삭제를 시작합니다.");
  System.out.print("이름 : ");
  String removeName = MenuViewer.keyboard.nextLine();
  for(PhoneInfo info:infoList){
    if(info.name.equals(removeName)){
      boolean remove = infoList.remove(info);
      System.out.println("데이터 삭제가 완료되었습니다. \n");
      return remove;
    }else{
      System.out.println("해당하는 데이터가 존재하지 않습니다. \n");
    }
  }

  return false;
}

이렇게 각각의 클래스나 메서드는 하나의 기능만 부여하는 단일 책임 원칙을 따르고 있습니다.

 

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

기능추가는 가능하지만 기존코드는 수정하지 말아야 한다

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

public class PhoneCompanyInfo extends PhoneInfo {

  String company;

  public PhoneCompanyInfo(String name, String num, String company) {
    super(name, num);
    this.company = company;
  }

  public void showPhoneInfo(){
    super.showPhoneInfo();
    System.out.println("company : "+company);
  }

  public int hashCode(){
    return name.hashCode();
  }

  public boolean equals(Object obj){
    PhoneCompanyInfo cmp=(PhoneCompanyInfo)obj;
    if(name.compareTo(cmp.name)==0){
      return true;
    }else{
      return false;
    }
  }
}

public class PhoneCompanyInfo extends PhoneInfo{} 처럼 외부라이브러리라도 그 기능을 extedns 또는 implements로 구현부를 새로운 기능으로 추가할 수 있습니다.

주의사항

protected로 시작하는 메서드나 필드는 외부라이러리의 경우 기능추가를 할수 없어 개방-폐쇄 원칙에 위반됩니다.

 

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

부모 클래스의 기능을 자식 클래스가 대체할 수 있어야 한다

-인터페이스로 부모클래스에서 호출기능을 만들었다면 자식클래스에서는 부모가 물려준 기능을 구현할수 있습니다.

  interface Animal{
    void sound();

    void sleep();
}
class Dog implements Animal{
@Override
public void sound(){

    System.out.println(”멍멍”);

}
@Override
public void sleep(){

    System.out.println(”강아지는 코골고 궁시렁거리면서 잡니다”);

  }
}

 

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

사용자는 자신이 사용하지 않는 인터페이스에 의존하지 않는다.

-필요한 메소드만 있는 작은 인터페이스를 사용하는것이 좋다

class Vehicle {
    public void startEngine() {
        
    }
}

class Car extends Vehicle {
    @Override
    public String startEngine() {
        return "Car engine started";
    }
}

class Bicycle extends Vehicle {
    @Override
    public void startEngine() {
        throw new UnsupportedOperationException("Bicycles don't have engines");
    }
}

Vehicle은 이동수단이라 public void startEngine(){}을 정의하였습니다. 그러나 Car는 자동차 엔진으로 시작합니다. 다른 Bicycle은 엔진이 필요없는 특정 이동수단의 인터페이스를 만들어야 합니다.

 

DIP(Dependency Injection Principle) 의존성 역전의 원칙

구체적인 구현보다 인터페이스나 추상 클래스에 의존하는 주입방식입니다.

class EmailService {
public void sendEmail(String message) {
        System.out.println("Sending email: " + message);
    }
}

class Notification {
    private EmailService service;

    public Notification(EmailService service) {
        this.service = service;
    }

    public void notify(String message) {
        service.sendEmail(message);
    }
}

// 사용 예
public class Main {
    public static void main(String[] args) {
        EmailService emailService = new EmailService();
        Notification notification = new Notification(emailService);
        notification.notify("Hello, World!");
    }
}

 

this.service=service는 필요한 EmailService를 주입받아사용하고 있습니다.

service.sendEmail(message)또한 Notification에서 EmailService클래스의 service의 데이터를 sendEmail(message)로 주입받아 Notification에서 사용할수 있습니다.

class Notification {
    private EmailService service;

    public Notification(EmailService service) {
        this.service = service;
    }

    public void notify(String message) {
        service.sendEmail(message);
    }
}

참고사항

-Monica ai

-ReadableCode : 박우빈 코치님

-내 블로그 https://www.notion.so/protected-VS-abstract-VS-interface-19ad3d93797281aebe49eba361c78e0f

댓글을 작성해보세요.

채널톡 아이콘