클래스 추출하기(Extract Class) 리팩터링 기법은 하나의 클래스가 두 가지 이상의 역할을 수행할 때, 이 중 일부를 새로운 클래스로 분리해내는 방법입니다.
하나의 클래스가 여러 역할을 수행하게 되면 코드의 가독성, 유지보수성이 떨어지며, 하나의 역할에 영향을 주는 변경이 다른 역할에도 영향을 미칠 수 있습니다.
이러한 문제를 해결하기 위해 두 가지 이상의 역할을 수행하는 클래스를 분리하여 각각의 역할에 맞는 새로운 클래스를 만들어주는 것이 클래스 추출하기입니다.
이 리팩터링 기법을 적용할 때는 먼저, 원래 클래스에서 새로운 클래스를 분리해낼 역할을 결정합니다.
그 다음, 새로운 클래스의 필드와 메서드를 정의하고, 이를 호출하는 코드를 새로운 클래스로 이동시켜줍니다.
예를 들어, Customer 클래스가 "사람 정보"와 "주소 정보"를 모두 포함하고 있는 경우, "사람 정보"와 "주소 정보"를 각각 "Person" 클래스와 "Address" 클래스로 분리할 수 있습니다.
이렇게 하면, 각각의 클래스는 자신이 담당하는 역할에만 집중하면 되므로 코드의 가독성과 유지보수성이 향상됩니다.
클래스 추출하기는 객체 지향 원칙 중 SRP(Single Responsibility Principle, 단일 책임 원칙)를 따르기 위해 매우 중요한 리팩터링 기법 중 하나입니다.
아래는 클래스 추출하기 리팩터링 기법을 적용한 예제 코드입니다.
#include <iostream>
#include <string>
#include <vector>
class Person {
public:
Person(const std::string& name, const std::string& phone) : name_(name), phone_(phone) {}
std::string getName() const { return name_; }
std::string getPhone() const { return phone_; }
private:
std::string name_;
std::string phone_;
};
class Address {
public:
Address(const std::string& street, const std::string& city, const std::string& state, const std::string& zip)
: street_(street), city_(city), state_(state), zip_(zip) {}
std::string getStreet() const { return street_; }
std::string getCity() const { return city_; }
std::string getState() const { return state_; }
std::string getZip() const { return zip_; }
private:
std::string street_;
std::string city_;
std::string state_;
std::string zip_;
};
class Customer {
public:
Customer(const std::string& name, const std::string& phone, const std::string& street, const std::string& city,
const std::string& state, const std::string& zip)
: person_(name, phone), address_(street, city, state, zip) {}
std::string getName() const { return person_.getName(); }
std::string getPhone() const { return person_.getPhone(); }
std::string getStreet() const { return address_.getStreet(); }
std::string getCity() const { return address_.getCity(); }
std::string getState() const { return address_.getState(); }
std::string getZip() const { return address_.getZip(); }
private:
Person person_;
Address address_;
};
int main() {
Customer customer("John Doe", "123-456-7890", "123 Main St", "Anytown", "CA", "12345");
std::cout << "Customer name: " << customer.getName() << std::endl;
std::cout << "Customer phone: " << customer.getPhone() << std::endl;
std::cout << "Customer address: " << customer.getStreet() << ", " << customer.getCity() << ", " << customer.getState() << " " << customer.getZip() << std::endl;
return 0;
}
위 코드에서는 Person과 Address 클래스를 추출하여 Customer 클래스에서 사용하도록 수정했습니다.
이렇게 하면 Customer 클래스가 단일 책임 원칙(Single Responsibility Principle)을 준수하게 되며, 코드의 유지보수성과 확장성이 향상됩니다.
'리팩터링 > 리팩터링 기법' 카테고리의 다른 글
리팩터링 기법. 함수 인라인(Inline Function) (0) | 2023.03.23 |
---|---|
리팩터링 기법. 필드 옮기기(Move Field) (0) | 2023.03.22 |
리팩터링 기법. 함수 옮기기(Move Function) (0) | 2023.03.19 |
리팩터링 기법. 단계 쪼개기(Split Phase) (0) | 2023.03.18 |
리팩터링 기법. 참조를 값으로 바꾸기(Change Reference to Value) (0) | 2023.03.16 |