필드 이동은 한 클래스에서 다른 클래스로 필드를 이동하는 리팩토링 기술 중 하나입니다.
클래스의 필드는 해당 클래스가 속한 책임 영역에 속하는 데이터여야 하지만 다른 클래스에 속하는 데이터인 경우도 있습니다.
이 경우 필드를 다른 클래스로 이동해야 합니다.
이 기술은 두 클래스 간의 결합을 줄이고 데이터와 책임을 더 잘 정렬합니다.
필드를 이동할 때 먼저 다른 클래스가 필드를 사용하고 있는지 또는 새 클래스가 필요한지 여부를 결정해야 합니다.
새 클래스가 필요한 경우 먼저 해당 클래스를 만들고 이전 클래스의 필드를 새 클래스의 필드로 이동하고 이전 클래스의 해당 필드에 대한 getter 및 setter 메서드를 작성합니다.
그리고 새 클래스의 인스턴스를 사용하도록 이전 클래스의 메서드를 변경합니다.
다음으로 고객 클래스에는 이름, 이메일 및 주소라는 필드가 있습니다.
class Customer {
public:
Customer(std::string name, std::string email, Address address)
: _name(name), _email(email), _address(address) {}
std::string getName() const { return _name; }
void setName(std::string name) { _name = name; }
std::string getEmail() const { return _email; }
void setEmail(std::string email) { _email = email; }
Address getAddress() const { return _address; }
void setAddress(Address address) { _address = address; }
private:
std::string _name;
std::string _email;
Address _address;
};
이메일 필드는 다른 수업에서도 사용할 수 있습니다.
필드 번역을 적용하여 이메일 필드를 별도의 이메일 클래스로 추출합니다.
class Email {
public:
Email(std::string address) : _address(address) {}
std::string getAddress() const { return _address; }
void setAddress(std::string address) { _address = address; }
private:
std::string _address;
};
class Customer {
public:
Customer(std::string name, Email email, Address address)
: _name(name), _email(email), _address(address) {}
std::string getName() const { return _name; }
void setName(std::string name) { _name = name; }
Email getEmail() const { return _email; }
void setEmail(Email email) { _email = email; }
Address getAddress() const { return _address; }
void setAddress(Address address) { _address = address; }
private:
std::string _name;
Email _email;
Address _address;
};
이제 이메일 클래스를 만들고 고객 클래스의 이메일 필드를 이메일 유형으로 변경했습니다.
이제 Email 클래스에 정의된 이름 및 주소 필드와 getEmail() 및 setEmail() 메서드만 Customer 클래스에서 사용됩니다.
필드 이전을 사용하기 전에 메일 정보가 변경되면 고객 클래스를 포함하여 메일을 사용하는 모든 클래스를 수정해야 Shotgun Surgery가 발생합니다.
이동 필드를 사용한 후에는 단순히 이메일 클래스를 변경하여 수정할 수 있습니다.