노마드코더 개발자북클럽 Clean code Mission(2) : 예시 만들기

Python 리팩토링


원칙1과 예시

원칙 1.


Dependency Inversion Principle
클래스는 상세한 구현이 아닌 추상화에 의존해야 한다.




[before]


class Pedal:

    def __init__(self, _type:str):

        self.pedal_type = _type


    def get_pressure(self)->int:

         if self.pedal_type == 'accelerator':             sensor = AcceleratorSensor()             pressure = sensor.copy_pressure_buffer()

            # do something

         elif self.pedal_type == 'brake':             sensor = BrakeSensor()             pressure = sensor.copy_pressure_buffer()

            # do something

         elif self.pedal_type == 'clutch':             sensor = CluthSensor()             pressure = sensor.copy_pressure_buffer()

            # do something

        return pressure             

      

[after]

class Pedal:

    def __init__(self, _type:str, sensor : Sensor):

        self.pedal_type = _type         self.sensor = sensor


    def get_pressure(self)->int:         return sensor.copy_pressure_buffer()


  

// 어떻게 고쳤는지, 사례에서 무엇을 배워야 하는지 ?

자동차를 예시로 들자면, 운전석에는 여러 종류의 페달이 있다.

_type을 직접 입력 받아서
if문을 통해 페달의 종류마다 분기문을 통해
페달에 가해지는 압력 값을 받아오는 로직을 상세하게 구현하기보다는


자세한 구현은 sensor class에 맡겨서
Pedal 클래스에서 가해지는 압력 값을 얻는 구현에 미치는 영향을 격리한다.














원칙2와 예시

원칙 2. 하나의 함수는 한 가지 일만 한다.

두 값을 더해서 db에 밀어넣는 작업의 예.



before

async def sum_and_save(a, b, db:AsyncSession):     answer = a + b     await db I/O Job(answer)

        

await sum_and_save(3,4, db=db)


after

  def _sum(a, b):          return a + b

 async def save(value, db):       result = await I/O Job(value)       return result total = _sum(3,4) save(total, db)
 
        

// 어떻게 고쳤는지, 사례에서 무엇을 배워야 하는지 ?

두 수를 더하는 작업과, db에 넣는 작업이 하나의 함수 안에 묶여있었는데
두 수를 더하는 작업과  db 작업에 대한 함수를 따로 만들었다. 

*db는 session이나 asyncsession과 같은
인스턴스화 된 db 연결 객체라고 가정.

*연결 객체 db가 없을 때에는 save() 작업을 할 수 없으므로
FastAPI에서는 Depend를 이용한다.












원칙 3과 예시

원칙 3. 높은 응집도의 클래스를 선호한다.
응집도가 높다는 말은 클래스에 속한 메서드와 변수가
서로 의존하며 논리적인 단위로 묶인다는 의미이다.



before

LogManager:

    def __init__(self, _type):         self._type = _type         self.db = None     

    def parse_log_file(self, _type):         if _type == '~':...     def connect_to_db(self):         connection = sesssion(f"mongodb:// ...")         self.db = connection     def get_log(self, id):         self.connection.query(...)




after


AccessLogRepository:

    def __init__(self, db):         self.db = db     

    def get_log_by_id(self, id):         self.db.query(...)


    def filter_logs_by_period(self, start, end):

        self.db.query(...)

  

// 어떻게 고쳤는지, 사례에서 무엇을 배워야 하는지 ?

LogManager라는 두리뭉술한 의미와 많은 역할이 종합되어 있는 클래스 대신
한 종류의 로그에 대해 DB 쿼리 작업을 하는 Class를 만들었다.
Repository 패턴.



 #노개북 #노마드코더 #개발자북클럽 


댓글

이 블로그의 인기 게시물

실무진 면접 경험으로 정리하는 백엔드 (1) : 에듀 테크 기업 면접

Blogger 커스터마이징 : CSS 수정 (sticky-header)

Intel 14th gen CPU의 칩 충돌 사태와 해결 방법