package com.haenin.section01.singleresponsibility.resolved;
/* 설명.
*   단일 책임의 원칙을 바르게 적용한다면 각각의 책임을 별도의 클래스로 분리하고
*   각 클래스는 자신의 데이터와 연산을 최대한 캡슐화 해서 관리한다.*/
public class Application {
    public static void main(String[] args) {
        /* 설명. 이름, 근무시간, 시급이 설정된 객체 생성 */
        Employee emp = new Employee("홍길동", 40, 25000);
        /* 설명. 급여 계산 */
        PayCalculator payCalculator = new PayCalculator();
        payCalculator.applyPayRate(emp);
        /* 설명. 데이터베이스에 저장 */
        EmployeeRepository employeeRepository = new EmployeeRepository();
        employeeRepository.save(emp);
        /* 설명. 근무시간 보고 */
        TimeReporter timeReporter = new TimeReporter();
        timeReporter.reportHours(emp);
    }
}

package com.haenin.section01.singleresponsibility.resolved;

public class Employee {
    private String name;
    private int workingHours;
    private int payRate;
    public Employee(){

    }

    public Employee(String name, int workingHours, int payRate) {
        this.name = name;
        this.workingHours = workingHours;
        this.payRate = payRate;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getWorkingHours() {
        return workingHours;
    }

    public void setWorkingHours(int workingHours) {
        this.workingHours = workingHours;
    }

    public int getPayRate() {
        return payRate;
    }

    public void setPayRate(int payRate) {
        this.payRate = payRate;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\\'' +
                ", workingHours=" + workingHours +
                ", payRate=" + payRate +
                '}';
    }
}

package com.haenin.section01.singleresponsibility.resolved;

public class EmployeeRepository {
    public void save(Employee emp){
        vaildateEmployeeDate(emp);
        System.out.println(emp.getName() + "의 정보를 데이터베이스에 저장합니다.");
    }
    /* 설명. 유효성 검사 내지는 메소드에서 호출하는 나만 쓰는 메소드는 외부에 노출하지 않는다. */
    private void vaildateEmployeeDate(Employee emp) {
        if(emp == null){
            throw new IllegalArgumentException("직원 정보가 null일 수 없습니다.");
            //필기. 매개변수가 잘못 넘어올 때 자주쓰는 예외
        }
        if(emp.getName() == null ||emp.getName().equals("")){
            throw new IllegalArgumentException("직원 이름은 필수입니다.");
        }
    }
}

package com.haenin.section01.singleresponsibility.resolved;

public class PayCalculator {
    public void applyPayRate(Employee emp){
        int pay = emp.getWorkingHours() * emp.getPayRate();
        // 필기. 일한 시간 * 시급
        System.out.println(emp.getName() + "의 급여를 계산합니다.");
    }
}

package com.haenin.section01.singleresponsibility.resolved;

public class TimeReporter {
    public void reportHours(Employee emp){
        validateWorkingHours(emp);
        System.out.println(emp.getName() + "의 근무시간을 보고합니다: " + emp.getWorkingHours());
    }

    private void validateWorkingHours(Employee emp) {
        if(emp.getWorkingHours() > 52){
            System.out.println("경고: 주 52시간을 초과하는 근무시간이 기록되었습니다.");
        }
    }
}