초청 특강 Recommendation Systems : Concepts, Techniques, and Research Results
키워드 : 추천 시스템, 머신러닝
소개 : 최근 온라인 비즈니스에서 크게 각광을 받고 있는 추천 시스템 기술에 대해서 다룹니다. 먼저, 추천 시스템의 기본 개념, 최신 기술, 응용에 대해서 설명하고, 머신 러닝 기술을 이용하여 추천 시스템을 어떻게 실현하는가에 대해서 설명합니다. 또한, 최근 제안된 무관심 아이템이라는 새로운 개념을 제시하고, 이 개념을 통하여 기존 추천 시스템의 정확도가 어떻게 개선 되는가에 대해서 다양한 관점에서 논의합니다. 또한, 추천 시스템에서 다루는 그래프 데이터를 효과적으로 저장하는 새로운 그래프 엔진 RealGraph를 소개하고, 이를 통하여 추천 시스템의 성능을 크게 개선시킬 수 있음을 설명합니다.
추천 시스템은 예전 데이터가 많은 업체만 하던 것을 작은 업체들도 시도하고 있음.
추천 기술은 몇가지 기반 기술이 있음
Content-based filtering은 내 데이터만 봄
Trust-based 는 트러스트라는 관계 데이터가 필요함. 주변인 추천 같은?
Collaborative filtering (CF)는 나와 취향이 비슷한 이웃을 찾고 내가 모르는 아이템을 얼마나 좋아하는지 예측함. Rating Matrix 사용
1단계 취향유사도 계산은 Pearson Correlation Coefficient based Collaborative Filtering(PCC) 사용
2단계 내가 얼마나 좋아할지는 Heuristic based methods 사용
일반 평균, 유사도에 따른 가중치를 주거나 각 이웃의 평균치도 고려함
위 단계가 Matrix Factorization, Tensor Factorization 이며 점차 딥러닝으로 넘어가는 중
Social network analysis, Deep Learning 등
정확도를 높이기 위해 Unrating 개념 추가
Unrating은 존재를 모르거나 알고도 관심이 없는 경우도 있음(부정적인)
기존 선호도로 쓰이던 부분을 사전/사후 선호도를 나눔.
Uninteresting item 찾는게 과제임.
기존 사용자가 좋아하는 것만 추천했지만 한양대에서는 싫어하는 것까지 고려하려 함.
작은 Interesting 그룹과 큰 Uninteresting 그룹이 필요함
깃'깔나는 Git 워크플로 알아보기
키워드 : 개발 방법론, 생산성
소개 : 주요 Git 워크 플로우의 이해 각자 상황에 적합한 Git 워크플로를 찾는 팁
Git flow
메인브랜치 : master, develop (master에 버전 태그 추가)
서포팅브랜치 : feature, release, hotfix (필요시 생성/제거)
hotfix는 마스터에서 브랜치 생성
Github flow
master 브랜치는 항상 배포 가능한 상태 유지
topic 브랜치 (Git flow의 feature) 는 기능 설명이 명확하게 작명하고 merge시 pull request 사용
topic 브랜치는 CI 빌드 통과해야 함.
배포는 merge 순간 bot을 통해 진행함.
매우 빈번하게 배포함.
Gitlab flow
Git flow는 너무 복잡, Github flow는 너무 간단하게 생각되어 나옴.
Gitlab flow - 지속적인 배포가 어려울때
master에서 production 브랜치로 머지 후 배포
Gitlab flow - 환경별 배포시
Gitlab flow - 릴리즈 소프트웨어시
Commit과 Push는 자주 할것
Merge Request or Pull Request 는 완료 전이라도 논의 및 피드백 받을 목적으로도 사용.
merge 전엔 테스트 필요
NHN Edu사례
단기간,
장기간 배포 일정(코드네임 부여)
rebase 로 정리함.
QA 수정사항은 각 프로잭트 브랜치에서 추가함.
Release 브랜치 사용안함.
배포 후 각 프로젝트 브랜치에 rebase
각 프로젝트 rebase시 conflict이 발생할 수 있고, 그 경우가 복잡할 경우 프로젝트 브랜치 재생성하고 cherry-pick 함.
hotfix 는 Pull Request 로 코드 리뷰와 테스트만 하고 배포는 직접 진행함.
업무프로세스
Pull Request 시 사내 메신저 연동
Pull Request 통과 조건을 부여하여 통과시만 merge 가능(github 설정)
- 코드 리뷰 승인시 조건
- 테스트 옵션 – Unit Test와 Sonarqube
(Sonarqube 는 테스트 결과와 별개로 패스되므로 참고만 함.)
- develop에 최신 master 적용여부 체크
Pull Request 생성시 Jenkins 빌드 및 Unit Test연동
Sonarqube 결과도 댓글로 달림
Github Pull Request + Jenkins + Sonarqube
실용적인 프런트엔드 테스트 전략
키워드 : 프런트엔드, 테스트, 아키텍처
소개 : 프런트엔드 코드는 사용자 환경과 밀접하게 연결되어 있고 복잡한 시각적 요소를 다루기 때문에 테스트를 자동화하기가 어렵습니다. 본 세션에서는 수년간 다양한 방식으로 테스트를 작성해 온 경험을 공유하며, 최신 테스트 도구를 사용해서 실용적으로 프런트엔드 코드를 테스트하는 방법을 설명합니다.
테스트는 왜 하는가?
대부분 개발자가 테스트 코드 작성 후 자동화함
그 이유는 Confidence 때문임.
백엔드의 경우 테스트는 https 요청에 대한 응답이 대부분.
프런트엔드는 마우스 키보드 등 입력과 시각적 정보 출력하고 코드로 확인하기 어려움.
입력 : DOM Event, Routing IO
출력 : Html, css 비교 등
결과 확인
\1. Html 비교
\2. 스냅샷 테스트 : 에전 테스트 결과와 파일 비교. Jest 사용
하지만 html 확인만으로는 테스트 결과에 신뢰를 줄 수 없음
구현상세테스트 vs 동작테스트로 테스트 성향을 구분.
위의 결과 확인은 구현상세테스트 성향임.
동작테스트로시각적 회귀 테스트진행함. (회귀란 기존 버전과 비교하기 떄문)
하지만 픽셀 단위 비교도 브라우저 렌더링 등에 영향을 받음
그리고 커맨드 라인에서 테스트 결과 확인이 어려움.
테스트 실행 단위별 이미지 파일 히스토리 관리 필요.
결정적으로 시각적 테스트 전문 도구(유료)
Applitools, Percy, Chromatic
시각적 테스트는 속도 문제와 테스트의 장점 중 하나인 문서화 기능을 처리하기 어려움
이로 인해 TDD 진행도 어려움.
그리고 단일 테스트에 영향 주는 요소 많음.
시각적 테스트 vs 기능적 테스트
기능 테스트시 시각적 요소 의존성 제거해야 함
JQuery의 Selector들 같은 경우가 이에 속하며, 이를 제거하기 위해 data 속성을 이용해 test-id 등을 부여할 수 있음.
세션설명 : 변화의 시대 : 안드로이드 앱 어떻게 개발할 것인가? 안드로이드는 끊임없는 OS 버전 뿐만아니라 개발 언어, 구조, GUI등 많은 부분에서 다양항 변화가 시도되고 있습니다. 많은 방법론과 라이브러리가 제공되다보니 어떤 전략과 기준으로 개발해야하는지 혼돈스러울 때가 많습니다. 네이버 앱의 개편에 적용한 기술 사례와 방법론을 통해서 효율적인 앱 개발애 대해서 얘기하고자 합니다.
세션설명 : 구글이 Android Architecture Component 의 ViewModel 을 발표하면서 다양한 시각의 MVVM 구현이 제시되고 있습니다. 여전히 많은 사람들이 혼동하는 MVVM 구현에 대해 올바른 안드로이드 MVVM 구현을 공유하고자 합니다. 이를 위해 안드로이드에서 어떠한 기본 작업이 선행되어야 하는지, 다양한 문제 상황에 대한 해결책에 대해 알아보고 MVVM 이 Grab 에서 어떻게 활용되고 있는지 알아보겠습니다.
안드로이드 MVVM의 올바른 구현과 그랩에서 사용하고 있는 아키텍처 소개.
국내 안드로이드 MVVM의 이해의 일반적인 오해 및 올바른 이해
안드로이드 MVVM에서 DataBinding 적용시 문제점들 및 그랩의 해결방안
그랩의 협업을 위한 아키텍처 (MVVM + 단일 액티비티 with Node)
Q & A
04. 디자인 1도 모르는 개발자, UX디자인 시작하기
발표자 : 최유리 (N Tech Service / NTS UX디자인실 설계&콘텐츠운영디자인)
세션설명 : 통계에 따르면 2018년 1분기에는 앱스토어에 약 220만개, 구글플레이에 약 380만개의 앱이 등록되어 있다. 이 치열한 경쟁속에서 사용자에게 오래도록 사랑받는 앱이 되려면 UX디자인은 선택이 아닌 필수다. UX디자인은 디자이너만의 영역이 아닌 개발팀 모두가 함께 만들어내야하는 가치이다. UX디자인에 관심을 갖고 참여한 개발자가 서비스 성공에 어떤 역할을 해 내는지 알아보자.
개발자의 UX 디자인 참여의 필요성과 실제사례 후기
UX 디자인이란?
UX 디자인에 참여함으로 얻을 수 있는 것들
UX 디자인시 고려해야 하는 것들
05. Material Design의 철학과 적용 사례
발표자 : 양찬석(구글 코리아 / Partner Developer Advocate) 임성혁 (구글 코리아 / Developer Ecosystem Program Manager)
세션설명 : 코틀린을 안드로이드에 적용하기 위해서는 안드로이드에 맞는 모듈의 개발, 거버넌스, 코딩 패턴, 디자인 패턴 등의 전략적 고려 사항이 필요합니다. 네이버앱에 코틀린을 적용한 경험을 토대로, 기존 프로젝트(또는 신규 프로젝트)에 코틀린을 적용할 때 반드시 고려해야 할 사항과 적용하면서 나온 사례를 통해서 최적화된 적용 방법을 공유합니다.
세션설명 : 안드로이드의 앱들은 현재 프로 가드를 통해서 보호되고 있고 향후로는 구글이 작성한 R8으로 대체할 예정에 있다. 난독화 도구들을 써봤지만 막연히 쓰는 경우가 많은데 난독화 도구가 어떤 일을 하고 있고 기본적인 메커니즘이 어떻게 구현되어있는지 프로가드, R8은 무엇인지, 그리고 안드로이드 빌드 과정에 어떻게 통합되는지를 살펴보는 시간을 갖는다.
runBlocking, CoroutineScope, GlobalScope 안에서 동작해야 함
CoroutineScope, GlobalScope
CoroutineScope
가장 기본적인 Scope
Thread 형태를 지정(Main, Default, IO 등을 지정)
CoroutineScope(Main, Default, IO, ...)
launch, async 등을 통해 scope를 실행
중요한 점
Activity/Fragment LifeCycle에 따라야 함
onDestroy() : cancel하도록 코드 추가
CoroutineScope(/* thread type */).launch { } 로 실행
launch { }의 return job의 동작을 지정 가능
join() : scope 동작이 끝날때까지 대기하며, suspend에서 호출 가능
cancel() : 동작을 종료하도록 호출
start() : scope가 아직 시작하지 않을 경우 start, scope의 상태를 확인
CoroutineScope의 interface 정의
@Suppress("FunctionName")
publicfunCoroutineScope(context:CoroutineContext):CoroutineScope=ContextScope(if (context[Job] !=null) context else context +Job())
publicinterfaceCoroutineScope {
@Deprecated(level=DeprecationLevel.HIDDEN, message ="Deprecated in favor of top-level extension property")
publicval isActive:Boolean
get() = coroutineContext[Job]?.isActive ?:true/** Context of this scope. */publicval coroutineContext:CoroutineContext
}
CoroutineScope 활용 - Delay 대신 job.join()
@Testfuntest() = runBlocking {
val job =CoroutineScope(Dispatchers.Unconfined).launch { // 새로운 scope를 생성하고 default로 launch. (Work Thread로 동작함)//launch에서 CoroutinScope에서 지정한 default Thread로 사용. (별도 지정 없으면 부모를 따라감)
delay(300L)
println("World!")
}
pirntln("Hello,")
// delay(500L) <-- 이 부분은 CoroutineScope에서 네트워크 같은 처리시 의미가 없어짐.
job.join() // join()으로 default thread 종료하기 전까지 대기
}
GlobalScope
전역에서 돌아가야할 경우
CoroutineScope 상속 받아 구현
Demon, Application 등에서 사용
Application의 lifetime에 따라 동작하는 scope에서 사용 추천
GlobalScope는 Dispatchers.Unconfirned(worker thread) 에서 동작
GlobalScope.launch(/* thread type */) { } 로 실행.
위에서 thread가 이미 지정되어 있어 launch에서 쓰레드 타입을 지정. 기본은 Default임.
GlobalScope API 코드
object GlobalScope :CoroutineScope {
/** * @suppress **Deprecated**: Deprecated in favor of top-level extension property*/@Deprecated(level=DeprecationLevel.HIDDEN,
message ="Deprecated in favor of top-level extension property")
overrideval isActive:Boolean
get() =true/** * Returns [EmptyCoroutineContext].*/overrideval coroutineContext:CoroutineContext
get() =EmptyCoroutineContext
}
GlobalScope 사용 예
fun ReceiveChannel<Int>.sqrt():ReceiveChannel<Double> =GlobalScope.produce(Dispatchers.Unconfined) {
for(number inthis@sqrt) {
send(Math.sqrt(number.toDouble()))
}
}
// 사용하는 코드
launch {
val request = service.getPosts()
val response = request.await()
if (response.isSuccessful) {
// Pass in the response.body() to your adapter
} else {
toast("Error ${response.code()}")
}
}
Q & A
Q : Dispatcher.Unconfined는 부모 코루틴 컨텍스트에서 코루틴을 실행하고 제일 처음 suspend 함수 이후에는 해당 suspend에서 사용했던 쓰레드에서 동작하는 걸로 알고 있음. 예제에서 Unconfined를 쓰셨던데 안드로이드에서 활용 가능한 부분이 있는지?
A : 테스트 코드에서 활용하기 위해 넣은 거임. UI Thread(Main Thread)에서 활용하기 위해 넣어야 함.
Q : Rx를 안쓰고 Coroutine 기반 라이브러리들로 코드 베이스를 변화시키거나 변화시킬 계획인지?
A : Coroutine을 조금씩 적용할 예정이며 Retrofit을 사용하기 위해 새로 팔 예정임. onClick에 먼저 적용 중.
세션설명 : 안드로이드에서 웹컨텐츠를 렌더링 하는데 많이 사용하고 있는 웹뷰의 동작 원리 대한 설명과 이를 바탕으로 한 웹 성능 최적화를 위한 여러가지 툴 사용법을 설명하는 세션입니다.
목차 :
1. History of Android WebView
2. Summary of how browsers work
3. Rendering pipeline overview
4. How chromium makes a frame?
5. VSync aligned touch input & frame output
1. Android WebView overview
1.1 안드로이드 웹뷰란?
안드로이드에서 제공하는 뷰
사용하는 케이스
안드로이드 기본 브라우저에서 사용
앱에서 거의 대부분의 배너 광고에서 사용
웹(HTML) 기반 앱에서 사용
안드로이드 네이티브 뷰와 함께 사용
혹자는 안드로이드에 숨어있는 제 3의 플랫폼이다 라고도 함.
1.2 안드로이드 웹뷰의 역사
J(젤리빈 / 4.1 / API 16~18) 이하
custom WebKit-based "classic" WebView
K(킷캣 / 4.4 / API 19)
Chromium 30/33-based WebView
L(롤리팝 / 5.0 / 21) 이상
Unbundled Evergreen WebView
1.3 안드로이드 웹뷰와 파편화
안드로이드 제조사에서 경쟁적으로 WebKit을 Customization
안드로이드 버전별 서로 다른 WebKit 사용
Android 4.3 이전 버전은 WebKit 기반의 렌더링 엔진을 사용
Android 4.4 부터는 Blink 기반의 렌더링 엔진으로 교체
현재는 사용자 웹뷰 업데이트 유무에 따라 서로 다른 버전을 사용 (앱 업데이트 없이도 이슈 생길 수 있음)
1.4 WebKit 브라우저 엔진의 역사
KHTML, KJS(1999.05 ~)
Apple Forks KHTML, KJS in 2001 -> WebKit (2001 ~), Open Source in 2005
세션설명 : Koin으로 DI를 하고 AAC, Rx를 조합한 MVVM 패턴에 대하여 이야기 하고자 합니다. 어째서 효율적인지 Testable한지를 함께 고민 해 보고 더 나은 구조를 향한 이야기를 나누어 보았으면 합니다.
목차 :
1. 발표 동기
2. AAC를 소개(나온 배경등)
3. MVVM을 소개(livedata,ViewModel과 엮으며)
4. Rx를 소개 (KickStarter를 참고하여)
5. Koin을 소개(DI를 간단하게 설명하며)
6. 위의 모든 것을 조합 한 예제 설명
7. 효율적인 부분 고민이 되는 지점등 같이 이야기해볼만 한 부분들을 화두로 던져 소통
8. 테스트코드 또한 위와같이 진행
9. 마무리.
Android 코드 아키텍쳐
MVC
MVP
MVVM
with Clean Architecture
with RFP(rxJava2)
with AAC, Koin
with Spek
MVI
VIPER
etc...
MVVM
with CleanArchitecture
with RFP (rxJava2)
with AAC, Koin
with Spek
with에 적힌 라이브러리, 프레임워크는 간단히 설명하기로 함.
why MVVM?
MVP로 충분히 잘 구현해도 서비스 운영을 하면서 아래의 문제들이 생김.
요구사항, 비즈니스 로직 늘어남 -> 코드량, 복잡성 높아짐 -> 유지보수성, 테스트 용이성 하락
what MVVM?
(MVVM에 대한 개인적인 견해이므로 다른 의견이 있을 수도 있음.)
Model, View, ViewModel로 구성되어 있는 패턴
ViewModel은 View의 추상화
View와 ViewModel은 n:m 의 관계
View는 ViewModel에 bindable함
ViewModel은 View의 추상화
ViewModel은 View의 상태와 행동이 추상화 된 것
ViewModel은 View의 input과 output이 명시되어 있는 인터페이스 (같은 input 엔 항상 같은 output 이라 테스트에 용이함)
output은 View의 상태와 Rooute로 나뉨
View와 ViewModel은 n:m 의 관계
하나의 View가 여러 ViewModel에 조합 가능
하나의 ViewModel이 여러 View에 적용 가능
재 사용성이 용이함.
View는 ViewModel에 bindable함
사용자 행동에 의해 입력 받았을 때 (View -> ViewModel)
사용자 행동에 따른 View의 상태를 변경시켜야 할 때 (ViewModel -> View)
모든 로직은 binding되는 시점에 결정됨.
장점
View에 대한 의존성이 제거되어 효과적으로 역할과 책임을 나눌 수 있음.
ViewModel 단독으로 테스트가 가능함으로 테스트 용이성 증가.
binding 되는 시점에 input 대비 output을 산출하는 로직이 정해지기 때문에 개발자가 상태 관리해야 하는 위험 줄여줌.
Databinding을 통해 보일러 플레이트 코드 줄일 수 있음.
How MVVM?
발표자가 생각한 android에서 MVVM
LiveData는 라이프싸이클 처리 등의 문제로 사용.
ViewModel 윗단 Model단부터는 Clean Architecher가 도입함.
Rx로 비동기 처리함.
Activity/Fragment/something은 View의 상태 변화를 제외한 Router역할+ViewModel과 View를 binding하는 역할 수행함.
beforeEachTest {
ArchTaskExecutor.getInstance().setDelegate(object:TaskExecutor() {
override fun executeOnDiskIO(runnable:Runnable) {
runnable.run()
}
override fun isMainThread():Boolean {
return true
}
override fun postToMainThread(runnable:Runnable) {
runnable.run()
}
})
}
afterEachTest {
ArchTaskExecutor.getInstance().setDelegate(null)
}
MainViewModelSpec
object MainViewModelSpec :KoinSpek({
beforeEachTest { ... }
afterEachTest { ... }
lateinit var userName:String
val viewModel:MainViewModel by inject { parametersOf(userName) }
val getUserData:GetUserData by inject()
Feature("MainViewModel spec") {
Scenario("유저가 화면에 들어오면 검색한 유저의 프로필,저장소 데이터가 정상적으로 보여야 한다") {
Given("검색하려는 유저의 이름은 omjoonkim이다"){
userName = "omjoonkim"
}
Then("화면에 검색한 유저의 데이터가 정상적으로 나타난다") {
assertEquals(
getUserData.get(userName).blockingGet(),
viewModel.output.refreshListData().value
)
}
}
Scenario("유저 프로필을 클릭하면 유저의 프로필 화면으로 이동되어야 한다") {
When("프로필을 클릭 했을 때") {
viewModel.input.clickUser(
viewModel.output.refreshListData().value?.first
?: throw IllegalStateException()
)
}
Then("해당 유저의 프로필 화면으로 이동 된다") {
assertEquals(
viewModel.output.refreshListData().value?.first?.name
?: throw IllegalStateException(),
viewModel.output.goProfileActivity().value
)
}
}
Scenario("홈버튼을 클릭하면 화면이 정상적으로 종료되어야 한다.") {
When("홈버튼을 클릭 했을 때") {
viewModel.input.clickHomeButton()
}
Then("화면이 정상적으로 종료 된다.") {
assertEquals(
Unit,
viewModel.output.finish().value
)
}
}
}
})
DI for Test
test_modules
val testModule = module {
single(override=true) {
TestSchedulerProvider() asSchedulersProvider
}
single(override=true) {
TestDummyGithubBrowserService() asGithubBrowserService
}
}
val test_module =listOf(myModule, testModule)
Spek을 이용한 테스트 코드 작성
Feature
Scenario
Given
When
Then
More... + TMI
Dagger2 vs Koin
Heavy vs light
Dependency Injection vs ServiceLocator
CompileTime vs RunTime
Spek과 Koin의 호환성
Spek + Koin을 사용하려면 추가적으로 작업해야 하는 코드들 있음.
(Spek 구동방식과 Koin을 사용하는 방식이 서로 충돌되기 때문)
개선의 여지 + 아쉬운 점
Databinding이 kotlin에 100% 호환되지 않음 (람다 함수를 xml에서 값으로 지정해줄 수 없음)
Router
Presentation module 분리
Q & A
Q : MVVM 적용시 피곤한 점은?
A : 기존 뱅크샐러드의 경우 MVP 베이스임. 그래서 MVP에 Koin 추가나 코드 수정해야 했음.
팀원 협의에 대한 부분. Rx나 MVVM 러닝커브가 높은 점.
Q : 클린 아키텍쳐면 presentation, domain, entity, data 4가지 레이어 정의를 보면 presentation이 ui에 해당되는데 왜 presentation에 data와 같은 레벨로 하고 ui는 remote로 한건지?
A : ui가 remote라기 보다는 ui와 remote는 서버에서 데이터를 받아오는가장 바깥 레이어로 생각하면 됨.
Q : Koin의 runtime error가 compile time error 대비 장점은?
A : Dagger는 적용하기 어려웠음. 선수지식과 많은 코드가 필요했음. Compile error시 어디서 에러가 나는지 찾아야 했음.
Koin을 하면서 코드 스타일로 의존성 주입을 하면서 에러 찾기가 편함.
복잡한 서비스의 경우는 Dagger, 심플한 경우 Koin이 괜찮아 보였음.
Q : TDD가 아닌 BDD를 한 이유는?
A : TDD와 BDD의 가장 큰 차이는 구현 대신 행동 즉 행위를 테스트하는 것임. Functional Programming 관점에서 행동 기반이 맞다고 생각했음.
Q : Model의 수에 따라 Mapper의 수도 지속적으로 증가하는데, Mapper가 특별한 경우가 아닐 땐 1:1로 매핑되고 Koin으로 바인딩 해주는 것들이 보일러 플레이트로 느껴짐. 이런 코드를 좀 더 줄일만한 아이디어는?
A : 진정한 클린 아키텍쳐라면 레이어 별로 테스트가 가능해야 하고, Mapper도 테스트되어야 함. 똑같은 input이 들어갈 경우 똑같은 entity를 내보내주는 부분이 확인 되어야 함. 그것 때문에 인터페이스를 만들고 개선의 여지가 있다고 봄. 모델에 단순히 컨버팅해주는 코드들이 많아 필요 없다거나 확장함수로 처리하는 경우도 있지만 제대로 하겠다면 매퍼를 만드는게 필요하다 봄.
Q : 개발 일정을 단축시킨다거나 안드로이드 인력을 줄였다거나 하는 경우는?
A : input과 output을 먼저 정의하고 ViewModel을 View를 짜고 그 다음에 binding 코드를 짜는 방식이 사고의 흐름에 맞게 개발한다고 봄. 그래서 빠르게 개발한다고 보지만, 선수지식과 경험이 필요한 부분이라 경우에 따라 다를 것으로 봄.
Q : input & output 등을 인터페이스로 구현하고 ViewState 모델링한 부분은 MVVM과 별개로 적용한 것인지?
A : 고민했던 부분. output 자체를 state로 나누는 것과 아예 router명을 명시해서 나누는 것도 고민했음. 개념적으로 같고 코드상의 차이로 보고, 모든 결과에 state라는 것과 그 외에는 router 코드로 판단하기로 함. MVVM과 별개로 봐도 될 것으로 봄.
완벽한 아키텍처, 완벽한 패턴 그리고 정답은 없다고 봄.
각각의 프레임워크, 플랫폼, 서비스 그리고 어떤 사람들이 어떤 컨벤션을 가지고 개발하는지에 따라 달라진다고 봄.
어떻게 할지에 고민보다는 왜 이렇게 하는지에 대한 이유만 명확하게 생각하고 논의하면 될 것으로 봄.
세션설명 : 변화의 시대 : 안드로이드 앱 어떻게 개발할 것인가? 안드로이드는 끊임없는 OS 버전 뿐만아니라 개발 언어, 구조, GUI등 많은 부분에서 다양항 변화가 시도되고 있습니다. 많은 방법론과 라이브러리가 제공되다보니 어떤 전략과 기준으로 개발해야하는지 혼돈스러울 때가 많습니다. 네이버 앱의 개편에 적용한 기술 사례와 방법론을 통해서 효율적인 앱 개발애 대해서 얘기하고자 합니다.
목차 :
1. 안드로이드 앱의 구조
2. 함수형과 객체형: 함수형과 객체형 개발 어떻게 적용할 것이가?
3. GUI 기반 구조: Activity 구조,Fragment 구조, View 기반의 구조의 장단점은 무엇인가? 어떤 구조를 택할 것인가?
4. 데이터 모델: 데이터 모델이 필요한가? MVC, MVP, MVVM 이 정말 필요한가?
5. 프로세스 와 쓰레드 어떤 모델로 가져갈 것인가? : Service, AsyncTask, Thread, JobManager, WorkManager, Coroutine ,Loader 너무 많은데
무엇이 정답인가? 멀티 프로세스 모델 어떻게 설계할 것인가?
6. 통계와 설정: 어떤 정보를 모으고 최적할 것인가?