📝 [Android/오르다 다이어리] 3년 전 레거시 리팩토링, 기능 완성 & UI/UX 개선 - Release 2 (v2.0.0) 후기
📌 지난 글:https://yujinius45.tistory.com/164
[Android/오르다 다이어리] 레거시 리팩토링 09 - HomeFragment 애니메이션 적용 & UI 개선
[Android/오르다 다이어리] 레거시 리팩토링 09 - HomeFragment 애니메이션 적용 & UI 개선 지난 글:https://yujinius45.tistory.com/163 이제 기능 미완성이었던 것도 완성되고 UI/UX 개선도 완료되어서 릴리즈를
yujinius45.tistory.com
🚀 3년 전 레거시 코드 리팩토링, 그리고 마침내 기능 완성
오르다 다이어리를 처음 만들었을 때는 기능이 많았지만, 구조적으로 정리가 덜 되어 있었고, UI/UX에 대한 고민이 부족했던 상태였다.
처음 앱을 만들었을 때는 "기능만 구현되면 된다!"라는 마인드로 개발했었다.
하지만 3년이 지난 지금 다시 프로젝트를 리팩토링하면서,
과거에 미처 고려하지 못했던 부분들이 많았다는 걸 깨달았고, 이를 하나하나 개선해 나갔다.
이번 Release 2 (v2.0.0)에서는 미완성 기능을 완성하고, UX를 개선하며, 코드 구조를 리팩토링했다.
이번 프로젝트를 통해 많이 배웠던 점들을 정리해 보려고 한다.
🔍 3년 전 코드에서 개선이 필요했던 점
v1.0.0에서는 기본적인 일정 관리, 일기 작성, 알람, 지도 메모 기능이 포함되어 있었다.
하지만, 실제 사용하면서 여러 문제점이 드러났다.
❌ 기존 코드에서 개선이 필요했던 부분
- UI/UX 문제
- 모든 화면이 개별적인
Activity로 구성되어 있어, 사용자가 홈으로 돌아가서 버튼을 눌러야만 다른 기능으로 이동 가능 - 화면 이동이 불편하고 비효율적이었으며, 처음 사용자가 홈 화면에서 어떻게 앱을 시작해야 하는지 명확하지 않았음
- 홈 화면이 정적 → 처음 앱을 실행한 사용자는 어떤 기능을 먼저 사용해야 할지 알기 어려움
- 모든 화면이 개별적인
- 기능 미완성
- MapMemo 기능이 완성되지 않음 → 앱을 종료하면 저장한 데이터가 사라지는 문제 발생
DiaryWritingFragment의 상태 유지 불가 → 화면 회전 시 입력한 내용이 사라짐
- 코드 구조 및 보안 문제
- DBHelper가 MainActivity에 종속되어 있음 → 독립적인 테스트 및 유지보수가 어려움
- SQL Injection 취약점 존재 → 사용자의 입력값이 SQL 문과 함께 실행되어 보안 위험이 있었음
- 직접 SQLite를 사용 → 관리가 어려워 유지보수성이 떨어짐
📌 리팩토링을 하며 배운 점
이번 프로젝트를 진행하면서 단순히 기능을 추가하는 것이 아니라, 어떻게 하면 유지보수하기 좋은 코드가 될까?를 고민하게 되었다.
내가 내 코드를 다시 보면서 개발을 할 때, 당장 기능이 동작하는 것보다, 이후 유지보수가 편하고 확장 가능한 코드를 작성하는 것이 중요하다는 것을 깨달았다.
1️⃣ 싱글톤 패턴을 적용하며 유지보수성이 높아진 사례
📌 기존 코드 문제점:
기존에는 DBHelper가 MainActivity에서 static 변수로 선언되어 있었다.
즉, 어떤 Fragment에서든 DBHelper를 사용하려면 MainActivity를 먼저 실행해야 했다.
📌 문제 발생 예시
public class MainActivity extends AppCompatActivity {
public static DBHelper mDBHelper; // MainActivity에 종속
}
이렇게 되면 DBHelper가 MainActivity에 강하게 결합되면서,
- 다른 클래스에서 MainActivity 없이 DBHelper를 사용할 수 없음
- MainActivity가 실행되지 않으면 DBHelper도 초기화되지 않음
- 테스트 코드에서 독립적으로 DBHelper를 사용하기 어려움
📌 해결 방법: 싱글톤 패턴 적용
public class DBHelper extends SQLiteOpenHelper {
private static DBHelper instance;
public static synchronized DBHelper getInstance(Context context) {
if (instance == null) {
instance = new DBHelper(context.getApplicationContext());
}
return instance;
}
}
📌 유지보수성이 어떻게 향상되었는가?
✅ DBHelper가 특정 Activity에 의존하지 않게 됨 → 어디서든 DBHelper.getInstance(context)로 호출 가능
✅ 테스트 코드에서 독립적으로 DBHelper를 사용할 수 있음
✅ 메모리를 절약하고 중복 인스턴스 생성을 방지함
2️⃣ MVVM 패턴 적용으로 개선
📌 기존 코드 문제점:
기존에는 Activity, Fragment 등 UI에서 UI 상태를 직접 관리하고 있었다.
다른 화면들은 DB에서 데이터를 로드해와서 상태 유지를 하고 있었으나 일기 작성 화면 같은 경우 화면이 회전되면 데이터가 초기화되는 문제가 있었다.
📌 문제 발생 예시
public class DiaryWritingFragment extends Fragment {
private EditText diaryContent;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
diaryContent = view.findViewById(R.id.diaryContent);
}
}
이렇게 하면 Fragment가 다시 생성될 때 데이터가 사라지는 문제 발생
📌 해결 방법: ViewModel을 사용하여 데이터 상태 유지
public class DiaryViewModel extends ViewModel {
private final MutableLiveData<String> diaryContent = new MutableLiveData<>();
public LiveData<String> getDiaryContent() {
return diaryContent;
}
public void setDiaryContent(String content) {
diaryContent.setValue(content);
}
}
📌 어떻게 개선되었는가?
✅ 화면 회전 시에도 데이터가 유지됨 → 사용성이 향상됨
✅ UI 로직과 비즈니스 로직이 분리됨 → 이후 추가 기능을 넣는다면 ViewModel에 추가해주면 됨
✅ 테스트 코드에서 ViewModel만 따로 테스트 가능 → 추후 기능이 추가된다면 진행할 수 있음
3️⃣ SQL Injection 방지 및 코드 관리가 쉬워진 사례
📌 기존 코드 문제점:
기존에는 사용자 입력값을 그대로 SQL 쿼리에 삽입하여 SQL Injection 취약점이 존재했다.
📌 문제 발생 예시 (보안 취약)
db.execSQL("INSERT INTO TODOLIST_TB (title, content) VALUES ('" + title + "', '" + content + "');");
만약 사용자가 "'); DROP TABLE TODOLIST_TB; --"을 입력하면, DB 테이블이 삭제될 수 있음
📌 해결 방법: Prepared Statement 사용
SQLiteDatabase db = getWritableDatabase();
String query = "INSERT INTO TODOLIST_TB (title, content) VALUES (?, ?)";
SQLiteStatement stmt = db.compileStatement(query);
stmt.bindString(1, title);
stmt.bindString(2, content);
stmt.executeInsert();
📌 어떻게 개선되었는가?
✅ SQL Injection이 방어됨 → 보안 강화
✅ 쿼리가 가독성 좋게 정리됨 → 이후 추가할 때는 좀 더 읽기 쉬워졌음
✅ 테스트 코드에서 SQL이 정상 동작하는지 검증 가능
🚀 결론 및 마무리
이번 리팩토링을 통해, 앱을 단순히 기능만 구현하는 것이 아니라, 유지보수성이 높은 구조로 만드는 것이 중요하다는 것을 배웠다.
특히, 싱글톤 패턴 적용, MVVM 구조 도입, UI/UX 개선, 보안 강화 등의 작업을 진행하면서 성장할 수 있었다. (이후 더 작업을 진행한다면 RoomDB 적용을 고려해볼 것 같다. )
예전에는 기능이 돌아가기만 하면 된다고 생각했지만, 이제는 코드의 확장성과 유지보수성까지 고민하게 되었다.
앞으로도 더 좋은 코드와 UI/UX를 고민하면서 발전해 나가야겠다!

