Understanding 'Clean Code' in a Pythonic way
2017-08-23
Clean Code: A Handbook Of Agile Software Craftsmanship (2009) λΌλ μ± μ μ½κ³ μ 리ν κΈμ λλ€. μ± μ μμ λ Java λ‘ μ°μ¬ μμ΄μ PythonμΌλ‘ μ°μΈ μ½λλ ν¨κ» μ°Ύμ보μμ΅λλ€. μ΄ μ± μ κ·Έ μμ²΄κ° ν΄λ¦°μ½λμ λλ€. μ½λλ₯Ό μμ±νλ μμΉκ³Ό μ² νμμ μ€μ μ½λκΉμ§ μ€λͺ μ΄ λͺ ννκ³ κ΅°λλκΈ°κ° μμ΅λλ€. μ€μ λ‘ μ½λ€κ° λ ΈνΈλΆμ μΌκ³ 리ν©ν λ§νλ©° 무λ¦μ νμΉ κ²½μ°κ° μ μ§ μμμ΅λλ€.
π Clean Code (2)
'Later equals never'. μ°λ¦¬λ νμ μ§κΈμ κΈνλ λΉ λ₯΄κ² μ§κ³ λμ€μ λ€μ μ 리νμκ³ λ€μ§νκ³€ νλ€. κ·Έλ¬λ μ°λ¦¬λ μλ€. λμ€μ κ²°μ½ μ€μ§ μλλ€λ κ²μ.
μ μλ 보μ΄μ€μΉ΄μ°νΈ μμΉμ λ§νλ€. 'μΊ νμ₯μ μ²μ μμ λλ³΄λ€ λ κΉ¨λνκ² ν΄λκ³ λ λλΌ'κ³ . 빨리 κ°λ μ μΌν λ°©λ²μ μΈμ λ μ½λλ₯Ό μ΅λν κΉ¨λνκ² μ μ§νλ μ΅κ΄μ΄λ€. μ½λλ₯Ό μ½λ μκ° λ μ§λ μκ° λΉμ¨μ 10λ 1μ νμ© λλλ€. μ°λ¦¬λ λμμμ΄ κΈ°μ‘΄ μ½λλ₯Ό μ½λλ€. κΉ¨λν μ½λ, κ°λ μ±μ΄ μ’μ μ½λκ° μ€μν μ΄μ λ€.
ν΄λΌμ΄μΈνΈμ μꡬμ¬νμ ννκ³ μΆμ μ νΉμ΄ λ€ λλ μλ€. λΆκ°λ₯ν μμ²μ νλ€κ³ , κΈ°νμ΄ λ무 짧μλ€κ³ . λλ μ΄λ° λͺ λ²μ μΈμ£Όμμ μ΄λ° λμ νλλ₯Ό κ°μ§κ³€ νλ€. κ·Έλ¬λ μ견μ μ μνμ§ μκ³ μν€λλλ‘ νκ²λ κ°λ°μμ μλͺ»μ΄λ€. μ΄ μ± μμ μμ¬μ κ²½μ°λ₯Ό λ€μ΄ μ€λͺ νλ€. 'μ΄λ νμκ° μ€λ κΈ°λ€λ¦΄ μ μμΌλ μμ μ μ μμ μ»μ§ λ§λΌκ³ μꡬνλ€λ©΄, μμ¬λ λ¨νΈνκ² κ±°λΆν΄μΌ νλ€.'
μ΄ μ± μ μΈ λ§λλ‘ μμ½νλ©΄ 'μ€λ³΅ μ€μ΄κΈ°, ννλ ₯ λμ΄κΈ°, μ΄λ°λΆν° κ°λ¨ν μΆμν κ³ λ €νκΈ°'μ΄λ€.
ν΄λμ€ μ΄λ¦μΌλ‘λ Data, Info κ°μ μΌλ°μ μ΄κ³ μλ―Έμλ μ΄λ¦μ νΌνλΌλ μ μ΄ ν₯λ―Έλ‘μ λ€. μλ μ²λΌ λ³μ κΈΈμ΄λ₯Ό λμ΄μ μ ννμ§ μκΈ° λλ¬Έμ κΈΈλλΌλ μμ μ μΈ μ΄λ¦μ μ°λκ² μ’λ€. κ°μ λͺ¨λ λ΄μμλ κ°μ λͺ μ¬/λμ¬λ₯Ό μ΄λ€. λλλ‘ μκ³ λ¦¬μ¦ μ΄λ¦, ν¨ν΄ μ΄λ¦ λ± ν΄λ² μμμμ μ¨ μ΄λ¦μ μ¬μ©νκ³ , μ΄κ² μκ±°λ λ¬Έμ μμ(domain)μ λ§₯λ½μ΄ μ€μνλ€λ©΄ μ¬κΈ°μ μ¨ μ΄λ¦μ μ΄λ€.
νλμ λ©μλμ νλμ κΈ°λ₯λ§. SRP(Single Responsibility Principle)λ₯Ό μ‘΄μ€νλ€. ν¨μλ νκ°μ§λ§νκ³ κ·Έ νκ°μ§λ₯Ό 'μ'ν΄μΌ νλ€. κ·Έλ λ€λ©΄ ν¨μκ° νκ°μ§λ§ νλμ§λ μ΄λ»κ² νλ¨ν κΉ? ν¨μλͺ μ λ€λ₯Έ μ΄λ¦μΌλ‘λ ννν μ μλ€λ©΄ κ·Έ ν¨μλ μ¬λ¬ μμ μ νλ μ μ΄λ€. μΌλ°μ μΈ κΈ°μ€μ 'getter(μ‘°ν)μΈμ§, setter(λͺ λ Ή)μΈμ§' μ΄λ€.
λΉμ°ν νλμ ν¨μμ μΆμν μμ€μ νλμ¬μΌ νλ€. μΆμν μμ€μ΄ λ€λ₯΄λ€λ©΄ μ¬λ¬ λ¨κ³λ‘ λλ μ μ μνκ³ μννλ€. λ€μ¬μ°κΈ°λ 2λ¨μ λμΌλ©΄ μ’μ§ μλ€.
ν λ©μλ μμμ λ€λ₯Έ λ©μλλ₯Ό λΆλ¬μ¬ λ λΆλ₯΄λ ν¨μλ₯Ό λ¨Όμ , λΆλ¬μ§λ ν¨μλ₯Ό λμ€μ μ μνλ€. κ·Έλ¦¬κ³ μ΄μ΄μ§λ μ½λμμ κ·Έ λ©μλκ° μ μλ κ²μ κΈ°λνλ κ²μ΄ μμ°μ€λ½λ€. λΉμ°ν μ½λ νλ¦μ΄ κ³ μ°¨μμμ μ μ°¨μμΌλ‘ μ§νλκΈ° λλ¬Έμ μ΄ν΄νκΈ°λ μ½λ€. DRF μ mixins.py
λ μλμ κ°μ΄ μ νμλ€.
# mixins.py
class DestroyModelMixin(object):
"""
Destroy a model instance.
"""
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()
destroy()
λ₯Ό λνν΄μ perform_destroy()
λΌλ ν¨μλ₯Ό λ§λ€μλ€. λΆλ¬μμ§λ λ©μλλͺ
μ΄ λͺ
νν΄μΌ μ΄ ν¨μκ° μ΄λ€ κΈ°λ₯μ μνν μ§ λ―Έλ¦¬ μ§μν μ μλ€.
'μ΅μ μ 무ν ν¨μ, μ°¨μ μ 1ν ν¨μ'λΌλ μ£Όμ₯μ΄ ν₯λ―Έλ‘μ λ€. writeField(name)μ΄ writeField(outputStream, name) λ³΄λ€ μ΄ν΄νκΈ° μ½λ€. λ€ν ν¨μκ° νμ μ΄ν΄νκΈ°κ° μ΄λ €μμ μ’μ νκ³€ νλλ° λλ§ μ΄λ €μ΄κ² μλλΌλ λ€νμ΄λ€. μ΄ν ν¨μλ₯Ό μ°λ κ²½μ°λ μ’νλ₯Ό ννν λμ²λΌ λκ° μΈμκ° μμ°μ μΈ μμκ° μλ κ²½μ°λ€. μΈμκ° λ§μμ§λ€λ©΄ outputStream.writeField(name)κ³Ό κ°μ΄ ν΄λμ€ λ³μλ‘ μ μΈνλ λ°©λ²λ μλ€.
μ£Όμμ μΈμ , μ΄λ»κ² λ¬μμΌ ν κΉ? μ μλ μ£Όμμ λ¬μ§ λ§λΌκ³ μ΄μΌκΈ° νλ€. License μ 보λ₯Ό λ΄λ κ²μ΄ μλ μ΄μ, νμκ° μλ€. μ½λμ μ£Όμλ νμ λκΈ°νν΄μΌνλ©° μ€μΈλΆμΈ λ¬λ¦° μ£Όμμ μ€νλ € μ½λλ₯Ό μ½λ κ²μ λ°©ν΄νλ€. μ°¨λΌλ¦¬ μ€λͺ μ΄ νμ μλ κΉ¨λν μ½λλ₯Ό μ°μ.
μ°κ΄λ ν¨μλΌλ¦¬λ μμ§ κ±°λ¦¬λ₯Ό κ°κΉκ², λ³μλ μ¬μ©νλ μμΉμ μ΅λν κ°κΉμ΄ μ μΈνκΈ°, μ΄μΈμλ μ€λ°κΏμΌλ‘ κ°λ λΆλ¦¬(importλ¬Έκ³Ό ν¨μ μ¬μ΄ μ€λ°κΏ) λ± νμμ κ΄ν λ΄μ©μ΄μλλ° μμ§μ μλν°μ μμ‘΄νλκ² λ§μμ΄ νΈνλ€. PEP8 μ€νμΌ κ°μ΄λλ₯Ό μ°Έκ³ νκ±°λ Pylama κ°μ λꡬλ₯Ό νμ©ν μλ μλ€.
μ¬μ©μκ° κ΅¬νμ΄ μ΄λ»κ² λμ΄ μλμ§ μ νμκ° μλ€. μλ£λ₯Ό μΈμΈνκ² κ³΅κ°νκΈ° 보λ€λ μΆμμ μΈ κ°λ μΌλ‘ νννλκ² μ’λ€. μΆμν μμ€μ λ°λΌ ν¨μλ₯Ό wrapping νμ¬ λ Όλ¦¬λ₯Ό μ¨κ²¨μ£Όλ κΈ°λ²μ΄ μ μ©νλ€.
# ꡬ체μ Bad
class Vehicle:
def getFuelTankCapacityInGallons():
# pass
def getGallonsOfGalsoline():
# pass
# μΆμμ Good
class Vehicle:
def getPercentFuelRemaining():
# pass
μλ‘μ΄ λ°μ΄ν° νμ μ΄ νμν κ²½μ°λΌλ©΄ ν΄λμ€/κ°μ²΄ μ§ν₯ κΈ°λ²μ΄ μ ν©νλ€. λ°λ©΄, μλ‘μ΄ ν¨μκ° νμν κ²½μ°λΌλ©΄ μ μ°¨/μλ£κ΅¬μ‘°κ° μ ν©νλ€. μμ€ν μ μλ‘ μ§€ λ μ΄λ€ λΆλΆμ΄ μ μ°ν΄μΌ ν μ§ νλ¨νκ³ μ ννλ κ²μ΄ μ’λ€. κ°μ²΄ μ§ν₯μ μλ£λ₯Ό μ¨κΈ°κ³ λμ(ν¨μ)μ 곡κ°νλ€. κ·Έλμ μλ‘μ΄ κ°μ²΄λ₯Ό κ³μ μ°μ΄λ΄κΈ°λ μ½μ§λ§ ν΄λμ€ λ΄ μλ‘μ΄ λ©μλλ₯Ό μΆκ°νκΈ°λ 골μΉμν μ μλ€. λ°λ©΄ μλ£κ΅¬μ‘° ννλ‘ κ΅¬ννμ κ²½μ°, μλ£λ₯Ό μ¨κΈ°μ§ μκ³ λ³λ€λ₯Έ λμλ μλ€. κ·Έλμ μλ‘μ΄ λμμ μΆκ°νκΈ° μ½λ€.
κ°μ²΄μ μ μ°¨λ₯Ό κ³ λ―Όνλ©° μ½λ©ν΄λ³Έ μ μ΄ μμ΄μ μ΄ λΆλΆμ μ μλΏμ§ μμλ€. λμ€μ λ€μ νλ² μ½μ΄λ΄μΌ ν λ΄μ©μ΄λ€.
'Coding is as much an art as it is a science'
- Rebecca Parsons
To be continued!