[개발 기록] 이름 짓기
-er로 끝나는 이름을 사용금지
클래스는 객체의 라이프사이클(만들고, 관리하고, 파괴하는 과정)을 관리 해야합니다. 절대 관리를 당해서는 안됩니다. ( 이게 getter, setter를 사용하면 안되는 이유중 하나라고 생각합니다. ) 늘 클래스는 능동적이어야 합니다.
⚠️클래스의 객체가 뭘 하는가? what does it do?
“CashFormatter가 통화를 format하면 되겠다!”라고 생각하면 아래처럼 수동적인 클래스가 생성됩니다.
public class CashFormatter {
private int dollars;
public CashFormatter(int dollars) {
this.dollars = dollars;
}
public String format() {
return String.format("$ %d", this.dollars);
}
}
✅클래스의 객체가 무엇인가? what is it?
클래스는 스스로 결정을 내리고 행동할 수 있는 자립적인 엔티티입다. 아래처럼 Cash는 스스로 usd 라는 통화를 설정할 수 있습니다.
public class Cash {
private int dollars;
public Cash(int dollars) {
this.dollars = dollars;
}
public String usd() {
return String.format("$ %d", this.dollars);
}
}
코드 리팩토링 단계
절차지향적 코드 - 리팩토링 전
- 수동적인 코드를 찾으세요.
- 아래
milk
는getPrice
를 해야 가격이 찾아지는 아주 수동적인 코드입니다.Milk milk = connection.findItem("우유"); int price = milk.getPrice();
getWallet
또한 마찬가지 입니다.Person pobi = connection.findPerson("포비"); Wallet wallet = pobi.getWallet();
setter
는 문제가 많습니다.
- 불변 객체가 아니기 때문에 일관성이 떨어집니다. ``` wallet.setAmount(wallet.getAmount() - price);
- 아래
pobi.setItem(milk);
```java
public class Mart{
public static void main(String[] args) {
DBConnection connection = new DBConnection();
Milk milk = connection.findItem("우유");
int price = milk.getPrice();
Person pobi = connection.findPerson("포비");
Wallet wallet = pobi.getWallet();
wallet.setAmount(wallet.getAmount() - price);
pobi.setItem(milk);
connection.save(pobi);
}
}
절차지향 코드 - 리팩토링 1단계
-
setter
를 우선 삭제합니다 ```java public class Mart{ public static void main(String[] args) { DBConnection connection = new DBConnection();Milk milk = connection.findItem(“우유”); int price = milk.getPrice();
Person pobi = connection.findPerson(“포비”); pobi.paymentFor(price);
pobi.setItem(milk);
connection.save(pobi); }
}
#### 객체지향 코드 - 리팩토링 끝
- 수동적이던 객체를 능동적으로 바꿉니다.
- 아래처럼 `milk`가 본인을 팔기 시작했습니다.
milk.sellTo(pobi);
```java
public class Mart{
public static void main(String[] args) {
DBConnection connection = new DBConnection();
Milk milk = connection.findItem("우유");
Person pobi = connection.findPerson("포비");
milk.sellTo(pobi);
connection.save(pobi);
}
}
메서드 이름을 신중하게 선택하세요
빌더(builder)의 이름은 명사로
- 빌더는 새로운 객체를 반환하는 메서드
조정자(manipulator)의 이름은 동사로
- 반환값이 없고 인스턴스에 변화를 주는 메서드
메서드 내에서 두가지 일이 일어난다면?
void put(String key, Float value);
처럼void put()
후에boolean success()
가 같이 포함된 메서드라면 PutOperation과 같은 클래스를 추가해 save() 메서드와 success() 메서드로 분리해야 합니다.
절대 getter와 setter를 사용하지 마세요
아래 코드를 보며 단순히 dollars
를 보관하는 용도의 클래스라는 생각이 듭니다.
이런 클래스는 자료구조와 다름이 없다고 생각합니다.
public class Cash {
private int dollars;
public int getDollars() {
return dollars;
}
public void setDollars(int dollars) {
this.dollars = dollars;
}
}
왜 자료구조가 유지보수에 좋지 않은가요?
자료구조보다 객체를 지향해야하는 모든 이유는 유지보수성과 관련 있습니다.
자료구조는 내부 변수를 밖으로 오픈하기 때문에 여러 프로세스에서 자료구조를 꺼내 사용하게 됩니다.
하나의 개발을 하더라도 해당 자료구조를 열어서 사용하는 모든 프로세스에 주의를 기울일 수 밖에 없고 범위가 넓어지면 유지보수성이 떨어집니다.
자바지기님은 발가벗겨진 데이터가 절차적인 프로그래밍 스타일을 사용하도록 부추긴다.
라고 표현하셨습니다. 👏
유지보수에 좋은 프로그래밍의 핵심 목표는 범위 축소와 단순화입니다. 위 목표를 달성 할 때 코드는 이해하고 수정하기 쉬워집니다.
접두사에 대하여
접두사 : 어떤 단어의 앞에 붙어 새로운 단어가 되게 하는 말
흔히 말하는 getXXX
, setXXX
입니다.
getDollars
와 같은 getter
는 데이터를 찾아 반환하라는 강제성이 있습니다. ( 돈내놔. 😠)
객체에게서 능동성을 앗아갔습니다.
반면에 dollars
는 “나 돈 얼마 있을까..? 🥹”라는 느낌이 들죠..? ( 그렇다고 하세요. 😡)
public class Cash {
private final int dollars;
public int dollars() {
return this.dollars;
}
}
댓글남기기