전체 글
-
움직이는 TextView개발/안드로이드 2021. 5. 11. 19:57
종종 화면내에서 움직이는 TextView를 만들어야 할 때가 있다. 이렇게 직선형태로 움직이는 애니메이션의 경우 TranslateAnimation 클래스를 이용해서 쉽게 구현이 가능하다. 아래 코드는 새로운 TextView를 만들고 layout에 추가한 다음 애니메이션을 실행한 코드다. 주목할 부분은 TranslateAnimation 코드다. CoroutineScope(Dispatchers.Main).launch { val movingText = TextView(requireContext()).apply { this.text = "움직이는 텍스트" this.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewG..
-
DIP(Dependency Inversion Principle)개발/아키텍처 2021. 5. 9. 08:57
좋은 아키텍처는 변동성이 큰 모듈에 의존하지 않는 것이다. 그런데 개발하다 보면 예상치 못한 버그도 종종 생기기 마련이기 때문에 어떤 클래스는 릴리즈마다 계속 수정을 할 수 밖에 없다. 그런데 이때마다 새로운 함수를 추가하고 새로운 변수가 등장한다면 이 클래스를 의존하는 다른 모듈에도 영향이 미친다. 이런 형태면 하나의 클래스를 수정하는데도 다른 클래스까지 영향을 주게 된다. 위 그림에선 사용자가 버그가 많은 결제 시스템 클래스를 의존하고 있다. 지금까지 pay 함수에 버그가 많아서 3개의 레거시 함수가 있다. 이런 형태는 새로운 함수가 추가될 때 마다 사용자의 코드에 영향을 주게 되는 사례다. 해법은 인터페이스를 이용하는 것이다. 모듈은 안정화된 인터페이스에 의존하고 변동성이 큰 실제 구현체는 인터페이..
-
ISP (Interface Segregation Principle)개발/아키텍처 2021. 5. 9. 08:28
ISP는 필요 이상 많은 것을 포함하는 모듈에 의존하지 말자는 원칙에서 유래됐다. 이것도 사례를 먼저 보자. 위 그림을 보면 결제관리, 환불관리, 포인트 관리 객체가 시스템 클래스를 참조하고 있다. 그런데 결제관리 객체는 pay 함수만 호출 할 것이고, 환불 관리는 refund, 포인트관리는 addPoint함수만 사용할 것이다. 각 객체의 입장에서는 필요 이상으로 시스템 클래스에 의존하고 있는 형태다. 만약 객체에서 불필요하게 다른 함수를 호출한다면 에러가 발생할 위험도 있다. 이런 경우에는 시스템을 각각 쪼개주는 방법이 있다. 결제시스템, 환불시스템, 포인트 시스템을 각각 인터페이스로 만들어고 시스템 클래스가 인터페이스의 하위타입으로 구현한다. 그리고 각각의 객체는 관계가 있는 인터페이스에만 의존하도록..
-
LSP (Liskov Substitution Principle)개발/아키텍처 2021. 5. 9. 08:11
LSP는 1988년에 미국MIT 공과대학 교수였던 바버라 리스코브가 제안한 것으로, 상호 대체 가능한 구성요소를 이용해 소프트웨어 시스템을 만들 수 있으려면, 이들 구성요소는 반드시 서로 치환가능해야 한다는 원칙이다. 문장으로 보면 무슨뜻인지 정확히 파악하기 어려우나 원칙을 지킨 사례와 어긴 사례를 보면 어떤 의미인지 감을 잡을 수 있을 것이다. 위 그림은 원칙을 지킨 사례다. 구매자가 결제 시스템을 사용하는데 결제 시스템에선 네이버페이, 카카오페이 둘중 하나를 사용하고 있다. 구매자는 네이버페이를 사용하던, 카카오페이를 사용하던 동일한 결제시스템 인터페이스를 사용하게 될 것이고 영향 받지 않는다. 따라서 결제 시스템은 필요에 따라 하위타입을 치환 가능하다. 객체지향형 프로그램을 개발해본 사람이라면 이렇..
-
OCP (Open Closed Principle)개발/아키텍처 2021. 5. 4. 18:39
SOLID 원칙의 두번째 원칙인 OCP (Open-Closed Principle)은 소프트웨어가 기존 코드를 수정하기보단, 새로운 코드를 추가함으로써 시스템의 행위를 변경할 수 있는 설계 원칙이다. OCP 원칙을 들어보지 못했더라도 Spring이나 안드로이드 최신 개발 프레임워크에서 지향하는 구조 (Spring Repository-Service-Controller 구조, 안드로이드 MVVM)를 사용하고 있다면 암묵적으로 OCP 원칙에 따르고 있게 되는데 이 원칙의 핵심은 소프트웨어를 이루는 컴포넌트를 저수준에서 고수준으로 계층화하는 것이다. 위 그림은 웹페이지를 출력하는 클라이언트를 단순하게 표현한 것이다. Interactor는 서버에 있는 데이터를 가져 올 수 있는 인터페이스의 역할을 하고, Contr..
-
SRP (Single Responsibility Principle)개발/아키텍처 2021. 5. 4. 17:30
소프트웨어 디자인 원칙으로 유명한 SOLID에서 처음으로 소개되는 항목 SRP는 Single Responsibility Principle 의 준말이다. 풀네임의 뜻을 통해 원칙의 의미를 추측한다면 "모든 모듈은 하나의 일만 해야 한다"로 오해하기 쉬운데 이건 함수인 경우에 적용되는 원칙이지 모듈 범위에서 SRP가 뜻하는 바는 이와 다르다. 디자인 원칙에서 SRP는 "하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다"는 것을 의미한다. 아마 이 문장의 느낌이 바로 와닿지가 않을 것 같기 때문에 다음 예제를 소개한다. 위 그림 상에의 Employee 클래스는 초과근무 시간(overtimeHours)을 속성으로 갖고 있고 재무팀에선 이 정보를 이용해 초과근무 수당을 계산하는 함수를(calcul..
-
AudioTrack: Discontinuity detected카테고리 없음 2021. 4. 30. 17:53
몇몇 영상에 대해 Exoplayer 라이브러리에서 AudioTrack: Discontinuity detected [expected 61128344, got 60909659] 에러를 뿜고 있었다. 영상도 렉이 걸리고 소리도 끊김이 있어서 한참 Exoplayer 라이브러리를 디버깅했었는데 이건 플레이어의 문제가 아니라 영상 파일이 문제였다. 사운드 인코딩 과정에서 버퍼 처리를 잘못해서 생긴 문제였는데 자세한 설명을 위해 아래 그림을 참조해보자. 트랜스코딩 과정은 Decoder에서 출력되는 Decoder Buffer를 Encoder Buffer에 복사하고 다시 Encoder에 입력하는 과정으로 이뤄진다. 위 그림에서 보면 Encoder Buffer와 Decoder Buffer모두 사이즈가 2048이기 때문에 ..
-
5월 5일부터는 앱의 광범위한 저장공간 액세스 권한이 필요한 이유를 알려야 합니다.개발/안드로이드 2021. 4. 30. 17:16
저장공간으로부터 파일을 읽어오는 앱을 출시한 개발자의 경우 올해 4월 15일부터 플레이스토어에서 아래 알림을 보게 될 확률이 높다..! 평소 같으면 이런 알림은 그냥 넘겨버렸는데 이번 공지에는 "허용된 용도 외에 모든 파일 액세스 권한에 액세스를 요청하는 앱은 Google Play에서 삭제되고, 업데이트를 게시할 수 없게 됩니다" 라는 무시무시한 경고문이 들어 있어 개발자들을 당황스럽고 잔뜩 쫄아버리게 만든다. 아니 갑자기 스토어에서 내려버리겠다고 으름장을 내다니. 그것도 5/5일부터 적용할 예정인 정책을 4/15일에 알려주는건 어처구니가 없다. 한 달 전도 아니고 3주 남짓한 시간 정도에 이걸 어떻게 모두 정리하냐는 말이다. 그래서 평소 같으면 그냥 지나쳐버린 자세히 알아보기 버튼을 클릭했다. 다행히 ..