진소희
1. 📌 핵심 개념 정리
✅ 요약하기
- 의도를 분명히 밝혀라
좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.-
따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 것이다.
-
예시1
- 변경 전
int d; // 경과 시간 (단위: 날짜)
이름 d는 아무 의미도 드러나지 않는다.
- 변경 후
int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays;
-
예시2
- 변경 전
public List<int []> getThem() { List<int []> list1 = new ArrayList<int []>(); for(int[] x : theList) if(x[0] == 4) list1.add(x); return list1; }
list에 무엇이 들었는가, 0번째 값이 왜 중요한가, 값 4는 무슨 의미인가, 함수가 반환값을 어떻게 사용하는지에 대한 정보가 드러나지 않는다.
- 변경 후
public List<int [] > getFlaggedCells () { List<int [] > flaggedCells = new ArrayList<int []>(); for (int[] cell : gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells. add (cell); return flaggedCells; }
결과적으로는 게임판이었고, 게임판에서 각 칸은 단순 배열이다. 배열 0번째 값은 칸 상태르 뜻한다. 값 4는 깃발이 꽂힌 상태를 가리킨다.
public List<Cell> getFlaggedCells () { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell: gameBoard) if (cell. isFlagged ()) flaggedCells.add (cell) ; return flaggedCells; }
칸을 간단한 클래스로 만들어주고, isFlagged()함수를 사용해 상수를 감춰서 더 개선해보았다.
-
- 그릇된 정보를 피하라
- 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용하면 안 된다.
- 서로 흡사한 이름을 사용하지 않도록 주의한다.
- 유사한 개념은 유사한 표기법을 사용한다.
- 의미 있게 구분하라
- 연속된 숫자(a1, a2, ...)를 덧붙이거나 불용어를 추가하는 방식(ProductInfo, ProductData, ...)은 적절하지 못하다. 이름이 달라야 한다면 의미도 달라져야 한다.
- a나 the와 같은 접두어를 사용하지 말라는 뜻은 아니다. 의미가 분명히 다르다면 사용해도 무방하다.
- 읽는 사람이 차이를 알도록 이름을 지어야 한다.
- 연속된 숫자(a1, a2, ...)를 덧붙이거나 불용어를 추가하는 방식(ProductInfo, ProductData, ...)은 적절하지 못하다. 이름이 달라야 한다면 의미도 달라져야 한다.
- 발음하기 쉬운 이름을 사용하라
- 발음하기 어려운 이름은 토론하기도 어렵다. 지적인 대화가 가능하도록 해야 한다.
- 검색하기 쉬운 이름을 사용하라
- 이름 길이는 범위 크기에 비례해야 한다.
- 변수나 상수를 코드 여러 곳에서 사용한다면 검색하기 쉬운 이름이 바람직하다.
- 인코딩을 피하라
- 헝가리식 표기법
- 변수명 앞이나 뒤에 데이터 타입(type)이나 역할을 접두사(prefix)로 붙이는 명명법
- 멤버 변수 접두어
- 클래스의 멤버 변수(필드)임을 명확히 표시하는 방식
- 사람들은 접두어를 무시하고 이름을 해독하는 방식을 익힌다. 코드를 읽을수록 접두어는 관심 밖으로 밀려난다.
- 결국, 헝가리식 표기법(nCount, bIsReady)이나 멤버 변수 접두어(m_name, _name 등)를 남용하는 것을 피하라는 뜻이다.
- 인터페이스 클래스와 구현 클래스
- 때로는 인코딩이 필요한 경우도 있다.
- 인터페이스 클래스 이름과 구현 클래스 이름을 어떻게 짜야 할까?
- 구현 클래스 이름을 인코딩하자!
- 헝가리식 표기법
- 자신의 기억력을 자랑하지 마라
- 문자 하나만 사용하는 변수 이름은 문제가 있다. 루프에서 반복 횟수를 세는 변수 i, j, k는 괜찮다.(루프 범위가 작을 때만)
- 전문가 프로그래머는 명료함이 최고라는 사실을 이해한다.
- 자신의 능력을 좋은 방향으로 사용해 남들이 이해하는 코드를 내놓는다.
- 클래스 이름
- 클래스 이름과 객체 이름은 명사나 명사구가 적합하다. 동사는 사용하지 않는다.
- 메서드 이름
- 메서드 이름은 동사나 동사구가 적합하다.
- 접근자, 변경자, 조건자는 javabean 표준에 따라 값 앞에 get, set, is를 붙인다.
- 생성자를 중복정의할 때는 정적 팩토리 메서드를 사용한다. 메서드는 인수를 설명하는 이름을 사용한다.
- 예시:
Complex fulcrumPoint = Complex.FromRealNumber(23.0)
- 기발한 이름은 피하라
- 재밌는 이름보다 명료한 이름을 선택하라.
- 특정 문화에서만 사용하는 농담은 피하는 편이 좋다.
- 의도를 분명하고 솔직하게 표현해라.
- 한 개념에 한 단어를 사용하라
- 추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다.(똑같은 메서드를 클래스마다 fetch, retrieve, get으로 제각각 부르면 혼란스럽다.)
- 메서드 이름은 독자적이고 일관적이어야 한다. 그래야 주석을 뒤져보지 않고도 프로그래머가 올바른 메서드를 선택한다.
- 일관성있는 어휘를 사용하자
- 말장난을 하지 마라
- 한 단어를 두 가지 목적으로 사용하지 마라.
- 예시
- 지금까지 구현한 add() 메서드는 모두가 기존값 두개를 더하거나 이어서 새로운 값을 만든다.
- 새로 작성하는 메서드는 집합에 값 하나를 추가한다. 이 메서드를 add라 불러도 괜찮을까?
- 새 메서드는 맥락이 다르기 때문에 insert나 append라는 이름이 적당하다.
- 해법 영역에서 가져온 이름을 사용하라
- 코드를 읽을 사람도 프로그래머라는 사실을 명심하라. 그러므로 전산 용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮다.
- 프로그래머에게 익숙한 기술개념은 아주 많다. 기술 개념에는 기술 이름이 가장 적합한 선택이다.
- 문제 영역에서 가져온 이름을 사용하라
- 적절한 프로그래머 용어가 없다면 문제 영역에서 이름을 가져온다.
- 우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다.
- 의미 있는 맥락을 추가하라
- 스스로 의미가 분명한 이름이 있다. 그래서 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다. 모든 방법이 실패하면 마지막 수단으로 접두어를 붙인다.
- 예시
- 변경 전:
firstName, lastName, street, houseNumber, city, state, zipcode
- 변경 후:
addrFirstName, addrLastName, addrStreet, addrHouseNumber, addrCity, addrState, addrZipcode
- 변수가 좀 더 큰 구조에 속한다는 사실이 분명해진다.
- 변경 전:
- 불필요한 맥락을 없애라
- 일반적으로 짧은 이름이 긴 이름보다 좋다. 단, 의미가 분명한 경우에 한해서이다. 이름에 불필요한 맥락을 추가하지 않도록 주의한다.
2. 🤔 이해가 어려운 부분
🔍 질문하기
- 생성자를 중복정의할 때는 정적 팩토리 메서드를 사용
- 이해한 부분
- 생성자만으로 여러 버전을 만들면 가독성이 떨어지고, 객체 생성의 의도가 명확하지 않기 때문이다.
- 이해 코드
- 변경 전
이렇게 하면 사용자가 어떤 생성자를 써야 할지 헷갈릴 수 있다.public class User { private String name; private int age; private boolean isAdmin; // 생성자 오버로딩 public User(String name) { this(name, 0, false); } public User(String name, int age) { this(name, age, false); } public User(String name, int age, boolean isAdmin) { this.name = name; this.age = age; this.isAdmin = isAdmin; } }
- 변경 후
public class User { private String name; private int age; private boolean isAdmin; private User(String name, int age, boolean isAdmin) { this.name = name; this.age = age; this.isAdmin = isAdmin; } // ✅ 정적 팩토리 메서드 사용 public static User of(String name) { return new User(name, 0, false); } public static User of(String name, int age) { return new User(name, age, false); } public static User createAdmin(String name, int age) { return new User(name, age, true); } }
의도를 명확하게 표현하는 정적 팩토리 메서드를 사용하면 가독성이 좋아진다.User u1 = User.of("소희"); // 일반 유저 User u2 = User.of("소희", 25); // 나이 포함 유저 User u3 = User.createAdmin("소희", 25); // 관리자 계정
- 변경 전
- 이해한 부분
- 인터페이스 클래스 이름과 구현 클래스 이름
- 이해한 부분
- 인터페이스와 구현 클래스의 이름을 직관적이고 명확하게 짓는 것이 중요.
- 인터페이스 이름은 역할(행동)을 나타내도록 한다.
- 구현 클래스는 역할을 수행하는 구체적인 객체임을 나타내야 한다.
- 인터페이스 이름에 I(예: IUserService) 같은 접두사를 붙이지 않는다.
- 이해 코드
구현체는 DefaultUserService 혹은 UserServiceImpl로 네이밍 가능// 인터페이스: 역할을 표현 public interface UserService { void registerUser(String name); } // 구현 클래스: 구체적인 구현체를 표현 public class DefaultUserService implements UserService { public void registerUser(String name) { System.out.println("Registering user: " + name); } }
- 이해한 부분
모르는 단어
- grep으로 찾기 쉽다
- 코드를 작성할 때 간단한 검색 명령어(grep)로 빠르게 원하는 내용을 찾을 수 있도록 코드를 명확하게 작성하라는 뜻
- 정적 메서드 팩토리(Static Factory Method)
- 정적 메서드 팩토리는 생성자의 직접 호출을 피하고, 대신 정적 메서드를 통해 객체를 생성하는 방식
- 예시:
public class Person { private String name; // private 생성자 private Person(String name) { this.name = name; } // 정적 팩토리 메서드 public static Person of(String name) { return new Person(name); } }
// 사용 예시 Person person = Person.of("소희"); // 생성자 대신 사용
3. 📚 참고 사항
📢 논의하기
- 논의하고 싶은 주제
- 이름 길이는 범위 크기에 비례
- 변수, 함수, 클래스 등의 이름 길이를 결정할 때, 해당 이름의 "범위(Scope)" 크기에 따라 적절한 길이를 가져야 한다
- 설명
- 범위는 어떤 기준으로 정하는가?
- 변수/함수의 "유효 범위(Scope)"가 작으면 짧은 이름을 사용해도 됨.
- 짧은 코드 블록(로컬 변수, for-loop 변수)에서만 사용되는 변수는 간결한 이름이 더 좋음
- 변수/함수의 "유효 범위(Scope)"가 크면 더 길고 의미 있는 이름을 사용해야 함
- 전역 변수, 클래스 필드, 공용 API 메서드는 더 명확한 이름이 필요함
- 변수/함수의 "유효 범위(Scope)"가 작으면 짧은 이름을 사용해도 됨.
- 길이는 어느정도의 기준인가?
- 범위는 어떤 기준으로 정하는가?
- 이름 길이는 범위 크기에 비례
No Comments