쉽게 배우는 튼튼한 프로그래밍 방법론

객체에서 세터 제거: 클린 코드의 핵심 원칙

일상로그92 2024. 9. 27. 12:17

 객체 지향 프로그래밍에서 세터 제거의 중요성을 이해하고, 이를 통해 코드 품질을 어떻게 개선할 수 있는지 알아보세요. 클린 코드의 핵심 원칙인 불변성 유지와 캡슐화를 통해 더 나은 소프트웨어 설계를 할 수 있습니다.


클린 코드와 세터: 불변성 유지의 중요성

세터란 무엇인가?

세터(setter)는 객체의 속성 값을 설정하는 메서드입니다. 예를 들어, Person 클래스에 setName 메서드가 있다면, 이는 Person 객체의 이름을 변경할 수 있는 기능을 제공합니다. 하지만 클린 코드 원칙에서는 세터를 사용하는 것이 항상 바람직하지 않을 수 있습니다.

세터의 문제점

세터를 사용하면 객체의 내부 상태를 외부에서 수정할 수 있습니다. 이로 인해 객체의 일관성이 깨질 수 있고, 객체의 상태가 예측할 수 없는 방식으로 변경될 위험이 있습니다. 예를 들어, 객체의 상태를 변경할 때 추가적인 유효성 검사나 로직이 필요할 수 있는데, 세터를 사용하는 경우 이런 로직이 누락될 가능성이 있습니다.

불변성(Immutable)의 개념

불변성은 객체가 생성된 이후에는 그 상태가 변경되지 않도록 하는 개념입니다. 불변 객체를 사용하면 객체의 상태를 보호할 수 있으며, 이를 통해 버그를 줄이고 코드를 더 쉽게 이해할 수 있습니다. 불변성을 유지하는 가장 효과적인 방법 중 하나는 세터를 제거하는 것입니다.

세터 제거의 장점

세터를 제거하고 불변 객체를 사용하면 여러 가지 장점이 있습니다. 첫째, 객체의 상태를 더 이상 변경할 수 없으므로, 예측 가능한 코드가 됩니다. 둘째, 불변 객체는 스레드 안전성을 보장합니다. 셋째, 객체의 상태 변경이 불가능하기 때문에, 객체를 더 쉽게 디버깅하고 테스트할 수 있습니다.


객체에서 세터 제거하기: 실전 접근법

1. 필드 초기화

세터를 제거하려면 먼저 클래스의 필드를 초기화해야 합니다. 보통 생성자를 사용하여 객체 생성 시 필드를 초기화합니다. 예를 들어, Person 클래스에서 이름을 초기화하려면 다음과 같이 작성할 수 있습니다.

public class Person {
    private final String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

이 예제에서 name 필드는 final로 선언되어 있으며, 생성자에서 한 번만 초기화됩니다. 이렇게 하면 객체의 상태가 변경되지 않도록 보장할 수 있습니다.

2. 불변 객체 사용

불변 객체를 만들기 위해서는 모든 필드를 final로 선언하고, 필드를 초기화하는 생성자를 제공하는 것이 좋습니다. 또한, 필드를 직접 수정할 수 있는 세터를 제공하지 않아야 합니다. 아래는 불변 객체의 예입니다.

public class Address {
    private final String street;
    private final String city;

    public Address(String street, String city) {
        this.street = street;
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public String getCity() {
        return city;
    }
}

3. 캡슐화 유지

세터를 제거하면서도 캡슐화를 유지하는 것이 중요합니다. 객체의 상태를 외부에서 직접 수정할 수 없게 함으로써, 객체가 스스로의 상태를 책임지도록 할 수 있습니다. 캡슐화를 통해 객체의 무결성을 유지하고, 객체 내부의 로직을 보호할 수 있습니다.

4. 변경 불가능한 컬렉션

불변 컬렉션을 사용하는 것도 세터를 제거하는 좋은 방법입니다. 예를 들어, List를 불변으로 만들려면 Collections.unmodifiableList를 사용할 수 있습니다. 이렇게 하면 컬렉션의 상태를 변경할 수 없게 되며, 코드의 안정성을 높일 수 있습니다.

import java.util.Collections;
import java.util.List;

public class Library {
    private final List<String> books;