🔗 https://github.com/yujin45/Team3_Orda_Diary/releases/tag/v2.0.0 (상세 변경 사항은 릴리즈 노트 참고)
Release 📌 Orda Diary Release 2 (v2.0.0) · yujin45/Team3_Orda_Diary
What's Changed [Refactor] targetSdk 34 적용 및 권한 변경 대응 by @yujin45 in #1 [Refactor] Activity → Fragment 전환 및 기능 개선 + DB 수정 버그 해결 by @yujin45 in #2 [Refactor] DiaryWritingFragment Configuration Chang...
github.com
'Android > 오르다 다이어리' 카테고리의 다른 글
| [Android/오르다 다이어리] 레거시 리팩토링 09 - HomeFragment 애니메이션 적용 & UI 개선 (0) | 2025.03.02 |
|---|---|
| [Android/오르다 다이어리] 레거시 리팩토링 08 - SQL Injection 테스트 및 해결 (0) | 2025.03.02 |
| [Android/오르다 다이어리] 레거시 리팩토링 07 - SQLite, MapMemo 기능 완성 (1) | 2025.03.02 |
| [Android/오르다 다이어리] 레거시 리팩토링 06 - DBHelper 싱글톤 패턴 적용 (0) | 2025.03.01 |
| [Android/오르다 다이어리] 레거시 리팩토링 05 - Configuration Change 대응 (ViewModel 적용) (0) | 2025.03.01 |