객체지향 개발에서 중요한 5대 원칙이 있다. 이것은 바로 SOLID 원칙이다.
SOLID 원칙은 객체지향 개발 과정에서 사용되는 다양한 패턴들을 체계적으로 정리한 것으로,
이 원칙들은 프로그래밍의 효율성과 소프트웨어의 확장성을 향상시키는 데 기여한다.
오늘은 이 중 S 에 해당하는 단일 책임 원칙 에 대해 다루어 보려고 한다.
단일 책임 원칙(Single Responsibility Principle, 이하 SRP) 은 SOLID 원칙 중 첫 번째로, 하나의 클래스는 하나의 책임만 가져야 한다고 규정한다. 여기서 책임은 클래스가 수행해야 할 기능을 의미한다. 따라서 객체지향 개발에서 SRP 원칙을 따르면, 각 클래스는 오직 자신만의 독립적인 역할을 수행하고, 다른 클래스의 영향을 최소화하도록 설계한다. 이렇게 하면 변경이 필요하더라도 해당 클래스만 수정하여 문제를 해결할 수 있으며, 이는 문제의 원인을 빠르게 찾아 해결할 수 있게 함으로써 소프트웨어의 전반적인 효율성을 높일 수 있다.
이 원칙을 실생활의 비유로 설명해보면, 한 요리사가 식당에서 요리뿐만 아니라 서빙, 청소, 계산까지 담당하는 상황을 생각해볼 수 있다. 요리사가 모든 업무를 담당하게 되면, 요리의 품질이 떨어질 가능성이 높고 식당의 전반적인 운영 효율도 떨어지게 된다. 요리사가 요리에만 집중하고 서빙이나 청소는 다른 직원이 담당한다면, 각자의 업무에 더 집중할 수 있고 전체적인 식당 운영의 효율성도 향상된다.
public class Employee {
private String name;
private String age;
public Employee(String name, String id) {
this.name = name;
this.id = age;
}
// 직원 급여 계산
public void calculatePay() {
...
}
// DB에 직원 정보 저장
public void saveToDatabase() {
...
}
// Getter
public String getName() {
return name;
}
public String getAge() {
return age;
}
// Setter
public void setName(String name) {
this.name = name;
}
public void setAge(String age) {
this.age = age;
}
}
위 예제에서는 Employee 클래스가 직원의 정보를 관리하는 동시에 급여 계산과 DB 저장 같은 여러 책임을 갖고 있다. 이는 SRP 에 어긋나며, 클래스의 유지보수와 확장성에 문제가 생길 수 있다. 급여 계산 방식이 변경되거나 DB 저장 방식이 변경될 경우, Employee 클래스를 직접 수정해야 하므로 코드의 수정이 빈번하게 발생할 수 있다.
// 직원 정보를 저장하는 기본 클래스
public class Employee {
private String name;
private String age;
public Employee(String name, String age) {
this.name = name;
this.age = age;
}
// Getter
public String getName() {
return name;
}
public String getAge() {
return age;
}
// Setter
public void setName(String name) {
this.name = name;
}
public void setAge(String age) {
this.age = age;
}
}
// 급여 계산을 담당하는 클래스
public class EmployeePayManager {
// 직원 급여 계산 메서드
public void calculatePay(Employee employee) {
...
}
}
// DB 관리를 담당하는 클래스
public class EmployeeDatabaseManager {
// DB에 직원 정보 저장
public void saveToDatabase(Employee employee) {
...
}
}
위 예제에서는 SRP 에 따라 리팩토링 하여 Employee 클래스는 오직 직원의 기본 정보만을 관리하고, 급여 계산과 데이터베이스 저장은 각각 EmployeePayManager 와 EmployeeDatabaseManager 클래스가 맡는다. 이 분리를 통해 각 클래스는 자신의 책임에만 집중할 수 있어 코드의 유지보수성과 확장성이 향상된다. 변경 사항이 있을 때 해당 클래스만을 수정하면 되므로 다른 부분에 미치는 영향을 최소화할 수 있고, 또 각 기능을 독립적으로 테스트할 수 있어 전체 시스템의 안정성도 높아진다.
Java 개발을 진행하면서 클래스 설계는 항상 많은 고민을 요구하는 과정이었다.
객체지향 개발 원칙을 충분히 이해하고 이를 실제 코드에 적용해보려는 시도는
개발자로서의 능력을 향상시키는데 많은 도움을 주지 않을까라는 생각이 든다.