Clean Code 1st μŠ€ν„°λ””

leocodmsΒ·2023λ…„ 5μ›” 2일
0

BackEnd

λͺ©λ‘ 보기
4/6

첫번째 μŠ€ν„°λ””

2023.02.03

λ‚˜μœ μ½”λ“œ

πŸ’‘ λ‚˜μœ μ½”λ“œλ‘œ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 치λ₯΄λŠ” 고톡

κΉ¨λ—ν•œ μ½”λ“œ

πŸ’‘ κΉ¨λ—ν•œ μ½”λ“œλž€?

  • 주의 깊게 μž‘μ„±ν•œ μ„Έμ„Έν•œ μ‚¬ν•­κΉŒμ§€ κΌΌκΌΌν•˜κ²Œ μ‹ κ²½μ“΄ μ½”λ“œ. κΉ”λ”ν•˜κ³  λ‹¨μ •ν•˜κ²Œ μ •λ¦¬λœ.
  • μž˜μ“΄ λ¬Έμž₯처럼 μ½νžˆλŠ”.
  • μ§μž‘ν–ˆλ˜ κΈ°λŠ₯을 κ·ΈλŒ€λ‘œ μˆ˜ν–‰ν•΄μ•Όν•˜λ©°, μ½μœΌλ©΄μ„œ λ†€λž„μΌμ΄ μ—†λŠ”. ν•¨μˆ˜λͺ…, λ§€κ°œλ³€μˆ˜λͺ…, μ±…μž„ 뢄리,,
  • 남듀이 μˆ˜μ •ν•˜κΈ° μ‰¬μš΄
  • μ‹œκ°„μ΄ μ§€λ‚˜λ„ κΉ¨λ—ν•˜κ²Œ μœ μ§€λ˜λŠ”

의미 μžˆλŠ” 이름

μ˜λ„λ₯Ό λΆ„λͺ…νžˆ λ°ν˜€λΌ!

의미있게 κ΅¬λΆ„ν•˜λΌ!

  • λΆˆμš©μ–΄λ₯Ό μΆ”κ°€ν•œ 이름은 μ•„λ¬΄λŸ° 정보λ₯Ό μ œκ³΅ν•˜μ§€ λͺ»ν•œλ‹€.
class Product {}
class ProductData {}
class ProductInfo {}
  • 쀑볡 λ˜ν•œ λΆˆμš©μ–΄μ΄λ‹€.
    λ³€μˆ˜ 이름에 variable, ν…Œμ΄λΈ” 이름에 table.
getActiveAccount()
getActiveAccounts()    // μ—¬λŸ¬κ°œ 리턴이 ν•„μš”ν•  수 μžˆλŠ”λ°, μ–΄λ–»κ²Œ λ³€κ²½ν•˜λ©΄ μ’‹μ„κΉŒ?
getActiveAccountInfo()
  • κ·Έλ¦‡λœ 정보λ₯Ό 피해라.

ex 1)

ex 2)

ex 3)

클래슀 이름, λ©”μ„œλ“œ 이름!

  • 클래슀, 객체 이름은 λͺ…사 λ˜λŠ” λͺ…사ꡬ
  • λ©”μ„œλ“œ 이름은 동사 λ˜λŠ” 동사ꡬ

ν•œ κ°œλ…μ— ν•œ 단어λ₯Ό μ‚¬μš©ν•˜λΌ!

πŸ‘

의미 μžˆλŠ” λ§₯락을 μΆ”κ°€ν•˜λΌ!

firstName, lastName, street, houseNumber, city

β†’ addrFirstName, arrdLastName, addrState

β†’ Address Class 생성





κ·Έλž˜μ„œ!

πŸ’‘ 넀이밍 κ·Έκ±° μ–΄λ–»κ²Œ 잘 ν•  수 μžˆλŠ”λ°μš”..?

  • κ°œλ… 정리 및 일원화
  • 그런데
    μš°λ¦¬λŠ” ν˜‘μ—…ν•΄μ„œ 일해야 ν•˜λŠ”λ°μš”..? κ°œλ…μ— λŒ€ν•œ 이해가 λ‹€λ₯Ό 수 μžˆμ–΄μš”!


βœ‹ κ·Έλž˜μ„œ μ œμ•ˆν•©λ‹ˆλ‹€! μœ‘ν•˜μ›μΉ™μ„ μ μš©ν•œ 넀이밍은 μ–΄λ–€κ°€μš”?

μ–Έμ œ, μ–΄λ””μ„œ, λˆ„κ°€, μ–΄λ–»κ²Œ, μ™œ, 무엇을

β†’ DealService.process(events)
λˆ„κ°€ : λ”œ μ„œλΉ„μŠ€κ°€.
μ–΄λ–»κ²Œ : μ²˜λ¦¬ν•œλ‹€.
무엇을 : μ΄λ²€νŠΈλ“€μ„.


operation에 λ”°λΌμ„œ μ²˜λ¦¬κ°€ 달라짐.

β†’ SpecialShopMatchService.processCreate(events)
λˆ„κ°€ : νŠΉκ°€μƒ΅ 맀치 μ„œλΉ„μŠ€κ°€.
μ–΄λ–»κ²Œ : μ²˜λ¦¬ν•œλ‹€.
무엇을 : μ΄λ²€νŠΈλ“€μ˜ 생성을.


Link Type에 λ”°λΌμ„œ μ²˜λ¦¬κ°€ 달라짐.
β†’ SpecialShopMatchService.processTourTicketCreate(events)
λˆ„κ°€ : νŠΉκ°€μƒ΅ 맀치 μ„œλΉ„μŠ€κ°€.
μ–΄λ–»κ²Œ : μ²˜λ¦¬ν•œλ‹€.
무엇을 : νˆ¬μ–΄ν‹°μΌ“ μ΄λ²€νŠΈλ“€μ˜ 생성을.

