cha_eyoon 2024. 7. 16. 06:14

✅ SOLID

분리를 잘한다 ⇒ 객체 지향적

 

예시 코드를 만들어보자.

  • SRP (Single Responsibility Principle) 단일책임 원칙
    • 한 클래스는 하나의 책임만 가져야 한다.
    • 이 클래스를 수정해야 하는 이유는 하나의 직군(역할) 때문이어야 한다.
    • 수정을 가하는 대상이 하나의 역할을 해야한다.
    • A ⇒ B ⇒ C 연쇄적으로 수정하는 일이 없도록..
    • 액터: 클래스에 수정을 가하는 역할자
class XSrp {
    class Employee {
        String name;
        String positon;

        Employee(String name, String position) {
            this.name = name;
            this.positon = position;
        }

        // * 초과 근무 시간을 계산하는 메서드 (두 팀에서 공유하여 사용)
        void calculateExtraHour() {
            // ...
        }

        // * 급여를 계산하는 메서드 (회계팀에서 사용)
        void calculatePay() {
            // ...
            this.calculateExtraHour();
            // ...
        }

        // * 근무시간을 계산하는 메서드 (인사팀에서 사용)
        void reportHours() {
            // ...
            this.calculateExtraHour();
            // ...
        }
}

class CorrectSrp {
    class Employee {
        private String name;
        private int salary;
        private int workHours;

        Employee(String name, int salary, int workHours) {
            this.name = name;
            this.salary = salary;
            this.workHours = workHours;
        }

        void calculateExtraHour() {
            new Calculator().calculateExtraHour();
        }
       
       void reportHours() {
			      new Reportor.~()
       }


    }

    class Calculator {
        private int workHours;
        private int standardHour;
        private int salary;

        Calculator(int workHours, int standardHour, int salary) {
            this.workHours = workHours;
            this.standardHour = standardHour;
            this.salary = salary;
        }


        private int calculateExtraHour() {
            int extraHours = workHours - standardHour;
            return extraHours > 0 ? extraHours : 0;
        }

        void calculatePay() {
            int extraPay = this.calculateExtraHour() * 20000; 
            int totalPay = this.salary + extraPay;
            System.out.println("Total Pay: " + totalPay);
        }
    }
    
    Class Reporter(){
	    // 따로 분리
	    
    }
  • OCP (Open/Closed Principle) 개방-폐쇄 원칙
    • 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다.
    • 코드의 추가로 기존의 코드가 영향을 받으면 안 된다.
  • LSP (Liskov Substitution Principle) 리스코프 치환 원칙
    • 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으며 하위타입의 인스턴스로 바꿀 수 있어야 한다.
    • 부모 클래스의 객체를 자식 클래스의 객체로 치환하더라도 프로그램의 정상적인 동작 유지
    • 자식 클래스는 부모 클래스의 모든 기능을 대체할 수 있어야 하며, 부모 클래스의 메서드와 동작을 일관되게 유지 ⇒ 올바른 상속을 위해, 자식 객체의 확장이 부모 객체의 방향을 따른다.
    • 인터페이스(공통규약) 만들고 그 이상의 것을 만든다? 말이 안됨
IPerson = sleep, work

Student implements IPerson = sleep, work("공부를한다');

Adult implements IPerson = sleep, work("돈을 번");

IPerson stu= new Student();

IPerson adu = new Student();

stu.work();

adu.work();
  • ISP (Interface Segregation Principle) 인터페이스 분리 원칙
    • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
interface Playable {
    void play();
}

interface StringInstrument extends Playable {
    void tuneStrings();
}

interface WindInstrument extends Playable {
    void adjustBreath();
}


class Guitar implements StringInstrument {
	  @Override
    public void play() {
        System.out.println("나 기타쳐~~~");
    }

    @Override
    public void tuneStrings() {
        System.out.println("기타 튜닝중이야~~~~");
    }
     @Override
    public void adjustBreath() {
        System.out.println("기타연주는 호흡조절이 필요 없는데, 어쩔 수 없이 구현한다.......");
    }
}

// 플루트 클래스
class Flute implements WindInstrument {
    @Override
    public void play() {
        System.out.println("나 플룻부는 중~~~~");
    }

    @Override
    public void adjustBreath() {
        System.out.println("관악기는 호흡조절이 생명이다~~~~");
    }
    
    @Override
    public void tuneStrings() {
        System.out.println("플룻은 줄이 없는데, 어쩔 수 없이 구현한다...");
    }
}
  • DIP (Dependency Inversion Principle) 의존관계 역전 원칙
    • 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다” - 의존성 주입은 이 원칙을 따르는 방법 중 하나다.
    • Phone이 추상화한 것 , 그리고 그걸 구체화 한게 Galaxy, Iphone
interface Phone {}

class Galaxy implements Phone {}
class IPhone implements Phone {}

class User {
	Phone phone; // 합성
    
    void setPhone(Phone phone) {
    	this.phone = phone;
    }
    
    void turnOnGalaxy() {}
    void turnOnIPhone() {}
}

public class Main {
	public static void main(String[] args) {
        User user = User();
        
        // 1. 갤럭시 폰을 켰을 때
        Phone phone = new Galaxy();
        user.setPhone(phone);
        user.turnOnGalaxy();
        
        // 2. 아이폰을 켰을 때
        Phone phone = new IPhone();
        user.setPhone(phone);
        user.turnOnIPhone();
    }
}

 

 

 

팀원들마다 개념을 이해한 방향이 달라서 각자 제시한 정의와 예시코드가 다 달랐다.

내가 생각했을 때 SOLID 원칙을 모두 준수하면서 코드를 작성하는 것은 어렵지만 개발자로 원칙을 지향하며 코드를 작성하도록 노력해야하는 것은 분명하다!!!