[util] 대용량 클래스 자동 리팩토링 노하우
이전 포스팅에서 이어집니다. https://blog.naver.com/devramyun/224076564029
[20251115][util]Flutter의 클래스에서 variables, constructor, method 개수 세는 Python 스크립트 + 클래스 part로 쪼개기 지금 제가 프론트엔드를 맡고 있는 건 아니지만, 한 때 프론트… 지금 제가 프론트엔드를 맡고 있는 건 아니지만, 한 때 프론트…
- 각 파일 클래스의 변수, 메소드, 생성자를 starting line과 ending line과 함께 정리한다.(Python정리스크립트)
- 변수, 메소드, 생성자를 어떻게 묶어서 리팩토링할지 정한다.
- 묶기로 결정한 것들끼리 파악한 줄 수를 토대로 복사해서 옮겨준다.(python복사스크립트)
- 원본파일에서 복사되지 않고 남은 것들만 복사해서 new_원본파일에 복사해서 옮겨준다.(python복사스크립트)
- old_원본파일을 삭제한다.
1
2
3
4
5
6
7
8
9
10
11
12
1. 각 파일 클래스의 변수, 메소드, 생성자를 starting line과 ending line과 함께 정리 (extract_methods_with_lines.py)
2. 변수, 메소드, 생성자를 어떻게 묶어서 리팩토링할지 정한다 (refactoring_analysis.json)
3. 새 extension 파일들 생성 - Python 스크립트로 카테고리별로 코드 복사해서 새 파일 생성:
- original_class_canvas.dart
- original_class_photo_thumb.dart
- original_class_theme_asset.dart
- original_class_book_save.dart
- original_class_product.dart
- original_class_utils.dart
4. 메인 파일에 새 part 선언 추가
5. 빌드 테스트 - 새 파일들이 정상 작동하는지 확인
6. 성공 시 기존 _1~_6 파일 삭제
좀 더 일반화된 프로세스는 다음과 같은 노하우로 정리하겠습니다.
1단계: 코드 분석 및 메타데이터 추출
- 클래스의 모든 멤버(변수, 메소드, 생성자)를 자동으로 추출
- 각 멤버의 시작 줄 번호와 끝 줄 번호 기록
- JSON/CSV 등으로 구조화된 데이터로 저장
2단계: 리팩토링 전략 수립
- 관련 기능별로 멤버들을 논리적 그룹으로 분류
- 각 그룹의 책임과 역할 정의
- 새로운 파일/클래스 구조 설계
3단계: 새로운 구조로 코드 분리
- 원본 파일은 건드리지 않고, 새 파일만 생성
- 줄 번호 정보를 활용해 자동으로 코드 추출 및 복사
- 카테고리별로 별도 파일/모듈/클래스로 분리
4단계: 통합 및 의존성 업데이트
- 메인 파일에 새 모듈 import/include 추가
- 필요한 설정 파일 업데이트 (예: part 선언, module exports 등)
5단계: 검증 및 테스트
- 빌드/컴파일 성공 확인
- 기존 기능이 정상 작동하는지 테스트
- 문제 발견 시 쉽게 롤백 가능 (원본 보존됨)
6단계: 레거시 코드 정리
- 검증 완료 후 기존 파일 삭제
- 버전 관리 시스템에 커밋
🔑 핵심 원칙
- 원본 보존: 새 파일만 생성, 원본 수정 금지
- 자동화: 스크립트로 반복 작업 자동화
- 점진적 접근: 한 번에 하나씩 검증하며 진행
- 안전 장치: 언제든 롤백 가능하도록 구성
우리의 경우를 계속 진행해보죠.
코드 라인을 같이 세는 스크립트입니다. https://gist.github.com/southglory/4353638679bc37066022cb3ccc075a6c
Dart/Flutter 파일에서 변수, 생성자, 메소드를 줄 번호와 함께 추출하는 스크립트 Dart/Flutter 파일에서 변수, 생성자, 메소드를 줄 번호와 함께 추출하는 스크립트 - extract_methods_with_lines.py Dart/Flutter 파일에서 변수, 생성자, 메소드를 줄 번호와 함께 추출하는 스크립트 - extract_methods_with_lines.py
결과입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
{
"file": "ai_book_provider_1.dart",
"total_variables": 0,
"total_constructors": 0,
"total_methods": 18,
"variables": [],
"constructors": [],
"methods": [
{
"name": "setCanvasList",
"start_line": 6,
"end_line": 14
},
{
"name": "canvasBodyList (getter)",
"start_line": 17,
"end_line": 20
},
{
"name": "getOverImageSize",
"start_line": 23,
"end_line": 40
},
{
"name": "calcPagePhotoCountList",
"start_line": 43,
"end_line": 64
},
{
"name": "cancelAll",
"start_line": 66,
"end_line": 68
},
{
"name": "updateThumbVer",
"start_line": 71,
"end_line": 73
},
{
"name": "getThumbUrl",
"start_line": 77,
"end_line": 80
},
{
"name": "thumbUrlCover",
"start_line": 82,
"end_line": 100
},
{
"name": "thumbUrlPage",
"start_line": 85,
"end_line": 100
},
{
"name": "calendarFThumbUrl",
"start_line": 102,
"end_line": 107
},
{
"name": "leftPage",
"start_line": 110,
"end_line": 876
},
{
"name": "rightPage",
"start_line": 878,
"end_line": 896
},
{
"name": "resizeMaxSize",
"start_line": 900,
"end_line": 916
},
{
"name": "isFirstHalfPage",
"start_line": 919,
"end_line": 922
},
{
"name": "isLastHalfPage",
"start_line": 924,
"end_line": 927
},
{
"name": "isFirstHalfPageCurrent",
"start_line": 929,
"end_line": 932
},
{
"name": "isLastHalfCurrent",
"start_line": 934,
"end_line": 937
},
{
"name": "getThemeXaml",
"start_line": 940,
"end_line": 1045
}
]
}
#flutter #refactoring #줄수세기 #대용량클래스자동리팩토링노하우
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.