ν•¨μˆ˜

μž‘κ²Œ λ§Œλ“€μ–΄λΌ

πŸ‘

ν•œ κ°€μ§€λ§Œ 해라

πŸ’‘ ν•œ κ°€μ§€μ˜ λ²”μœ„κ°€ λ­”λ°μš”..?

  • μ§€μ •λœ ν•¨μˆ˜ 이름 μ•„λž˜μ—μ„œ 좔상화 μˆ˜μ€€μ΄ ν•˜λ‚˜μΈ λ‹¨κ³„λ§Œ μˆ˜ν–‰
  • 의미 μžˆλŠ” μ΄λ¦„μœΌλ‘œ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μΆ”μΆœν•  수 μžˆλ‹€λ©΄, κ·Έ ν•¨μˆ˜λŠ” μ—¬λŸ¬ μž‘μ—…μ„ ν•˜λŠ” 것이닀.

switch λ¬Έ

public Mony caculatePay(Employee e) throws InvalidEmployeeType{
	switch (e.type) {
		case COMMISSIONED:
			return calculateCommissionedPay(e);
		case HOURLY:
			return calculateHourlyPay(e);
		case SALARIED:
			return calculateSalariedPay(e);
		default:
			throw new InvalidEmployeeType(e.type);
	}
}
  • 4가지 문제점
    1. κΈΈλ‹€
    2. ν•œ κ°€μ§€λ§Œ μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€.
    3. SRP 유발
      μ½”λ“œλ₯Ό λ³€κ²½ν•  μ΄μœ κ°€ μ—¬λŸΏμ΄λ‹€. isPayday(), deliverPay()
      - λ‹¨μΌμ±…μž„ 원칙 SRP(single responsibility principle)
          <aside>
          πŸ’‘ ν΄λž˜μŠ€λŠ” ν•˜λ‚˜μ˜ μ±…μž„λ§Œ 가지며, ν΄λž˜μŠ€λŠ” κ·Έ μ±…μž„μ„ μ™„μ „νžˆ μΊ‘μŠν™” 해야함.
          
          </aside>
          
          μ±…μž„ : λ³€κ²½ν•˜λ €λŠ” 이유
          
          [JPA μ˜ˆμ‹œ](https://stackify.com/solid-design-principles/)
          
    4. OCP μœ„λ°˜
      μƒˆ 직원 μœ ν˜•μ„ μΆ”κ°€ν•  λ•Œλ§ˆλ‹€ μ½”λ“œλ₯Ό λ³€κ²½ν•΄μ•Ό ν•œλ‹€.
  • λ¦¬νŽ™ν† λ§ Switch 문을 좔상 νŒ©ν† λ¦¬μ— μˆ¨κΈ΄λ‹€. β†’ λ‹€ν˜•μ„±
    public abstract class Employee {
    	public abstract boolean isPayday();
    	public abstract Money calculatePay();
    	public abstract void deliveryPay(Money pay);
    }
    
    public interface EmployeeFactory {
    	public Employee makeEmployee(EMployeeRecord r) throws InvaliedEmployeeType;
    }
    
    public class EmployeeFactoryImpl implements EmployeeFactory {
    	public Employee makeEmployee(EmployeeRecord r) throws InvaliedEmployeType{
    		switch (r.type) {
    			case COMMISSIONED:
    				return new ComissionedEmployee(r);
    			case HOURLY:
    				return new HourlyEmployee(r);
    			case SALARIED:
    				return new SalariedEmployee(r);
    			default:
    				throw new InvaliedEmployeeType(r.type);
    		}
    	}
    }

Switch 문은 단 ν•œ 번만 μ‚¬μš©ν•΄λΌ!

λΆ€μˆ˜ 효과λ₯Ό μΌμœΌν‚€μ§€ 마라!

Public class UserValidator {
	private Cryptographer cryptographer;

	public boolean checkPassword(String userName, String password) {
		User user = UserGateway.findByName(userName);
		if (user != User.NULL) {
			String codedPhrase = user.getPhraseEncodedByPassword();
			String phrase = cryptographer.decrypt(codedPhrase, password);
			if ("Valid Password".equals(phrase)) {
				Session.initialize();
				return true;
			}
		}
		return false;
	}
}

checkPassword() β†’ checkPasswordAndInitializeSession()

β€˜ν•œ κ°€μ§€β€™λ§Œ ν•œλ‹€λŠ” κ·œμΉ™μ€ μœ„λ°˜ν•˜μ§€λ§Œ, ν•˜λŠ” μž‘μ—…μ„ λͺ…μ‹œν•˜λŠ” 편이 더 μ’‹λ‹€.

REAL WORLD CODING

였λ₯˜ μ½”λ“œλ³΄λ‹€ μ˜ˆμ™Έλ₯Ό μ‚¬μš©ν•˜λΌ

주석

μ μ ˆν•œ 주석은 가독성을 높이고 코딩을 νŽΈλ¦¬ν•˜κ²Œν•œλ‹€!

  • 정보λ₯Ό μ œκ³΅ν•˜λŠ” 주석
  • μ˜λ„λ₯Ό μ„€λͺ…ν•˜λŠ” 주석
  • 의미λ₯Ό λͺ…λ£Œν•˜κ²Œ λ°ν˜€μ£ΌλŠ” 주석
  • κ²°κ³Όλ₯Ό κ²½κ³ ν•˜λŠ” 주석
  • μ€‘μš”μ„±μ„ κ°•μ‘°ν•˜λŠ” 주석
  • TODO 주석
profile
Backend Developer

0개의 λŒ“κΈ€