변수명 지어주는 사이트 : https://www.curioustore.com/#!/
항상 표준 명명 규칙을 따라야 한다.
- 클래스와 인터페이스 (Class & Interface):
- 대문자로 시작하며 각 단어의 첫 글자를 대문자로 표기한다 (PascalCase).
- 클래스 이름은 보통 명사 또는 명사구로 표현한다.
- 예:
Person,DataManager,HttpRequestHandler.
- 메서드 (Method):
- 소문자로 시작하며 각 단어의 첫 글자는 대문자로 표기한다 (camelCase).
- 메서드 이름은 동사 또는 동사구로 작성하여, 메서드가 수행하는 동작을 명확히 설명해야 한다.
- 예:
calculateTotal(),fetchUserData(),isUserLoggedIn().
- 변수 (Variable):
- 소문자로 시작하며 각 단어의 첫 글자는 대문자로 표기한다 (camelCase).
- 변수 이름은 가능한 구체적이고 명확하게, 변수의 목적을 설명하도록 작성한다.
- 예:
userName,accountBalance,maxRetryCount.
- 상수 (Constant):
- 모든 글자를 대문자로 표기하며 단어 간에 밑줄 (
_)을 사용한다 (SNAKE_CASE). - 예:
MAX_BUFFER_SIZE,DEFAULT_TIMEOUT.
- 모든 글자를 대문자로 표기하며 단어 간에 밑줄 (
- 패키지 (Package):
- 모두 소문자로 표기하며 회사 도메인을 뒤집은 형태로 시작한다.
- 예:
com.example.app,org.openai.utils.
- 동사 또는 동사구로 명확히 표현:
- 예:
save(),load(),calculateInterest(). - 이처럼 메서드 이름은 그 메서드가 무슨 작업을 하는지 명확하게 나타내야 함
- 예:
- 부울 값을 반환하는 메서드는
is로 시작:- 예:
isValid(),isEmpty(),isUserActive(). - 부울 값을 반환하는 메서드의 경우
is를 접두사로 붙이는 것이 일반적
- 예:
- 설명적인 이름으로 의미 명확히 하기:
- 예:
getCustomerData(),sendEmailNotification(). - 긴 이름을 피해야 하지만, 너무 짧고 애매한 이름도 피해야 합니다. 적절하게 설명적이면서 이해할 수 있는 이름을 사용하는 것이 중요
- 예:
- 자바 라이브러리의 명명 규칙과 일관성 유지:
- 예: 자바의 컬렉션 메서드들은
add(),remove(),clear(),contains()와 같은 이름을 사용한다. - 이처럼 널리 사용되는 메서드 이름을 참조함으로써 일관성을 유지하고 다른 개발자들이 쉽게 이해할 수 있게 된다.
- 예: 자바의 컬렉션 메서드들은
-
좋은 예시:
public void sendEmailNotification(String email) { // 이메일 알림을 보낸다. } public boolean isAccountActive() { // 계정이 활성화되어 있는지 여부를 반환한다. } public double calculateTotalPrice(List<Item> items) { // 아이템의 총 가격을 계산한다. }
-
나쁜 예시:
public void sE(String e) { // 너무 짧고 모호하다. 메서드가 무슨 일을 하는지 전혀 알 수 없다. } public void performAction() { // 메서드가 어떤 동작을 수행하는지 알 수 없다. 메서드 이름이 너무 일반적이다. } public boolean accountStatus() { // 부울 값을 반환하지만, `is` 접두사가 없어 의미가 명확하지 않다. }
- 명확하고 일관성 있게 메서드 이름을 짓는 것이 중요하다. 이해할 수 있고, 같은 패키지에 속한 다른 이름들과 일관되게 짓는 게 최우선 목표다.
- 메서드 이름은 무엇을 하는지 쉽게 이해할 수 있도록 지어야 하며, 동사 형태로 시작하여 동작을 설명해야 합니다.
- 긴 이름은 피하자.
- 자바 표준 명명 규칙을 따르고, 필요시 자바 API 가이드를 참조하여 개발자 커뮤니티에서 널리 받아들여지는 방식으로 이름을 짓는 것이 좋다.
편의 메서드를 너무 많이 만들지 말자.
- 각 메서드는 자신의 역할에만 충실해야 한다: 많은 기능을 하나의 메서드에 넣으면 복잡해지고 이해하기 어려워지므로, 명확한 단일 책임 원칙을 지켜야 한다.
- 메서드가 너무 많은 클래스와 인터페이스는 피해야 한다: 유지보수와 사용이 어렵기 때문에 필요한 최소한의 기능을 메서드로 정의해야 한다.
// 나쁜 예시 - 여러 기능을 하나의 메서드에 몰아넣음
public void manageOrderAndSendReceipt(Order order) {
// 주문 관리
processOrder(order);
// 영수증 발송
sendReceipt(order);
}
// 좋은 예시 - 메서드가 각각의 소임을 다함
public void processOrder(Order order) {
// 주문 처리 로직
}
public void sendReceipt(Order order) {
// 영수증 발송 로직
}직교란 수학에서 온 용어로, 서로 직각(90。)을 이루며 교차 한다는 뜻이다. 수학의 관점에서 직교하는 요소들은 서로 독립적이다.
- 직교성(Orthogonality): 기능 간 독립성을 높여 메서드 수를 줄이는 효과를 기대할 수 있다. 기능을 잘게 나누어 필요한 기본 기능들만 제공하면, 그 기능들을 조합하여 더 복잡한 동작을 구현할 수 있다. 예시로
List의subList()와indexOf()메서드를 들 수 있다.
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
List<String> subList = list.subList(1, 4); // ["b", "c", "d"]
int index = subList.indexOf("c"); // 1“직교성이 높다”라고 하면 “공통점이 없는 기능들이 잘 분리되어 있다” 혹은 “기능을 원자적으로 쪼개 제공한다” 정도로 해석할 수 있다. 예를 들어 본문의 List 설명에서 ‘부분리스트 얻기’와 ‘주어진 원소의 인덱스 구하기’는 서로 관련이 없다. 따라서 두 기능을 개별 메서드로 제공해야 직교성이 높다고 할 수 있다.
- 매개변수는 4개 이하로 유지하는 것이 좋다. 매개변수가 많아지면 기억하기 어렵고 사용자가 혼동할 수 있다.
- 같은 타입의 매개변수가 여러 개 연달아 나오는 경우는 특히 피해야 한다. 매개변수의 순서를 잘못 입력할 가능성이 있기 때문이다.
// 나쁜 예시 - 매개변수가 너무 많음
public void createUser(String firstName, String lastName, String email, String phoneNumber, String address, String city, String zipCode) {
// 사용자 생성 로직
}
// 좋은 예시 - 매개변수 수를 줄이기 위해 도우미 클래스를 사용
public void createUser(UserInfo userInfo) {
// 사용자 생성 로직
}
// 도우미 클래스
public class UserInfo {
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
private String address;
private String city;
private String zipCode;
// 생성자, 게터, 세터 등을 정의
}- 메서드 나누기: 메서드를 여러 개로 쪼개 각각이 원래 매개변수 목록의 부분집합을 처리하도록 한다. 이렇게 하면 메서드 수는 늘어날 수 있지만 기능 간의 독립성을 높여 유지보수를 쉽게 한다. java.util. List 인터페이스가 좋은 예다.
// 나쁜 예시 - 모든 기능을 하나의 메서드로 처리
public void processPayment(String cardNumber, String expiryDate, double amount) {
// 결제 처리 로직
}
// 좋은 예시 - 메서드를 나눠서 책임 분리
public void validateCard(String cardNumber, String expiryDate) {
// 카드 유효성 검사
}
public void executePayment(double amount) {
// 결제 실행
}- 도우미 클래스 활용: 매개변수 여러 개를 묶어주는 도우미 클래스를 만들기. 일반적으로 이런 도우미 클래스는
정적 멤버 클래스로 둔다. 특히 잇따른 매개변수 몇 개를 독립된 하나의 개념으로 볼 수 있을 때 추천하는 기법이다. 예를 들어 카드의 숫자와 무늬를 묶어 하나의 매개변수로 만들면 API와 클래스 구현이 깔끔해진다.
// 도우미 클래스를 활용해 매개변수를 묶기
public class CardInfo {
private String cardNumber;
private String expiryDate;
// 생성자와 게터를 정의
}
public void processPayment(CardInfo cardInfo, double amount) {
// 결제 처리 로직
}- 빌더 패턴 응용: 메서드 호출에서도 빌더 패턴을 응용하여 많은 매개변수를 처리한다. 먼저 모든 매개변수를 하나로 추상화한 객체를 정의하고, 클라이언트에서 이 객체의 세터(setter) 메서드를 호출해 필요한 값을 설정하게 하는 것이다.
- 이때 각 세터 메서드는 매개변수 하나 혹은 서로 연관된 몇 개만 설정하게 한다.
- 클라이언트는 먼저 필요한 매개변수를 다 설정한 다음, execute 메서드를 호출해 앞서 설정한 매 개변수들의 유효성을 검사한다. 마지막으로, 설정이 완료된 객체를 넘겨 원하 는 계산을 수행한다.
public class Payment {
private String cardNumber;
private String expiryDate;
private double amount;
public static class Builder {
private String cardNumber;
private String expiryDate;
private double amount;
public Builder cardNumber(String cardNumber) {
this.cardNumber = cardNumber;
return this;
}
public Builder expiryDate(String expiryDate) {
this.expiryDate = expiryDate;
return this;
}
public Builder amount(double amount) {
this.amount = amount;
return this;
}
public Payment build() {
Payment payment = new Payment();
payment.cardNumber = this.cardNumber;
payment.expiryDate = this.expiryDate;
payment.amount = this.amount;
return payment;
}
}
}
// 사용 예시
Payment payment = new Payment.Builder()
.cardNumber("1234-5678-9012-3456")
.expiryDate("12/24")
.amount(100.0)
.build();- 클래스 대신 인터페이스 사용: 매개변수 타입으로 인터페이스를 사용하는 것이 클래스보다 유연하다. 예를 들어
Map인터페이스를 사용하면 여러 구현체(HashMap,TreeMap등)를 사용할 수 있다.
// 나쁜 예시 - 특정 구현체에 의존
public void processData(HashMap<String, String> data) {
// 데이터 처리 로직
}
// 좋은 예시 - 인터페이스 사용
public void processData(Map<String, String> data) {
// 데이터 처리 로직
}- boolean 대신 열거 타입 사용: 가능하면 boolean 대신 2개 이상의 값을 가지는 열거형(enum)을 사용합니다. 열거형은 코드의 의미를 명확히 전달할 수 있고, 선택지를 쉽게 확장할 수 있다.
public enum TemperatureScale { FAHRENHEIT, CELSIUS, KELVIN }
// 나쁜 예시
public Thermometer newInstance(boolean isCelsius) {
// 섭씨 온도계를 반환
}
// 좋은 예시 - 열거형 사용
public Thermometer newInstance(TemperatureScale scale) {
// 주어진 온도 단위에 맞는 온도계를 반환
}- 편의성을 위한 고수준 기능 제공은 신중히: 자주 사용되는 조합이나 성능 최적화를 위한 고수준 기능을 별도로 제공할 수 있지만, 필요 이상의 고수준 기능 추가는 API를 복잡하게 만들 수 있다.
- 직교성(Orthogonality)을 고려한 설계는 테스트와 유지보수를 용이하게 한다. 기능 간에 서로 독립적이도록 잘 나누는 것이 핵심이다.
.png)
.png)
.png)