# K4 피어세션
| K001 | K005 | K009 | K036 | K032 | K051 |
| ---- | ---- | ---- | ---- | ---- | ---- |
| 구윤경 | 김성환 | 김영훈 | 윤형식| 신재혁 | 장성희|
## 🍖 구현 방법 Overview
### K001
- 캔버스를 사용하지 않고 동적으로 뷰를 생성하는 식으로 구현
- `Plane` 을 MVC 중 M으로 두고, 액티비티/커스텀 뷰에서 이벤트 처리
- onPause시 상태 저장, onCreate시 상태 불러오기
### K005
- 각각의 데이터 타입에 해당하는 커스텀 뷰를 정의하여 FrameLayout에 표시
- `Plane` 클래스에서 데이터를 조작하고 이벤트를 발행
- 레이아웃을 LayerFragment, PlaneFragment, AttrFragment로 나누고 각각의 Fragment마다 필요한 이벤트를 리스닝
- [프로젝트 구조](https://github.com/boostcampwm-2021/kotlin-p2-canvas/pull/430)
### K009
- FrameLayout에 타입에 따라 각각 View를 생성
- AAC 뷰모델을 이용하여 모델 데이터를 저장
- Activity에 controller 기능을 주로 구현하고 MainActivity가 가지고 있는 PlaneView에 View를 표시하는 기능 구현
- 구분자를 이용하여 String 타입으로 데이터 직렬화
- Drawing은 경로좌표를 ArrayList로 저장하고 캔버스의 drawPath를 이용하여 ImageView의 배경으로 넣어줌
### K032
- Canvas를 사용하지 않고 ConstraintLayout에 View를 생성하여 추가하는 방식으로 구현
- View에 start, top을 parent에 chain을 연결, left, top margin을 통해 좌표를 입력
- 사각형 Drag and Drop을 멀티터치가 아니라 LongClick을 이용하여 동작
### K036
- M: `Rectangle`, `Image`, `Text` ...
- V: `Activity`
- C: `Plane`
- 모델에 뷰를 생성하기 위한 데이터를 보관
- `Plane`에서 모델에 요청하여 상황에 맞는 뷰를 `Activity`에 전달하여 추가함
- `Activity`에서 `LiveData`의 변동이 있거나 이벤트가 발생할 때 `Plane`클래스의 메서드를 실행
### K051
- MainActivity가 controller와 view의 역할을 하고, PlaneViewModel이 model 역할
- 캔버스는 사용하지 않고 사각형과 사진은 imageview, 텍스트는 textview로 동적으로 생성
- 생성한 component들을 담는 리스트와 속성들을 livedata를 사용해서 그 값들이 바뀌면 뷰에 반영하도록 구현
- 상태 저장은 onPause, 상태 복원은 onResume에서 진행, 상태 저장에 필요한 클래스들은 @Serializable 어노테이션 달아서 직렬화
## 🤔 궁금한 점
### 클래스 간의 역할 분리
MainActivity 하나만 사용한다면 클래스가 너무 커져서 관리가 힘들어지고, 여러 클래스로 작업을 나눈다면 객체 간의 복잡한 상호 작용을 컨트롤하는데 문제가 있다. 어떻게 하면 클래스의 관심사를 분리하면서 상호 작용을 잘 관리할 수 있을까?
=> 어려운 문제💦
### `Rect`, `Image`, `Text`, `Drawing` 모델 클래스의 설계 방식
❓ 각 모델들의 구조를 어떤 방식으로 구현했는지
❓ 모델에서 구현한 기능의 범위와 그 기준
❓ 새로운 모델을 추가할때 코드의 변경점이 많았는지
1. 각각의 데이터 타입을 Shape의 서브 클래스로 구현
- 데이터 타입의 역할은 자신의 속성을 변경하는 정도로만 제한
- 최대한 안드로이드 SDK나 다른 클래스에 의존성이 없도록 구성
- 객체 생성은 Factory에 위임
2. Model 내 공통된 동작을 넣는지?
3. Model이 클래스로 정의됐을 경우 entity로 부름
4. 모델에서의 공통된 동작들은 뷰나 컨트롤러에 의존성이 없이 수행할 수 있는 메서드로만 구성
### 터치 관련
❓ 드로잉 터치와 캔버스 레이아웃 터치를 어떻게 구분했는지?
❓ 멀티터치 이벤트 구현 어떻게 했는지
- ACTION_MOVE 도중 false를 return 하여 다른 이벤트 발생 방지(추정)
### 직렬화 과정
❓역직렬화 할 때 데이터의 타입을 어떻게 구별했는지
- string 형식으로 만들어서 구분자로 식별
- `@Serailizable` 어노테이션, Super class를 sealed class로 구현
### Canvas -> RecyclerView 클릭 동작 구현 방식
- Observer 방식 사용
### 5단어 텍스트 추출
❓ 누가누가 제일 짧게 썼나,,
- split -> random -> subList/slice -> joinToString
### 위치, 크기 EditText 구현
❓ 커스텀해서 만들었는지, 아니면 화살표 없이 했는지
- 기본 형태 (화살표 없이)
- 커스텀으로 위/아래 화살표 버튼 추가하는 식으로 구현
### 드로잉 구현
- 좌표 리스트를 가지고 캔버스에 drawPath를 이용하여 경로를 그린 뒤 ImageView에 비트맵을 넣어주는 방식으로 구현
### 상태 저장 및 불러오기 시점
- onPause/onStop
- onCreate
### 임시 뷰 구현 방식
오브젝트를 이동시킬 때 보여주는 임시 뷰는 오브젝트 타입에 따라 다른 뷰를 보여줘야 한다.
뷰 인스턴스 자체를 복제하는 방식은 사용할 수 없다고 하는데 어떻게 하면 상황별로 다른 뷰를 보여줄 수 있을까?
- Shadow Builder
[Drag and Drop 튜토리얼✔](https://www.raywenderlich.com/24508555-android-drag-and-drop-tutorial-moving-views-and-data#toc-anchor-002)
### 텍스트뷰
- `TextView`
- `drawText`