[이 프로젝트를 시작하게 된 이유] 저는 3주차 미션까지 하면서 회고 하기가 가장 어려웠습니다. 노트나 메모장에 어떤 내용으로 적을지 저장해놓고 막상 회고를 적을때는 까먹어서 다시 코드나 커밋을 보면서 적거나, 더듬더듬 메모를 찾아 다시 기억을 꺼내는 작업을 하면서 회고를 했습니다. 그렇게 하다보니 메모를 보더라도 어떤 의도로 이 글을 적었는지 기억이 안날때도 있고, 메모를 할 때에도 코드와 같이 인사이트나 감상을 적고 싶은데 그렇제 못하니 어려울때가 많았습니다. 이런 문제점들 때문에 개발과 회고가 완벽히 분리되어 일관성이 떨어지는 경험을 자주 했었어요.
그러다 개발 기록을 개발 프로젝트 안에서 함께 관리할 수 있다면 개발 일지나 회고를 적을 때 더 좋지 않을까? 라는 생각이 문득 들었습니다. 저는 이 생각을 작게 검증하기 위해 우선 사람들은 회고나 개발 일지를 어떻게 적는지 우테코 프리코스 디스코드에 여쭤보았습니다.
열 분이 넘는 분들께서 정말 따듯하게 답변해주셨고, 가장 많은 답변은 역시 노션이나 메모장을 이용해 메모하는 것이었습니다. 많은 분들께서 메모를 다른 기록 플랫폼을 통해 기록하기때문에 저는 기록 플랫폼을 하나로 합쳐 개발과 기록을 함께 할 수 있는 어플리케이션을 만들어야겠다고 생각했습니다.
[어떤 플랫폼으로 만들거야?] 정말 많은 고민을 했던 부분이었습니다. 취지와 목적은 뚜렸했으나, 이런 어플리케이션을 어디서 만들어 사용자에게 전달할지는 전혀 고려하지 않았었습니다. 처음에는 웹 어플리케이션만 막연하게 생각하며 깃허브 레포지토리와 연동 가능한 기록 웹 어플리케이션을 만들까? 라는 생각을 했습니다. 기술적으로는 복잡하고 대단한 도전이 될 것 같아보였지만, 그게 정말 개발과 기록을 함께 할 수 있는 어플리케이션이 될 수 있는지는 강한 의문이 들었습니다. 깃허브 레포지토리는 정돈하여 commit된 내용만 push를 하기 때문에 그런 상태에서 적는 기록은 솔직하지 못하고 즉각적이지 않은 기록이라고 생각했습니다. 결과적으로 이렇게 메모를 하는건 노션을 이용해 정리하는 것과 마찬가지이기 때문에 저는 이 방법을 포기하고 다른 방법을 찾아보았습니다.
그러던 중, 어떻게 만들기 최상단에서 고민하기 보단 내가 어디서 개발을 하는지 내려와 다시 집중하기로 했습니다. 저는 주로 백엔드를 개발을 할때, java를 이용하기 때문에 intellij 라는 IDE를 사용합니다. 그리고 인텔리제이 안에서 개발 기록도 하면 좋겠단 생각이 들었습니다. 인텔리제이에서는 마켓플레이스를 통해 다양한 기능이 있는 플러그인을 다운받아 IDE 내부에서 사용할 수 있습니다. 플러그인을 생각하는 순간 개발과 기록을 함께라는 가치를 사용자에게 어떻게 전달할지 명확해졌습니다. 개발은 주로 IDE를 통해서 하므로, 기록을 IDE 안에서 할 수 있도록 플러그인을 제공하는 것입니다.
[어떻게 만들거야?] 플러그인을 개발하기로 마음 먹었기 때문에, 개발의 방향성은 정확해졌습니다. 하지만 아직 가치를 어떤 기능과 화면으로 풀어낼지는 확실하지 않습니다. 그래서 개발과 기록을 함께라는 가치를 구체적으로 풀어쓰면 어떤 느낌인지 정리해보았습니다.
- 개발하는 순간을 기록을 할 수 있어야 한다.
- 내가 기록을 작성할 때, 코드의 상태와 시점이 저장되어야 한다.
- 내가 원하는 코드를 선택해서 그 부분에 대한 기록을 할 수 있어야 한다.
- 기록을 나중에 한 눈에 볼 수 있거나 그 기록을 재가공 할 수 있어야 한다.
위의 구체적인 가치를 나름대로 정하여 이를 기준으로 최종적으로 구체적인 기능과 저장해야 할 데이터를 결정할 수 있었습니다.
기능은 구체화 할 수 있었지만, 저는 아직 인텔리제이 플러그인을 전혀 만들 줄 모릅니다. 특히 kotlin은 처음 사용해보는 것이며, 자바 스윙은 예전에 학교 과제로 사용은 해보았지만 기억이 전혀 안나는 상황이었습니다. 그렇기에, 저는 1차 완성의 목표를 AI에 의존해 완성을 하고, 완성한 경험을 통해 내가 다시 만들어보자는 계획을 세우고 행동으로 옮겼습니다. AI를 이용해 개발을 하면서 사실 거의 자연어로 개발을 했고, 서비스 로직에서는 큰 오류가 없었지만 자바 스윙 부분에서 원하는 디자인으로 나오지 않아 그 부분에서 많이 난항을 겪었습니다.
[AI를 이용한 바이브 코딩을 통해 뭘 배웠어?] 저는 인텔리제이 플러그인을 어떻게 만들어야 할지 몰랐지만, AI를 통해 코틀린의 필수 문법과 플러그인이 제공하는 api를 학습할 수 있었습니다. 그리고 저는 프로젝트를 할 때, 내가 생각한 기능을 실제로 구현할 수 있는지와 정말 필요한지를 항상 고민합니다. 그렇기에 이런 부분에서 저는 AI를 적극적으로 사용하여 프로토타입을 만들고, 가능한 부분과 실제로 필요한 부분을 빠르게 피드백 하여 보다 더 완성도 있는 결과물을 만들어 낼 수 있었습니다.
하지만 단점이 명확했습니다. 뻔하긴 하지만, 이해하는 코드보다 이해하지 못하는 코드가 훨씬 더 많았기에 시간이 지날수록 소위 말하는 스파게티 코드가 되어갔습니다. 혼자 개발하는 것이라면 상관 없겠지만, 여러 사람이 장기적으로 사용해야하는 프로젝트라면 이 코드는 아무도 손을 대지 못하는 코드일 것 입니다.
이렇게 AI를 통해 처음부터 끝까지 완성해보면서 AI를 어디까지 어떻게 사용해야 생산성이 올라가는지 나름의 기준과 깨달음을 얻을 수 있었습니다. AI는 프로토타입을 만들거나 아예 모르는 것을 간단하게 경험할때는 좋은 도구이자 멘토가 됩니다. 하지만 AI에게 내가 모르는 것을 계속 맡기다 보면 위 설명처럼 스파게티 코드가 되어버릴 것입니다. 따라서 보다 좋은 코드를 만들기 위해선 내가 알고 있는 것을 AI에게 시켜야 합니다. 코드 수백줄을 몇 분만에 입력하고 사용자에게 결과물을 보여줍니다. 이렇게 AI는 정말 타자가 빠릅니다(?). AI를 새로운 코드를 만들게 하고 그걸 확인하걸 사람이 하는게 아니라, 내 머릿속에 있는 코드를 AI에게 타자로 쳐달라고 해야합니다. 그렇게 되면 AI가 나오는 코드는 내가 아는 코드이기 때문에, AI가 생성했지만 관리가 가능한 생산성을 만들어 낼 수 있습니다.
AI를 이용해 플러그인 완성을 했기 때문에, 저는 이제 직접 개발을 하기로 했습니다. 아래는 조금은 단편적일 수도 있지만, 직접 개발하면서 만났던 느꼈던 점과 기억에 남는 에러를 정리해보았습니다.
[직접 개발하면서 무엇을 느꼈어? - 기능 개발] 코딩을 한 시간보다 플러그인 구조 이해와 테스트 코드 설계 시간이 정말 오래 걸렸습니다. 그래서 실제 개발한 시간의 비율을 생각해보면 화면 째려보기 55%, 코딩하기 45%로 실제로 코딩한 시간은 생각보다 적었습니다. 특히 메모 생성 기능을 만들 때, 인텔리제이의 에디터를 직접 가져와 통합 테스트를 할 수 있었습니다. 이렇게 하다보니 또 새롭게 알아야 할 지식이 생기고 어떻게 하면 좋은 테스트 코드를 만들 수 있을지 고민을 계속 하다 보니 시간은 가고 개발 진도는 나가지 않았습니다.
그래서 저는 좋은 테스트 코드를 짜는 것을 과감히 포기했습니다. 많이 고민하면 좋은 결과를 만들어낼 수 있을 것입니다. 하지만 시간과 체력은 유한합니다. 어느정도 고민을 했으면 생각에 확정을 짓고 행동을 하면서 그 고민이 맞았는지 틀렸는지를 알게 됩니다. 철저히 배우는 입장에서는 좋은 코드를 지향하기 위해 고민하되, 너무 생각 속에 얽매이면 행동에서 얻는 경험을 하지 못한다는 것을 알았습니다.
[직접 개발하면서 어떤 오류를 만났어? - 기능 개발] 가장 기억에 남는 오류는 기능과 화면을 모두 개발하고 통합 테스트를 할 때 나타난 "Note 저장 불가 문제"였습니다. 인텔리제이 플러그인 프레임워크에서는 데이터를 저장할 때, PersistentStateComponent를 이용해서 만든 레포지토리에 저장합니다. 플러그인 프레임워크는 정보를 xml 형태로 저장하고, 플러그인이 실행되면 이를 메모리로 띄워 관리하고 플러그인이 적절한 타이밍에 xml에 저장합니다. 이때 필요한게 state라는 필드입니다. 정보를 불러올 땐, loadState() 라는 메서드를 이용해 xml 데이터를 메모리로 가져와 state를 저장합니다. 그리고 state에 변경이 일어나면 플러그인은 데이터가 변경되었다고 판단하고 추후에 xml로 변경사항을 저장합니다.
저의 문제는 플러그인이 데이터가 변경됨을 감지하지 못해서 일어났던 문제였습니다. 저의 updateNote()의 기본 로직은, 사용자가 노트 내용을 바꾸면 내용이 수정된 Note 객체를 NoteState로 변환해 state에 바로 덮어 씌우는 방식이었습니다. 이때 state는 객체가 아예 새로 바뀌어 변경이 되었는지 감지를 못하게 되었고, 그렇기 때문에 변경 사항이 저장되지 않았던 거였습니다. 저는 이를 해결하기 위해 중간에 NoteStorageState라는 data 클래스를 만들어 필드로 NoteState를 받도록 했습니다. 이렇게 구현을 하면 NoteState를 완전히 덮어 씌워도 NoteStorageState 객체는 사라지지 않아 state가 변경됨을 감지할 수 있게 됩니다. 저는 이 부분이 기존에 사용했던 RDBS와 많이 달라 기억에 남는 오류였습니다.
[직접 개발하면서 어떤걸 고민했어? - 화면 리팩토링]
[3주 간의 오픈미션, 그리고 6주간의 프리코스를 마무리 하면서]
[]
ㅁ