    public Library(List<String> books) {
        this.books = Collections.unmodifiableList(books);
    }

    public List<String> getBooks() {
        return books;
    }
}

세터 제거의 한계와 주의사항

세터 제거의 한계

세터를 제거하는 것이 모든 상황에서 최선의 해결책은 아닙니다. 예를 들어, 객체의 상태를 자주 변경해야 하는 경우에는 세터가 필요할 수 있습니다. 이런 경우에는 세터 사용을 최소화하고, 적절한 유효성 검사와 상태 관리 로직을 추가하는 것이 중요합니다.

성능 고려

불변 객체는 성능 측면에서 이점이 있을 수 있지만, 때로는 성능 저하를 초래할 수도 있습니다. 예를 들어, 불변 객체를 사용하면 객체를 복제하거나 새로 생성하는 비용이 발생할 수 있습니다. 이러한 성능 문제를 해결하기 위해서는 불변 객체와 가변 객체를 적절히 혼합하여 사용하는 것이 필요할 수 있습니다.

디버깅과 테스트

세터를 제거하면 코드가 더 안전해질 수 있지만, 디버깅과 테스트가 더 어려워질 수 있습니다. 객체의 상태를 변경하는 테스트가 필요한 경우, 테스트 설계에 신경을 써야 합니다. 또한, 생성자와 초기화 로직을 잘 작성하여 객체 생성 시점에서 모든 상태가 올바르게 설정되도록 해야 합니다.


결론

세터를 제거하고 불변 객체를 사용하는 것은 클린 코드의 중요한 원칙 중 하나입니다. 이를 통해 코드의 안정성과 예측 가능성을 높일 수 있으며, 객체의 상태를 보호할 수 있습니다. 그러나 세터 제거가 항상 최선의 선택은 아니며, 성능과 테스트 측면에서도 신중한 접근이 필요합니다. 클린 코드를 지향하며, 상황에 맞는 적절한 설계 방식을 선택하는 것이 중요합니다.


FAQ

Q1: 세터를 제거하면 코드가 항상 더 안정해지나요?
A1: 세터를 제거하면 코드의 안정성을 높일 수 있지만, 모든 상황에서 최선의 해결책은 아닙니다. 세터를 제거하고 불변 객체를 사용할 때, 성능 저하나 테스트 어려움 등의 문제가 발생할 수 있으므로 상황에 맞는 적절한 설계가 필요합니다.

Q2: 불변 객체는 어떻게 구현하나요?
A2: 불변 객체를 구현하려면 필드를 final로 선언하고, 객체 생성 시 모든 필드를 초기화해야 합니다. 또한, 객체의 상태를 변경할 수 있는 메서드나 세터를 제공하지 않아야 합니다.

Q3: 세터를 제거하면 성능에 어떤 영향을 미치나요?
A3: 세터를 제거하고 불변 객체를 사용할 때, 객체를 복제하거나 새로 생성하는 비용이 발생할 수 있습니다. 성능 문제를 해결하기 위해서는 불변 객체와 가변 객체를 적절히 혼합하여 사용하는 것이 필요할 수 있습니다.


해시태그

#클린코드 #프로그래밍 #세터제거 #불변성 #객체지향 #소프트웨어설계 #코드품질 #캡슐화 #객체지향프로그래밍 #코딩 #프로그래밍팁 #개발자 #소프트웨어개발 #테스트 #디버깅 #Java #CSharp #Python #불변객체 #코드안정성 #객체상태 #설계패턴 #프로그래밍기술 #소프트웨어품질 #코드리팩토링 #설계원칙

 

[쉽게 배우는 튼튼한 프로그래밍 방법론] - 객체의 본질 파악: 클린 코드의 핵심

 

[쉽게 배우는 튼튼한 프로그래밍 방법론] - 소프트웨어 설계 원칙: 클린코드를 위한 기초

 

[쉽게 배우는 튼튼한 프로그래밍 방법론] - 빈약한 객체를 풍성한 객체로 변환하기: 클린코드 방법론의 핵심