개요
저희 회사에서 AI 코딩을 이용해 제가 간단히 만든 이미지 판정 프로그램이 있습니다.
소스 코드 : https://drive.google.com/file/d/1sfCMVzhr_wmu3ZqfbxEPsQ-_c1buNGPb
※ 지난글에서 소개한 이미지 판정(흰색 오염 판정) 로직 외에 두가지 로직이 추가되어 있습니다.
(경계선의 선형 완결성 판정, 흑점 검출 판정)
※ 참고 이전글
https://www.gpters.org/dev/post/determination-defective-product-images-HzGwJZluRDLyU26
https://www.gpters.org/dev/post/determination-defective-product-images-sosI4iWn0CXHrRn
이 코드는 실행하게 되면 다음과 같은 GUI창이 뜨면서 크게 3종류의 이미지 판정을 할 수 있게 로직이 구성되어 있습니다.
당장 회사에서 사용해야 하는 꼭 필요한 기능은 모두 구현되어 있었고 사용에 불편함은 없었지만, 소스코드를 관리하는 제 입장에서는 불편한 점이 몇가지 있었습니다.
필요할 때마다 AI 코딩툴을 통해 코드를 추가하다 보니 각각의 코드들이 따로 노는 모양이었습니다. (최소한의 기능 구현 후 최대한 정리했지만 부족함이 많았습니다.)
폴더/파일경로에 대한 관리, 파라미터에 대한 관리도 최대한 패키지화 한 GUI 로 정리했지만, 그럼에도 호출시에서는 각각의 번호로 호출해서 가독성이 좋지 않았습니다.
비슷 비슷한 구조의 코드가 반복되어서 한번 수정이 발생하면 반복되는 코드를 모두 다시 바꿔야 하는 어려움이 있었습니다.
앞으로도 기능은 계속 추가될 예정인데(현업에서 이미지 판정이 필요하다는 로직이 생길 때마다 조금씩 기능은 추가될 것 같 습니다.) 점점 코드가 복잡해져서 구현이 점점 어려워 졌습니다.
이와 같은 문제점을 모두 한번에 해결해 보고자 Code Refactoring을 진행해 봤습니다.
Code Refactoring : 리팩터링(refactoring)은 소프트웨어 공학에서 '결과의 변경 없이 코드의 구조를 재조정함'을 뜻한다. 주로 가독성을 높이고 유지보수를 편하게 한다. 버그를 없애거나 새로운 기능을 추가하는 행위는 아니다.
AI 활용 상세
이전에 genspark을 활용하여 GitHub Copilot과 Cursor의 차이점을 분석했었습니다.
https://www.gpters.org/dev/post/asked-genspark-cursor-vs-NbhjOaUx2fWINvR
당시 내린 결론으로 "리팩토링에는 Cursor가 더 유리하다." 였으므로, Cursor를 이용하여 리팩토링을 진행하였습니다.
Cursor의 Composers를 띄워두고, Refactoring을 하고자 하는 코드를 올려둔 상태에서 간단히 지시했습니다.
코드를 리팩토링해줘
그 결과 다음과 같은 응답을 확인할 수 있습니다.
그리고, Composers 좌측에도 다음과 같이 4개의 파일이 만들어진 것을 확인 할 수 있었습니다.
코드 내부 구조를 살펴보니, 주요 변수 선언 및 코드의 큰 틀까지는 구조적으로 잘 구성되게 변경된 것을 볼 수 있었습니다.
다만, 메인 기능 부분은 상세 코드가 채워져 있지 않았습니다.
다시 다음과 같이 지시를 했습니다.
기존 코드의 내용으로 프레임 생성 로직, 위젯 생성 로직, 파라미터 업데이트 로직도 코딩해줘
기존 로직의 내용으로 Simple Judge 로직, Line Judge 로직, Dot judge 로직 코드를 완성해줘
이렇게 2번의 지시를 추가하고 나자 코드 내부까지 채워진 것을 확인할 수 있었습니다.
Accept All을 클릭한 다음 "main.py"파일을 실행해 보니, 이번에는 에러가 발생하는 것을 확인할 수 있었습니다.
뭔가 에러가 있는 것을 볼 수 있어서 Composers에서 다시 수정을 요청했습니다.
실핼하니 다음과 같은 에러가 발생했어.
ModuleNotFoundError: No module named 'IMG_Judge_Refactor'
에러 수정해줘.
이번에는 만들어진 파일을 다음과 같이 폴더 구조로 변경하면 해결 될것이라는 상세한 안내를 알려줬습니다.
가이드에 맞춰 폴더를 생성하고, 폴더에 위와 같은 파일들을 복사해 넣거나 생성한 다음,
터미널에서 "python main.py"를 실행했습니다.
이번엔 또 다른 에러가 발생했습니다.
다시 Composers에서 물었습니다.
다음과 같은 오류가 발생했어.
AttributeError: 'ImageJudgeGUI' object has no attribute 'line_judge_test'. Did you mean: 'simple_judge_test'?
오류 수정해줘
그러자, 다음과 같이 누락되었음을 확인한 메세지와 함께 추가할 코드를 만들어 줬습니다.
이제 여기까지 해서 실행해 보니, 정상적으로 실행이 되고, GUI가 뜨는 것을 확인할 수 있었습니다.
완성된 코드 모음 :
https://drive.google.com/drive/folders/1I_WDgyX9lKJCx_FkbR1yFmqg7gHsxxL_?usp=sharing
결과 확인
1) 기능 동작 확인
주요 기능 중 Line Judge와 Dot Judge를 Test 해 볼 수 있는 이미지는 회사에 있는 관계로 주말에 Test해 보지는 못했습니다.
"White dot in Black area" 기능은 가상의 열쇠 이미지로 테스트해본 결과 잘 동작하는 것을 확인할 수 있었습니다.
2) Refactoring된 코드 구성 확인
코드 길이는 8% 가량 줄었습니다.
741줄 → 8 + 412 + 245 + 15 = 680줄
소스의 길이 관점에서는 그리 유의미하게 효율적으로 변했다고 보기는 어려웠습니다.
코드 내부 구성에서는 불명확한 변수들의 상당 부분이 명확히 정리되었습니다.
image_processor.py 코드 내부의 파일/폴더 경로나 주요 Parameter를 불러오는 부분의 소스 코드가 보다 명확해져서 이후 수정/보완이 필요할 때 가독성이 좋아졌습니다.
※ 물론 gui.py에서는 실행시마다 각각의 parameter를 연결하는 작업이 필요했기 때문에 불명확한 요소가 완전히 사라진 것은 아니었습니다.
불필요하게 Case를 나누고 반복되었던 꼭 필요한 부분만 조건문으로 따지게 깔끔하게 정리 되었습니다.
Ex) 폴더/파일 경로 GUI 구성 로직
이랬던 코드가
이렇게 바뀌었습니다.
파일의 구성도 하나의 파일에 모든 내용이 모여 있는 것이 아니라 목적에 따라 파일별로 나뉘어져 있었습니다. 이후 , 기능이 추가될 경우 목적에 따라 필요한 영역만 수정하면 되어 향후 관리 는 좀 더 용이해 졌습니다.
결론 및 시사점
이미 어느 정도 완성되어 필요한 기능은 잘 동작하던 코드를 향후 유지 보수의 용이성을 확보하기 위해 Refactoring을 진행했습니다.
원래 Refactoring 작업이 노력이 많이 들어가는 반면 기능 면에서는 큰 차이를 보이지 않기 때문에 쉽게 진행하기가 어려운 영역인 것은 사실입니다.
하지만, Cursor와 같은 AI툴을 활용하면 이전과는 다르게 훨씬 작은 공수로도 훌륭하게 Refactoring을 해낼 수 있음을 확인 할 수 있었습니다.
다만, 단 한번의 Refactoring을 요청하는 명령 만으로는 모든 것이 완벽하게 수행하지 않는다는 점.
코드가 만들어진 이후에도 재차 실행, 코드 확인 및 Test를 거듭하면서 추가 수정을 요청해야 완성도를 높일 수 있다는 것을 알 수 있었습니다.