: 사전 지식이 없는 개발자조차 코드를 통해 맥락을 파악할 수 있기 때문이다!
: 코드를 이해하기 힘들고, 혼란을 주거나, 예측이 불가능하게 만드는 이름들이다.
대표적으로 이름에 의미가 없는 경우와 의미가 부정확한 경우를 꼽을 수 있다.
//이게 왜 어떤식으로 쓰이는지 전혀 알 수 없음
//a1과 a2의 차이는 무엇인가?
int a1 = 0;
int a2 = 1;
playerController.change(a1, a2);
//리팩토링
int fist = 0
int dagger = 1
playerController.changeEqipWeapon(fist, dagger);
class PlayerInfoController
class PlayerDataController
class PlayerObjectController
// 위의 클래스의 차이가 뭔지 한번에 알 수 있나?
class PlayerAbllityController
class PlayerAchievementController
class PlayerInventoryController
//차례로 능력치, 업적, 소지창에 대한 것임을 한눈에 알 수 있다.
//Minecraft 관련 코드
/*광범위한 경우*/
class MinecraftPlayerController
class MinecraftMonsterController
//Minecraft는 너무 광범위해서 어떠한 의미도 주지 않음.
//리팩토링
class PlayerController
class MonsterController
/*협소한 경우*/
class AliceAttackController
//Alice는 너무 좁은 범위의 의미
//프로젝트의 성향에 따라 범위는 유동적이다.
//FemalePlayer 또는 FemaleNPC로 대체하는 것이 적절한 범위
//리팩토링
class FemalePlayerAttackController
Object bossMonsterMoveController;
Object bossMonsterModController;
//언뜻 보기에 비슷한 이름
//옛날 코드
QuestNumber questNumberAliceStory;
//지금 코드
QuestString questNumberAliceStory;
//타입을 굳이 적을 이유가 없고 타입이 변경되었을 때는 혼란을 줄 수 있음
//리팩토링: 타입 빼고
QuestString aliceStory;
/*재료 아이템을 인벤토리 리스트에 추가하는 메소드*/
private List<MaterialItem> addMaterialItem(MaterialItem material){
InventoryList.append(meterial);
return InventoryList;
}
//둘다 동일하게 list에 값을 추가하는 건데 add와 insert를 사용
//같은 개념에 다른 용어
/*무기 아이템을 인벤토리 리스트에 추가*/
private List<WeaponItem> insertWeaponItem(WeaponItem weapon){
InventoryList.append(weapon);
return InventoryList;
}
//두 문자열을 하나의 문자열로 만드는 개념
//리스트에 더하는 메소드도 add, 문자열을 더하는 것도 add -> 개념 충돌
/*요리 재료와 조리 도구를 합쳐서 새로운 문자열을 생성*/
private String addFoodItem(FoodItem food, MakingItem pot){
return String.format("A cooked %s in a hot %s", food.toString(), pot.toString())
}
//리팩토링
//insert: 리스트에 추가
//add: 문자열을 더함
//정해진 것이 아니라 일관된 표현이 중요
private List<MaterialItem> insertMaterialItem(MaterialItem material){
...
}
private List<MaterialItem> insertWeaponItem(MaterialItem material){
...
}
private String addFoodItem(FoodItem food, MakingItem pot){
...
}
/*잘못된 케이스*/
// PrintDamageLog가 무엇을 하는 메소드인지 가장 아래까지 가야 알 수 있음
//메소드의 정보가 부분적으로만 표현됨
//함수의 길이도 너무 길다.
Private void PrintDamageLog(String character, int damage){
String damageClassficaionName;
String logColor;
if(damage == 0){
damageClassficationName = "Miss";
String logColor = "gray";
}
else if (damage > 10000){
damageClassficationName = "Critical"
String logColor = "red";
}
else{
damageClassficationName = "Auto attack"
String logColor = "blue";
}
String logMessage = String.format(
"%s damage: (%s) %s - %d", character, logColor, damageClassficationName, damage
}
//리팩토링
//클래스를 통해서 깔끔하게 정리 가능
//메소드를 쪼개서 메소드 추출 리팩토링 기법을 사용
Class DamageLog{
private String damageClassficaionName;
private String logColor;
//핵심 메소드를 통해서 클래스의 역할을 바로 알 수 있음
//핵심 역할: DamageLog를 print
public String print(String character, int damage){
setDamageLog(character, damage);
return String.format(
"%s damage: (%s) %s - %d", character, logColor, damageClassficationName, damage
)
}
//명확하게 어떻게 나누어지는지 직관적으로 확인 가능
private setDamageLog(String character, int damage){
if(damage == 0){
damageIsMiss();
}
else if(damage > 10000){
damageIsCritical()
}
else{
damageIsAutoAttack()
}
}
private void damageIsMiss(){
damageClassficationName = "Miss";
String logColor = "gray";
}
private void damageIsCritical() {
damageClassficationName = "Critical"
String logColor = "red";
}
private void damageIsAutoAttack(){
damageClassficationName = "Auto attack"
String logColor = "blue";
}
}