SlideShare une entreprise Scribd logo
1  sur  135
오디오 플레이어 리팩토링기
- freestrings@gmail.com
웹 기반 오디오 플레이어 .
HTML5 Audio 를 이용한 플레이어
.
웹 오디오를 만들 때 주의점 ?
웹이라서 Refresh 금지
다른 특이점 없나요 ?
네 .
그런 오디오 플레이어의
개선 , 검토를
의뢰 받다 !
문제상황을 설명 듣다 .
설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명
주로 재생 중 , 다음곡 넘어가기를 여러 번 실행하면 동작이 멈춘 듯 보이다가 실행 ..,
재생 중 일시정지를 한 후 , 다시 재생을 하다가 곡 목록에서 다른 곡을 선택하여 실행하면
바로 플레이가 되지 않고 … 한번에 여러 곡을 넘어가려고 위 화살표
버튼을 여러 번 클릭하면 , 동작이 되지 않고 멈춰 있음 ..
한참을 기다리면 , 몇번 째인지 넘어갔던 곡이 실행됨 .
동작 멈춤 현상이 간혹 재현되며 , 멈춤 현상 중 곡목록 닫기를 하거나 다른 액
션 버튼이 동작하지 않음
.., PC 에서보다 모바일에서 발생 빈도가 높은 상황임 .
어느 순간부터 곡이 재생목록에 추가되지 않는다 .
설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명
그냥 , " 될 때가 있고 , 안 될 때가 있다 "
개발환경을 공유 받다 .
동일한 개발서버 동일한 디렉토리에
파일을 FTP 로 올리면서 테스트 한다
.
누가 제 파일을 덮어 쓰면 어떻게 하나요 ?
" 작업하는 파일이 달라서 그럴 일은 없어요 ."
1. 기반시스템 
소스코드관리시스템┃빌드시스템┃버그관리시스템┃테스트관리시
스템과 테스트 자동화툴┃프로젝트관리시스템┃요구사항관리시스템
 
2. 조직 
프로젝트 구성원의 역할 ┃조직체계 
3. 개발방법론과 프로세스 
소프트웨어 개발방법론┃소프트웨어 개발 프로세스 
4. 사람 
인재 확보┃문서 작성 기술 
5. 문화 
동료 리뷰┃연구┃공유┃품질 우선┃규칙 준수┃장기적인 관점으로
보기 
• Blocked UI
• Heavy requests
• Cookie
• Polling
• Global control flags.
Blocked UI
// 회원정보
function MemberInfo() {
return sendRequest("/getmemberinfo");
}
Blocked UI
//ajax 리턴값받기 ( 동기 : GET)
function sendRequest(url)
{
var oj = createHttpRequest();
oj.open("GET",url,false);
...
oj.send();
return oj.responseText;
}
Blocked UI
• “ 응답을 바로 리턴을 받는다”는 의미는 ?
Blocked UI
• “ 응답을 바로 리턴을 받는다”는 의미는 ?
– 응답을 받기까지 UI 가 다른 작업을 할 수 없다
.
Blocked UI
• “ 응답을 바로 리턴을 받는다”는 의미는 ?
– 응답을 받기까지 UI 가 다른 작업을 할 수 없다
.
• 문제는 ?
Blocked UI
• “ 응답을 바로 리턴을 받는다”는 의미는 ?
– 응답을 받기까지 UI 가 다른 작업을 할 수 없다
.
• 문제는 ?
– 웹 브라우저가 멈춘다 .
Heavy requests
• 한 곡 재생에 필요한 기본요청 6 개
• 모두 순차적으로 실행
Heavy requests
Cookie
• 쿠키는 사용자 별 정보를 힘들이지 않고 관
리하기에  좋다
Cookie
• 쿠키는 사용자 별 정보를 힘들이지 않고 관
리하기에  좋다
• 그렇지만 , 모든 HTTP 요청에 붙어 다닌
다
Polling
• 주기가 짧을 수록 거의 실시간으로 서버와
정보를 동기화 할 수 있다 .
Polling
• 주기가 짧을 수록 거의 실시간으로 서버와
정보를 동기화 할 수 있다 .
• 그렇지만 , 주기가 짧으면 부하가 생긴다 .
Polling
• 주기가 짧을 수록 거의 실시간으로 서버와
정보를 동기화 할 수 있다 .
• 그렇지만 , 주기가 짧으면 부하가 생긴다 .
• 음악사이트는 다른 서비스 보다 사이트에
상주하는 시간이 길다 .
기술에 대한 잘못된 이해와 활용은 심
각한 문제다 .
기술에 대한 잘못된 이해와 활용은 심
각한 문제다 .
그렇지만 , 문제 진단만 되면 ,
서핑과 시간으로 해결 될 수 있다 .
리펙토링
리펙토링
• " 코드가 작성된 후에 디자인을 개선하는 작업 .“
리펙토링
• " 코드가 작성된 후에 디자인을 개선하는 작업 .“
• 왜 잘 동작하는 코드를 고쳐 ?
리펙토링
• " 코드가 작성된 후에 디자인을 개선하는 작업 .“
• 왜 잘 동작하는 코드를 고쳐 ?
• 돌기만 하면 되잖아요 !
리펙토링
• 코드가 작성된 후에 디자인을 개선하는 작업 .
• “ 왜 잘 동작하는 코드를 고쳐 ?”
• “ 돌기만 하면 되잖아요 !”
• “ 일단 대충 이렇게 하시죠”
소프트웨 개발에서는 ,
디자인을 한 다음 코딩을 한다 .
좋은 디자인이 먼저다 .
그러나 ,
시간이 지나면 코드는 수정되고 ,
그러나 ,
시간이 지나면 코드는 수정되고 ,
본래의 모습은 형채도 없이 사라진다 .
그러나 ,
시간이 지나면 코드는 수정되고 ,
본래의 모습은 형채도 없이 사라진다 .
코드는 엔지니어링에서 해킹으로 변질된다
좋은 디자인은
지속적으로 좋은 디자인을 찾는 습관부터다
HTML5 Audio Element
•
http://www.w3.org/wiki/HTML/Elements/audio
<audio id="myAudio"></audio>
<script>
function aud_play_pause() {
var myAudio =
document.getElementById("myAudio");
if (myAudio.paused) {
myAudio.play();
} else {
myAudio.pause();
}
}
</script>
쉽다 .
<audio id='Player' ...></audio>
<button .. onclick="Play()" > 재생 </button>
function Play() {
…
Player.play();
...
}
실제코드 1
Player = document.getElementById('Player');
...
Player.addEventListener("playing", OnPlaying , true);
...
function OnPlaying() {
// 재생로그 ( 시작 )
if (StartPlayLogFlag == false) {
PlayerLog("S",
SongIDS[PlayIndex], 1, PlayLogInfo);
StartPlayLogFlag = true;
}
}
실제코드 2
var SongIDS = new Array(); // 곡아이디 ( 배열 )
var SongInfos = new Array(); // 곡정보 ( 배열 )
var PlayIndex = -1; // 플레이순서
var PlaySongID = ""; // 플레이곡
var LoopFlag = false; // 전체반복여부
var OneLoopFlag = false; // 한곡반복여부
var ShuffleFlag = false; // 셔플여부
var PauseFlag = false; // 일시중지여부
var LibrarySongFlag = false; // 좋아요여부
var MemberStreamingFlag = false; // 회원스트리밍이용권여부
...
var PlayerLoginLayerFlag = false; // 로그인레이어표시여부
var PlayerBuyItemLayerFlag = false; // 구매레이어표시여부
var StartPlayLogFlag = false; // 시작로그여부
var MiddlePlayLogFlag = false; // 중간로그여부
var EndPlayLogFlag = false; // 종료로그여부
var PlayLogInfo = ""; // 로그정보
var ChannelCode = ""; // 채널코드
var MaxCount = 200; // 최대수
실제코드 3
function SongPlay(songID) { // 곡재생
...
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
...
}
실제코드 4
function Loop(flag) {
...
if (flag == "one") {
document.getElementById("btnLoop1_1").style.display = "none;
document.getElementById("btnLoop1_2").style.display = "none"
document.getElementById("btnLoop2_1").style.display = ""
document.getElementById("btnLoop2_2").style.display = ""
document.getElementById("btnLoop3_1").style.display = "none"
document.getElementById("btnLoop3_2").style.display = "none"
OneLoopFlag = true;
LoopFlag = false;
}
if (flag == "all") {...}
if (flag == "") {...}
...
}
실제코드 5
function Prev () {
if(SongIDS.length > 0) {
PauseFlag = false;
if (NextFunction != null) clearInterval(NextFunction);
if (ShuffleFlag == true) {
PlayIndex =
Math.floor( SongIDS.length * Math.random() );
} else {
PlayIndex = PlayIndex - 1;
if (PlayIndex < 0) {
// 이전곡이 없습니다 . 레이어표시
...
}
Play();
}
}
}
실제코드 6
다들 이렇게 코딩하지 않음 ?
뭐가 문제일까요 ?
<audio id='Player' ...></audio>
<button .. onclick="Play()" > 재생 </button>
function Play() {
…
Player.play();
...
}
실제코드 1
Player = document.getElementById('Player');
...
Player.addEventListener("playing", OnPlaying , true);
...
function OnPlaying() {
// 재생로그 ( 시작 )
if (StartPlayLogFlag == false) {
PlayerLog("S",
SongIDS[PlayIndex], 1, PlayLogInfo);
StartPlayLogFlag = true;
}
}
실제코드 2
var SongIDS = new Array(); // 곡아이디 ( 배열 )
var SongInfos = new Array(); // 곡정보 ( 배열 )
var PlayIndex = -1; // 플레이순서
var PlaySongID = ""; // 플레이곡
var LoopFlag = false; // 전체반복여부
var OneLoopFlag = false; // 한곡반복여부
var ShuffleFlag = false; // 셔플여부
var PauseFlag = false; // 일시중지여부
var LibrarySongFlag = false; // 좋아요여부
var MemberStreamingFlag = false; // 회원스트리밍이용권여부
...
var PlayerLoginLayerFlag = false; // 로그인레이어표시여부
var PlayerBuyItemLayerFlag = false; // 구매레이어표시여부
var StartPlayLogFlag = false; // 시작로그여부
var MiddlePlayLogFlag = false; // 중간로그여부
var EndPlayLogFlag = false; // 종료로그여부
var PlayLogInfo = ""; // 로그정보
var ChannelCode = ""; // 채널코드
var MaxCount = 200; // 최대수
실제코드 3
function SongPlay(songID) { // 곡재생
...
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
...
}
실제코드 4
function Loop(flag) {
...
if (flag == "one") {
document.getElementById("btnLoop1_1").style.display = "none;
document.getElementById("btnLoop1_2").style.display = "none"
document.getElementById("btnLoop2_1").style.display = ""
document.getElementById("btnLoop2_2").style.display = ""
document.getElementById("btnLoop3_1").style.display = "none"
document.getElementById("btnLoop3_2").style.display = "none"
OneLoopFlag = true;
LoopFlag = false;
}
if (flag == "all") {...}
if (flag == "") {...}
...
}
실제코드 5
function Prev () {
if(SongIDS.length > 0) {
PauseFlag = false;
if (NextFunction != null) clearInterval(NextFunction);
if (ShuffleFlag == true) {
PlayIndex =
Math.floor( SongIDS.length * Math.random() );
} else {
PlayIndex = PlayIndex - 1;
if (PlayIndex < 0) {
// 이전곡이 없습니다 . 레이어표시
...
}
Play();
}
}
}
실제코드 6
" 컨트롤 변수의 조건에 따라 분기가 되고 ,
객체 / 변수의 접근을 제약 할 수 없다 ."
정도를 공통점으로 꼽을 수 있다 .
왜 이렇게 되었을 까요 ?
왜 이렇게 되었을 까요 ?
• 익숙하지 않은 기술
왜 이렇게 되었을 까요 ?
• 익숙하지 않은 기술
• 기획자에게 질문 할 수록 불어나는 요구사항
왜 이렇게 되었을 까요 ?
• 익숙하지 않은 기술
• 기획자에게 질문 할 수록 불어나는 요구사항
• 촉박한 일정
왜 이렇게 되었을 까요 ?
• 익숙하지 않은 기술
• 기획자에게 질문 할 수록 불어나는 요구사항
• 촉박한 일정
• 어제도 야근
왜 이렇게 되었을 까요 ?
• 익숙하지 않은 기술
• 기획자에게 질문 할 수록 불어나는 요구사항
• 촉박한 일정
• 어제도 야근
• 나도 예전에 개발 좀 했다고 운떼는 PM/ 고참
잠시 , 조건문의 단순화에 대한 학구모드
잠시 , 조건문의 단순화에 대한 학구모드
• 객체지향에서 조건은 다형성으로 상당 부 처리가
될 수 있다 .
잠시 , 조건문의 단순화에 대한 학구모드
• 객체지향에서 조건은 다형성으로 상당 부 처리가
될 수 있다 .
– 예를 들면 , Visitor 패턴
http://java.dzone.com/articles/design-patterns-visitor
http://java.dzone.com/articles/design-patterns-visitor
http://java.dzone.com/articles/design-patterns-visitor
http://java.dzone.com/articles/design-patterns-visitor
http://java.dzone.com/articles/design-patterns-visitor
잠시 , 조건문의 단순화에 대한 학구모드
• 객체지향에서 조건은 다형성으로 상당 부 처리가
될 수 있다 .
– 예를 들면 , Visitor 패턴
• 그럼 문제 해결을 위해 객체지향적인 ? 코드로
바꿔야 하나 ?
잠시 , 조건문의 단순화에 대한 학구모드
• 객체지향에서 조건은 다형성으로 상당 부 처리가
될 수 있다 .
– 예를 들면 , Visitor 패턴
• 그럼 문제 해결을 위해 객체지향적인 ? 코드로
바꿔야 하나 ?
• 자바스크립트는 Overloading 을 지원하지 않는
다 .
조건문의 단순화를 위한 다른 몇가지 기법
조건문의 단순화를 위한 다른 몇가지 기법
• Decompose conditional
• Replace Nested Conditional With Guard
Clauses
• Remove Control Flag
Decompose conditional
복잡한 조건문이 있는 경우
http://www.refactoring.com/
Replace Nested Conditional With
Guard Clauses(1)
메소드가 정상적인 실행 경로를 불명확하게 하는 조건 동작을 가지고 있
는 경우 .
http://www.refactoring.com/
Replace Nested Conditional With
Guard Clauses(2)
메소드가 정상적인 실행 경로를 불명확하게 하는 조건 동작을 가지고 있
는 경우 .
http://www.refactoring.com/
Remove Control Flag(1)
일련의 boolean 식에서 컨트롤 플래그 역활을 하는 변수가 있는 경우 ,
break 또는 return 을 사용
http://www.refactoring.com/
Remove Control Flag(2)
일련의 boolean 식에서 컨트롤 플래그 역활을 하는 변수가 있는 경우 ,
break 또는 return 을 사용
http://www.refactoring.com/
학습은 끝났는데 ,, 응용은 ?
학습은 학습일 뿐 ..
노가다로 하나씩 정리 해 보자 .
직접적인 접근 차단 .
직접적인 접근 차단 .
• 자바스크립트에서 직접적인 접근 차단은 ?
직접적인 접근 차단 .
• 자바스크립트에서 직접적인 접근 차단은 ?
• function outer() { function inner() {} }
직접적인 접근 차단 .
• 자바스크립트에서 직접적인 접근 차단은 ?
• function outer() { function inner() {} }
• inner 를 호출 하는 방법은 ?
직접적인 접근 차단 .
• 자바스크립트에서 직접적인 접근 차단은 ?
• function outer() { function inner() {} }
• inner 를 호출 하는 방법은 ?
• new Audio() 는 뭔가요 ?
직접적인 접근 차단 .
• 자바스크립트에서 직접적인 접근 차단은 ?
• function outer() { function inner() {} }
• inner 를 호출 하는 방법은 ?
• new Audio() 는 뭔가요 ?
– 일반적인 DOM Element 는 document 를 통해
서 생성하는 것과 달리 직접 생성이 가능하다 .
잠시 모바일 환경에서 제약사항을 알아보자
iOS Safari 에서는 User action 이 없으면
음악을 자동 재생 할 수 없다 .
http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML
그럼 ,, 다른 모바일 OS 의 브라우저
는
자동재생이 된나요 ?
아니 .
그러면 왜 iOS 만 언급을 ?
그러면 왜 iOS 만 언급을 ?
iOS 이외엔 browser Audio 를
잘 지원하지 않는다 .
정확히는 모바일류에서 iOS 이외에는
HTML5 Audio 는 서비스에 쓸만하지 않다
.
예를 들면 ,
안드로이드에서는 화면을 끄면 음악도 같이 꺼진다 .
홈버튼을 눌러 브라우저가 내려가는 순간
음악이 중지된다 .
물론 , 최신 버전 기준이다 .
그래서 예제에는 빠져있지만 ,
iOS 에서는 Audio 객체를 활성화시키는
다음과 같은 류의 코드가 필요하다 .
다시 Player 정리로 돌아와서 ,
이제 audio 객체에 직접 접근이 불가능 하다 .
뭐가 달라졌나 ?
앞에서 본 코드 1
앞에서 본 코드 1
• 오디오 상태 관리가 필요없다 .
– 매번 Player.status() 를 통해 얻는다 .
• Audio 의 함수를 직접 호출 해서 발생되는
side effect 도 없다 .
– 실제 Audio 객체가 의도하지 않은 곳에서 직
접 호출되고 그 여파로 , 제어 플래그들의 값이
올바르지 않게 되고 있었다 .
앞에서 본 코드 2
• 여러 기능을 가진 Prev() 를 기억하는가 ?
앞에서 본 코드 2
• 여러 기능을 가진 Prev() 를 기억하는가 ?
– 재생목록의 기능이 계속 추가되면서 걸레가 된
것이 분명 !
앞에서 본 코드 2
• 여러 기능을 가진 Prev() 를 기억하는가 ?
– 재생목록의 기능이 계속 추가되면서 코드가 길
어 진 것이 분명하다 .
• 재생목록은 크게 3 가지 기능을 가진다 .
– 무작위재생과 순차재생
– 반복모드
– 재생목록의 변경에 따른 기타처리
셔플재생과 일반재생
• 단지 재생 순서 차이다 .
셔플재생과 일반재생
• 단지 재생 순서 차이다 .
• Iterator 는 어떨까 ?
– hasNext()
– next()
셔플재생과 일반재생
• 단지 재생 순서 차이다 .
• Iterator 는 어떨까 ?
– hasNext()
– next()
• OrderedIterator vs ShuffleIterator
또 뭐가 달라졌나 ?
PlayIndex, PlaySongID, LoopFlag, OneLoopFlag,
ShuffleFlag, SongInfos, SongIDS..
등의 속성이나 컨트롤 플래그들이
사라지거나 숨겨졌다 .
그럼 , " 이전곡이 없습니다 ." 같
은 UI 표현은 어떻게 하나요 ?
function Loop(flag) {
...
if (flag == "one") {
document.getElementById("btnLoop1_1").style.display = "none;
document.getElementById("btnLoop1_2").style.display = "none"
document.getElementById("btnLoop2_1").style.display = ""
document.getElementById("btnLoop2_2").style.display = ""
document.getElementById("btnLoop3_1").style.display = "none"
document.getElementById("btnLoop3_2").style.display = "none"
OneLoopFlag = true;
LoopFlag = false;
}
if (flag == "all") {...}
if (flag == "") {...}
...
}
앞에서 본 코드 3
CSS 에 관련된 개발문제들
• 웹의 장점 중 하나는 CSS 를 통한 유연한 HTML
Layout, 그러나 갈수록 복잡해지는 UI
• 더없이 높아진 고객 눈높이
– UI 요건 변경이 자주 생김
• JavaScript 에서는 UI 변경을 위해 CSS 클래스
만 추가 / 삭제 하는 것이 추세
• 커스터마이징 하기가 힘든 ExtJS 를 아세요 ?
• 디자이너나 퍼블리셔와 개발자간 협업은 서로에
게 영향이 적어야 한다
앞에서 본 코드 4
function SongPlay(songID) { // 곡재생
...
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
조건문의 많은 코드
...
}
Pull Up Method
• 동일한 일을 하는 메소드를 여러 서브클래
스에서 가지고 있다면 , 이 메소드를 수퍼
클래스로 옮겨라 .
Pull Up Method
• 동일한 일을 하는 메소드를 여러 서브클래
스에서 가지고 있다면 , 이 메소드를 수퍼
클래스로 옮겨라 .
• “ 조건문 많은 코드”인데 갑자기 수퍼클래
스는 무엇인가요 ?
Pull Up Method
• 동일한 일을 하는 메소드를 여러 서브클래
스에서 가지고 있다면 , 이 메소드를 수퍼
클래스로 옮겨라 .
• “ 조건문 많은 코드”인데 갑자기 수퍼클래
스는 뭔가요 ?
• 모두 곡 재생에 대한 권한 처리 들이다 .
– 이용권 , 19 세 , 서비스 불가곡 , XXX 차감 , 기
타 .
Pull Up Method
• 동일한 일을 하는 메소드를 여러 서브클래
스에서 가지고 있다면 , 이 메소드를 수퍼
클래스로 옮겨라 .
• “ 조건문 많은 코드”인데 갑자기 수퍼클래
스는 뭔가요 ?
• 모두 곡 재생에 대한 권한 처리 들이다 .
– 이용권 , 19 세 , 서비스 불가곡 , XXX 차감 , 기
타 .
• checkAutority(memberInfo, songInfo) 정도
면 공통점이 된다
Task 는 이전 Task 의 결과에 따라  
실행여부가 결정된다 .
결과가 false 이면 다음 task 를 실행하지 않는다
.
간단해 졌다 .
기술에 대한 잘못된 이해와 활용은 심
각한 문제다 .
그렇지만 , 문제 진단만 되면 ,
서핑과 시간으로 해결 될 수 있다 .
문제 진단 능력은 경력과 비례한다 .
코드의 디자인 능력은 노력에 비례한다 .
틈틈이 코드를 정리하는 습관을 지닙시다 .
감사합니다 .
여담
• UI 를 조작하는 부분의 예시가 부족합니다 .
여담
• UI 를 조작하는 부분의 예시가 부족합니다 .
– 저도 소위 , ‘ 날코딩’을 했던 터라 뺐습니다 .
여담
• UI 를 조작하는 부분의 예시가 없네요 ?
– 저도 소위 , ‘ 날코딩’을 했던 터라 뺐습니다 .
여담
UI 를 조작하는 부분의 예시가 없네요 ?
– 저도 소위 , ‘ 날코딩’을 했던 터라 뺐습니다 .
• UI 날코딩은 대책이 없나요 ?
여담
• UI 를 조작하는 부분의 예시가 없네요 ?
– 저도 날코딩을 했던 터라 뺐습니다 .
• UI 날코딩은 대책이 없나요 ?
– 잘 구조화된 CSS
– 템플릿 엔진 또는 프레임워크
여담
• UI 를 조작하는 부분의 예시가 없네요 ?
– 저도 날코딩을 했던 터라 뺐습니다 ..
• UI 날코딩은 대책이 없나요 ?
– 잘 구조화된 CSS
– 템플릿 엔진 또는 프레임워크
• 왜 사용 하지 않았나요 ?
여담
• UI 를 조작하는 부분의 예시가 없네요 ?
– 저도 날코딩을 했던 터라 뺐습니다 .
• UI 날코딩은 대책이 없나요 ?
– 잘 구조화된 CSS
– 템플릿 엔진 또는 프레임워크
• 왜 사용 하지 않았나요 ?
– 187 request,
– 1.7 MB transferred,
– 5.8 s ( onload 3.08s, DOMContentLoaded 2.07s)
– 이미 페이지 로딩이 너무 느려서 추가 라이브러리를 사
용하기엔 다소 무리가 있었습니다 .

Contenu connexe

En vedette

리뷰자료 2016
리뷰자료 2016 리뷰자료 2016
리뷰자료 2016 WATER KOREA
 
9x년생 개발자 모임 3회 발표
9x년생 개발자 모임 3회 발표9x년생 개발자 모임 3회 발표
9x년생 개발자 모임 3회 발표Bo Min Lee
 
모바일 웹 어플리케이션 접근성
모바일 웹 어플리케이션 접근성모바일 웹 어플리케이션 접근성
모바일 웹 어플리케이션 접근성Eun Cho
 
지난 2년동안 망고플레이트에서 배운 것
지난 2년동안 망고플레이트에서 배운 것지난 2년동안 망고플레이트에서 배운 것
지난 2년동안 망고플레이트에서 배운 것Skyler Shin
 
프로그래머라고 말할 수 있기까지
프로그래머라고 말할 수 있기까지프로그래머라고 말할 수 있기까지
프로그래머라고 말할 수 있기까지Hyun-Mook Choi
 
Histedit - 9XD 2016 Year-end party Ignite Talk
Histedit - 9XD 2016 Year-end party Ignite TalkHistedit - 9XD 2016 Year-end party Ignite Talk
Histedit - 9XD 2016 Year-end party Ignite TalkHong-il Yang
 
기말개인피피티
기말개인피피티기말개인피피티
기말개인피피티rincho
 
디자이너의 코딩 도전기
디자이너의 코딩 도전기디자이너의 코딩 도전기
디자이너의 코딩 도전기Hyejeong Park
 
nodejs websocket & SOCKET.IO
nodejs websocket & SOCKET.IOnodejs websocket & SOCKET.IO
nodejs websocket & SOCKET.IOMungyu Choi
 
[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기한재 제
 
웹소켓 (WebSocket)
웹소켓 (WebSocket)웹소켓 (WebSocket)
웹소켓 (WebSocket)jeongseokoh
 
[제2회] 9x년생 개발자 모임
[제2회] 9x년생 개발자 모임[제2회] 9x년생 개발자 모임
[제2회] 9x년생 개발자 모임Yurim Jin
 
JEJUPICK [2016 Oh My Jeju Hackathon]
JEJUPICK [2016 Oh My Jeju Hackathon]JEJUPICK [2016 Oh My Jeju Hackathon]
JEJUPICK [2016 Oh My Jeju Hackathon]Yurim Jin
 
WebSocket 기반 쌍방향 메시징
WebSocket 기반 쌍방향 메시징WebSocket 기반 쌍방향 메시징
WebSocket 기반 쌍방향 메시징trustinlee
 
O2O 스타트업에서 한 개발자의 이야기
O2O 스타트업에서 한 개발자의 이야기O2O 스타트업에서 한 개발자의 이야기
O2O 스타트업에서 한 개발자의 이야기Theodore(Yongbin) Cha
 
5조 인터렉티브디자인_최종본
5조 인터렉티브디자인_최종본5조 인터렉티브디자인_최종본
5조 인터렉티브디자인_최종본yesolrr
 
Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션
Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션
Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션미래웹기술연구소 (MIRAE WEB)
 
모임 뒤에 사람있어요 - 9XD 1년 회고
모임 뒤에 사람있어요 - 9XD 1년 회고모임 뒤에 사람있어요 - 9XD 1년 회고
모임 뒤에 사람있어요 - 9XD 1년 회고Yurim Jin
 
신입 개발자 생활백서
신입 개발자 생활백서신입 개발자 생활백서
신입 개발자 생활백서Yurim Jin
 

En vedette (20)

리뷰자료 2016
리뷰자료 2016 리뷰자료 2016
리뷰자료 2016
 
9x년생 개발자 모임 3회 발표
9x년생 개발자 모임 3회 발표9x년생 개발자 모임 3회 발표
9x년생 개발자 모임 3회 발표
 
모바일 웹 어플리케이션 접근성
모바일 웹 어플리케이션 접근성모바일 웹 어플리케이션 접근성
모바일 웹 어플리케이션 접근성
 
지난 2년동안 망고플레이트에서 배운 것
지난 2년동안 망고플레이트에서 배운 것지난 2년동안 망고플레이트에서 배운 것
지난 2년동안 망고플레이트에서 배운 것
 
프로그래머라고 말할 수 있기까지
프로그래머라고 말할 수 있기까지프로그래머라고 말할 수 있기까지
프로그래머라고 말할 수 있기까지
 
Histedit - 9XD 2016 Year-end party Ignite Talk
Histedit - 9XD 2016 Year-end party Ignite TalkHistedit - 9XD 2016 Year-end party Ignite Talk
Histedit - 9XD 2016 Year-end party Ignite Talk
 
기말개인피피티
기말개인피피티기말개인피피티
기말개인피피티
 
디자이너의 코딩 도전기
디자이너의 코딩 도전기디자이너의 코딩 도전기
디자이너의 코딩 도전기
 
nodejs websocket & SOCKET.IO
nodejs websocket & SOCKET.IOnodejs websocket & SOCKET.IO
nodejs websocket & SOCKET.IO
 
[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기
 
웹소켓 (WebSocket)
웹소켓 (WebSocket)웹소켓 (WebSocket)
웹소켓 (WebSocket)
 
[제2회] 9x년생 개발자 모임
[제2회] 9x년생 개발자 모임[제2회] 9x년생 개발자 모임
[제2회] 9x년생 개발자 모임
 
JEJUPICK [2016 Oh My Jeju Hackathon]
JEJUPICK [2016 Oh My Jeju Hackathon]JEJUPICK [2016 Oh My Jeju Hackathon]
JEJUPICK [2016 Oh My Jeju Hackathon]
 
WebSocket 기반 쌍방향 메시징
WebSocket 기반 쌍방향 메시징WebSocket 기반 쌍방향 메시징
WebSocket 기반 쌍방향 메시징
 
O2O 스타트업에서 한 개발자의 이야기
O2O 스타트업에서 한 개발자의 이야기O2O 스타트업에서 한 개발자의 이야기
O2O 스타트업에서 한 개발자의 이야기
 
5조 인터렉티브디자인_최종본
5조 인터렉티브디자인_최종본5조 인터렉티브디자인_최종본
5조 인터렉티브디자인_최종본
 
Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션
Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션
Kaazing - 웹소켓 기술의 유일한 엔터프라이즈 솔루션
 
모임 뒤에 사람있어요 - 9XD 1년 회고
모임 뒤에 사람있어요 - 9XD 1년 회고모임 뒤에 사람있어요 - 9XD 1년 회고
모임 뒤에 사람있어요 - 9XD 1년 회고
 
인터랙트
인터랙트인터랙트
인터랙트
 
신입 개발자 생활백서
신입 개발자 생활백서신입 개발자 생활백서
신입 개발자 생활백서
 

Similaire à Refactoring web audio_player

코끼리를 냉장고에 넣는 법 - 최부호, NDC2013
코끼리를 냉장고에 넣는 법 - 최부호, NDC2013코끼리를 냉장고에 넣는 법 - 최부호, NDC2013
코끼리를 냉장고에 넣는 법 - 최부호, NDC2013NDOORS
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들
NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들
NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들대원 김
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유Hyojun Jeon
 
131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원NAVER D2
 
응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angular응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angularredribbon1307
 
16 학술제 마무리 자료
16 학술제 마무리 자료16 학술제 마무리 자료
16 학술제 마무리 자료Junyoung Jung
 
떠먹여주는 Memcached 1
떠먹여주는 Memcached 1떠먹여주는 Memcached 1
떠먹여주는 Memcached 1Jinwoo Hong
 
Sw학생교재소개(초)
Sw학생교재소개(초)Sw학생교재소개(초)
Sw학생교재소개(초)성훈 김
 
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기flashscope
 
NDC17 장창완(최종)
NDC17 장창완(최종)NDC17 장창완(최종)
NDC17 장창완(최종)창완 장
 
스크립트 피피티
스크립트 피피티스크립트 피피티
스크립트 피피티지수 정
 
깃헙으로 코드리뷰 하기
깃헙으로 코드리뷰 하기깃헙으로 코드리뷰 하기
깃헙으로 코드리뷰 하기Ohgyun Ahn
 
NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화
NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화
NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화ByungJoon Lee
 
[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발
[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발
[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발동현 김
 
[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)
[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)
[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)NAVER D2
 
제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요
제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요
제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요NAVER D2
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템QooJuice
 
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...Kay Kim
 
코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기Yong Hoon Kim
 

Similaire à Refactoring web audio_player (20)

코끼리를 냉장고에 넣는 법 - 최부호, NDC2013
코끼리를 냉장고에 넣는 법 - 최부호, NDC2013코끼리를 냉장고에 넣는 법 - 최부호, NDC2013
코끼리를 냉장고에 넣는 법 - 최부호, NDC2013
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들
NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들
NDC17. "솔리테어: 덱다웃" 유니티 모바일 테스팅 기법들
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
 
131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원131 deview 2013 yobi-채수원
131 deview 2013 yobi-채수원
 
응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angular응답하라 반응형웹 - 4. angular
응답하라 반응형웹 - 4. angular
 
16 학술제 마무리 자료
16 학술제 마무리 자료16 학술제 마무리 자료
16 학술제 마무리 자료
 
떠먹여주는 Memcached 1
떠먹여주는 Memcached 1떠먹여주는 Memcached 1
떠먹여주는 Memcached 1
 
Sw학생교재소개(초)
Sw학생교재소개(초)Sw학생교재소개(초)
Sw학생교재소개(초)
 
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
[NHN NEXT]실전프로젝트 밴드 게임 만들기 후기
 
NDC17 장창완(최종)
NDC17 장창완(최종)NDC17 장창완(최종)
NDC17 장창완(최종)
 
스크립트 피피티
스크립트 피피티스크립트 피피티
스크립트 피피티
 
깃헙으로 코드리뷰 하기
깃헙으로 코드리뷰 하기깃헙으로 코드리뷰 하기
깃헙으로 코드리뷰 하기
 
NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화
NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화
NDC 2013 Monkeyrunner를 이용한 모바일 테스트 자동화
 
[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발
[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발
[HYSS 2016] 쉽고 빠르게 시작하는 Volatility Plugin 개발
 
[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)
[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)
[Kerference] 쉽고 빠르게 시작하는 Volatility plugin 개발 - 김동현(BoB)
 
제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요
제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요
제12회 IT4U 강연회 - 악성코드 분석 잘하고 싶어요
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
 
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
애자일 게임 개발: 현실 세계의 혼돈을 다루는 법 (Agile Game Development: Dealing With Chaos In Th...
 
코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기
 

Refactoring web audio_player

  • 2. 웹 기반 오디오 플레이어 . HTML5 Audio 를 이용한 플레이어 .
  • 3. 웹 오디오를 만들 때 주의점 ?
  • 7. 그런 오디오 플레이어의 개선 , 검토를 의뢰 받다 !
  • 9. 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 주로 재생 중 , 다음곡 넘어가기를 여러 번 실행하면 동작이 멈춘 듯 보이다가 실행 .., 재생 중 일시정지를 한 후 , 다시 재생을 하다가 곡 목록에서 다른 곡을 선택하여 실행하면 바로 플레이가 되지 않고 … 한번에 여러 곡을 넘어가려고 위 화살표 버튼을 여러 번 클릭하면 , 동작이 되지 않고 멈춰 있음 .. 한참을 기다리면 , 몇번 째인지 넘어갔던 곡이 실행됨 . 동작 멈춤 현상이 간혹 재현되며 , 멈춤 현상 중 곡목록 닫기를 하거나 다른 액 션 버튼이 동작하지 않음 .., PC 에서보다 모바일에서 발생 빈도가 높은 상황임 . 어느 순간부터 곡이 재생목록에 추가되지 않는다 . 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명 설명
  • 10. 그냥 , " 될 때가 있고 , 안 될 때가 있다 "
  • 12. 동일한 개발서버 동일한 디렉토리에 파일을 FTP 로 올리면서 테스트 한다 .
  • 13. 누가 제 파일을 덮어 쓰면 어떻게 하나요 ?
  • 14. " 작업하는 파일이 달라서 그럴 일은 없어요 ."
  • 15.
  • 16. 1. 기반시스템  소스코드관리시스템┃빌드시스템┃버그관리시스템┃테스트관리시 스템과 테스트 자동화툴┃프로젝트관리시스템┃요구사항관리시스템   2. 조직  프로젝트 구성원의 역할 ┃조직체계  3. 개발방법론과 프로세스  소프트웨어 개발방법론┃소프트웨어 개발 프로세스  4. 사람  인재 확보┃문서 작성 기술  5. 문화  동료 리뷰┃연구┃공유┃품질 우선┃규칙 준수┃장기적인 관점으로 보기 
  • 17. • Blocked UI • Heavy requests • Cookie • Polling • Global control flags.
  • 18. Blocked UI // 회원정보 function MemberInfo() { return sendRequest("/getmemberinfo"); }
  • 19. Blocked UI //ajax 리턴값받기 ( 동기 : GET) function sendRequest(url) { var oj = createHttpRequest(); oj.open("GET",url,false); ... oj.send(); return oj.responseText; }
  • 20. Blocked UI • “ 응답을 바로 리턴을 받는다”는 의미는 ?
  • 21. Blocked UI • “ 응답을 바로 리턴을 받는다”는 의미는 ? – 응답을 받기까지 UI 가 다른 작업을 할 수 없다 .
  • 22. Blocked UI • “ 응답을 바로 리턴을 받는다”는 의미는 ? – 응답을 받기까지 UI 가 다른 작업을 할 수 없다 . • 문제는 ?
  • 23. Blocked UI • “ 응답을 바로 리턴을 받는다”는 의미는 ? – 응답을 받기까지 UI 가 다른 작업을 할 수 없다 . • 문제는 ? – 웹 브라우저가 멈춘다 .
  • 24. Heavy requests • 한 곡 재생에 필요한 기본요청 6 개 • 모두 순차적으로 실행
  • 26. Cookie • 쿠키는 사용자 별 정보를 힘들이지 않고 관 리하기에  좋다
  • 27. Cookie • 쿠키는 사용자 별 정보를 힘들이지 않고 관 리하기에  좋다 • 그렇지만 , 모든 HTTP 요청에 붙어 다닌 다
  • 28. Polling • 주기가 짧을 수록 거의 실시간으로 서버와 정보를 동기화 할 수 있다 .
  • 29. Polling • 주기가 짧을 수록 거의 실시간으로 서버와 정보를 동기화 할 수 있다 . • 그렇지만 , 주기가 짧으면 부하가 생긴다 .
  • 30. Polling • 주기가 짧을 수록 거의 실시간으로 서버와 정보를 동기화 할 수 있다 . • 그렇지만 , 주기가 짧으면 부하가 생긴다 . • 음악사이트는 다른 서비스 보다 사이트에 상주하는 시간이 길다 .
  • 31. 기술에 대한 잘못된 이해와 활용은 심 각한 문제다 .
  • 32. 기술에 대한 잘못된 이해와 활용은 심 각한 문제다 . 그렇지만 , 문제 진단만 되면 , 서핑과 시간으로 해결 될 수 있다 .
  • 34. 리펙토링 • " 코드가 작성된 후에 디자인을 개선하는 작업 .“
  • 35. 리펙토링 • " 코드가 작성된 후에 디자인을 개선하는 작업 .“ • 왜 잘 동작하는 코드를 고쳐 ?
  • 36. 리펙토링 • " 코드가 작성된 후에 디자인을 개선하는 작업 .“ • 왜 잘 동작하는 코드를 고쳐 ? • 돌기만 하면 되잖아요 !
  • 37. 리펙토링 • 코드가 작성된 후에 디자인을 개선하는 작업 . • “ 왜 잘 동작하는 코드를 고쳐 ?” • “ 돌기만 하면 되잖아요 !” • “ 일단 대충 이렇게 하시죠”
  • 38. 소프트웨 개발에서는 , 디자인을 한 다음 코딩을 한다 . 좋은 디자인이 먼저다 .
  • 39. 그러나 , 시간이 지나면 코드는 수정되고 ,
  • 40. 그러나 , 시간이 지나면 코드는 수정되고 , 본래의 모습은 형채도 없이 사라진다 .
  • 41. 그러나 , 시간이 지나면 코드는 수정되고 , 본래의 모습은 형채도 없이 사라진다 . 코드는 엔지니어링에서 해킹으로 변질된다
  • 42. 좋은 디자인은 지속적으로 좋은 디자인을 찾는 습관부터다
  • 44.
  • 45.
  • 46. <audio id="myAudio"></audio> <script> function aud_play_pause() { var myAudio = document.getElementById("myAudio"); if (myAudio.paused) { myAudio.play(); } else { myAudio.pause(); } } </script>
  • 48. <audio id='Player' ...></audio> <button .. onclick="Play()" > 재생 </button> function Play() { … Player.play(); ... } 실제코드 1
  • 49. Player = document.getElementById('Player'); ... Player.addEventListener("playing", OnPlaying , true); ... function OnPlaying() { // 재생로그 ( 시작 ) if (StartPlayLogFlag == false) { PlayerLog("S", SongIDS[PlayIndex], 1, PlayLogInfo); StartPlayLogFlag = true; } } 실제코드 2
  • 50. var SongIDS = new Array(); // 곡아이디 ( 배열 ) var SongInfos = new Array(); // 곡정보 ( 배열 ) var PlayIndex = -1; // 플레이순서 var PlaySongID = ""; // 플레이곡 var LoopFlag = false; // 전체반복여부 var OneLoopFlag = false; // 한곡반복여부 var ShuffleFlag = false; // 셔플여부 var PauseFlag = false; // 일시중지여부 var LibrarySongFlag = false; // 좋아요여부 var MemberStreamingFlag = false; // 회원스트리밍이용권여부 ... var PlayerLoginLayerFlag = false; // 로그인레이어표시여부 var PlayerBuyItemLayerFlag = false; // 구매레이어표시여부 var StartPlayLogFlag = false; // 시작로그여부 var MiddlePlayLogFlag = false; // 중간로그여부 var EndPlayLogFlag = false; // 종료로그여부 var PlayLogInfo = ""; // 로그정보 var ChannelCode = ""; // 채널코드 var MaxCount = 200; // 최대수 실제코드 3
  • 51. function SongPlay(songID) { // 곡재생 ... 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 ... } 실제코드 4
  • 52. function Loop(flag) { ... if (flag == "one") { document.getElementById("btnLoop1_1").style.display = "none; document.getElementById("btnLoop1_2").style.display = "none" document.getElementById("btnLoop2_1").style.display = "" document.getElementById("btnLoop2_2").style.display = "" document.getElementById("btnLoop3_1").style.display = "none" document.getElementById("btnLoop3_2").style.display = "none" OneLoopFlag = true; LoopFlag = false; } if (flag == "all") {...} if (flag == "") {...} ... } 실제코드 5
  • 53. function Prev () { if(SongIDS.length > 0) { PauseFlag = false; if (NextFunction != null) clearInterval(NextFunction); if (ShuffleFlag == true) { PlayIndex = Math.floor( SongIDS.length * Math.random() ); } else { PlayIndex = PlayIndex - 1; if (PlayIndex < 0) { // 이전곡이 없습니다 . 레이어표시 ... } Play(); } } } 실제코드 6
  • 54. 다들 이렇게 코딩하지 않음 ? 뭐가 문제일까요 ?
  • 55. <audio id='Player' ...></audio> <button .. onclick="Play()" > 재생 </button> function Play() { … Player.play(); ... } 실제코드 1
  • 56. Player = document.getElementById('Player'); ... Player.addEventListener("playing", OnPlaying , true); ... function OnPlaying() { // 재생로그 ( 시작 ) if (StartPlayLogFlag == false) { PlayerLog("S", SongIDS[PlayIndex], 1, PlayLogInfo); StartPlayLogFlag = true; } } 실제코드 2
  • 57. var SongIDS = new Array(); // 곡아이디 ( 배열 ) var SongInfos = new Array(); // 곡정보 ( 배열 ) var PlayIndex = -1; // 플레이순서 var PlaySongID = ""; // 플레이곡 var LoopFlag = false; // 전체반복여부 var OneLoopFlag = false; // 한곡반복여부 var ShuffleFlag = false; // 셔플여부 var PauseFlag = false; // 일시중지여부 var LibrarySongFlag = false; // 좋아요여부 var MemberStreamingFlag = false; // 회원스트리밍이용권여부 ... var PlayerLoginLayerFlag = false; // 로그인레이어표시여부 var PlayerBuyItemLayerFlag = false; // 구매레이어표시여부 var StartPlayLogFlag = false; // 시작로그여부 var MiddlePlayLogFlag = false; // 중간로그여부 var EndPlayLogFlag = false; // 종료로그여부 var PlayLogInfo = ""; // 로그정보 var ChannelCode = ""; // 채널코드 var MaxCount = 200; // 최대수 실제코드 3
  • 58. function SongPlay(songID) { // 곡재생 ... 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 ... } 실제코드 4
  • 59. function Loop(flag) { ... if (flag == "one") { document.getElementById("btnLoop1_1").style.display = "none; document.getElementById("btnLoop1_2").style.display = "none" document.getElementById("btnLoop2_1").style.display = "" document.getElementById("btnLoop2_2").style.display = "" document.getElementById("btnLoop3_1").style.display = "none" document.getElementById("btnLoop3_2").style.display = "none" OneLoopFlag = true; LoopFlag = false; } if (flag == "all") {...} if (flag == "") {...} ... } 실제코드 5
  • 60. function Prev () { if(SongIDS.length > 0) { PauseFlag = false; if (NextFunction != null) clearInterval(NextFunction); if (ShuffleFlag == true) { PlayIndex = Math.floor( SongIDS.length * Math.random() ); } else { PlayIndex = PlayIndex - 1; if (PlayIndex < 0) { // 이전곡이 없습니다 . 레이어표시 ... } Play(); } } } 실제코드 6
  • 61. " 컨트롤 변수의 조건에 따라 분기가 되고 , 객체 / 변수의 접근을 제약 할 수 없다 ." 정도를 공통점으로 꼽을 수 있다 .
  • 63. 왜 이렇게 되었을 까요 ? • 익숙하지 않은 기술
  • 64. 왜 이렇게 되었을 까요 ? • 익숙하지 않은 기술 • 기획자에게 질문 할 수록 불어나는 요구사항
  • 65. 왜 이렇게 되었을 까요 ? • 익숙하지 않은 기술 • 기획자에게 질문 할 수록 불어나는 요구사항 • 촉박한 일정
  • 66. 왜 이렇게 되었을 까요 ? • 익숙하지 않은 기술 • 기획자에게 질문 할 수록 불어나는 요구사항 • 촉박한 일정 • 어제도 야근
  • 67. 왜 이렇게 되었을 까요 ? • 익숙하지 않은 기술 • 기획자에게 질문 할 수록 불어나는 요구사항 • 촉박한 일정 • 어제도 야근 • 나도 예전에 개발 좀 했다고 운떼는 PM/ 고참
  • 68. 잠시 , 조건문의 단순화에 대한 학구모드
  • 69. 잠시 , 조건문의 단순화에 대한 학구모드 • 객체지향에서 조건은 다형성으로 상당 부 처리가 될 수 있다 .
  • 70. 잠시 , 조건문의 단순화에 대한 학구모드 • 객체지향에서 조건은 다형성으로 상당 부 처리가 될 수 있다 . – 예를 들면 , Visitor 패턴
  • 76. 잠시 , 조건문의 단순화에 대한 학구모드 • 객체지향에서 조건은 다형성으로 상당 부 처리가 될 수 있다 . – 예를 들면 , Visitor 패턴 • 그럼 문제 해결을 위해 객체지향적인 ? 코드로 바꿔야 하나 ?
  • 77. 잠시 , 조건문의 단순화에 대한 학구모드 • 객체지향에서 조건은 다형성으로 상당 부 처리가 될 수 있다 . – 예를 들면 , Visitor 패턴 • 그럼 문제 해결을 위해 객체지향적인 ? 코드로 바꿔야 하나 ? • 자바스크립트는 Overloading 을 지원하지 않는 다 .
  • 78. 조건문의 단순화를 위한 다른 몇가지 기법
  • 79. 조건문의 단순화를 위한 다른 몇가지 기법 • Decompose conditional • Replace Nested Conditional With Guard Clauses • Remove Control Flag
  • 80. Decompose conditional 복잡한 조건문이 있는 경우 http://www.refactoring.com/
  • 81. Replace Nested Conditional With Guard Clauses(1) 메소드가 정상적인 실행 경로를 불명확하게 하는 조건 동작을 가지고 있 는 경우 . http://www.refactoring.com/
  • 82. Replace Nested Conditional With Guard Clauses(2) 메소드가 정상적인 실행 경로를 불명확하게 하는 조건 동작을 가지고 있 는 경우 . http://www.refactoring.com/
  • 83. Remove Control Flag(1) 일련의 boolean 식에서 컨트롤 플래그 역활을 하는 변수가 있는 경우 , break 또는 return 을 사용 http://www.refactoring.com/
  • 84. Remove Control Flag(2) 일련의 boolean 식에서 컨트롤 플래그 역활을 하는 변수가 있는 경우 , break 또는 return 을 사용 http://www.refactoring.com/
  • 86. 학습은 학습일 뿐 .. 노가다로 하나씩 정리 해 보자 .
  • 88. 직접적인 접근 차단 . • 자바스크립트에서 직접적인 접근 차단은 ?
  • 89. 직접적인 접근 차단 . • 자바스크립트에서 직접적인 접근 차단은 ? • function outer() { function inner() {} }
  • 90. 직접적인 접근 차단 . • 자바스크립트에서 직접적인 접근 차단은 ? • function outer() { function inner() {} } • inner 를 호출 하는 방법은 ?
  • 91.
  • 92. 직접적인 접근 차단 . • 자바스크립트에서 직접적인 접근 차단은 ? • function outer() { function inner() {} } • inner 를 호출 하는 방법은 ? • new Audio() 는 뭔가요 ?
  • 93. 직접적인 접근 차단 . • 자바스크립트에서 직접적인 접근 차단은 ? • function outer() { function inner() {} } • inner 를 호출 하는 방법은 ? • new Audio() 는 뭔가요 ? – 일반적인 DOM Element 는 document 를 통해 서 생성하는 것과 달리 직접 생성이 가능하다 .
  • 94. 잠시 모바일 환경에서 제약사항을 알아보자 iOS Safari 에서는 User action 이 없으면 음악을 자동 재생 할 수 없다 . http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML
  • 95. 그럼 ,, 다른 모바일 OS 의 브라우저 는 자동재생이 된나요 ?
  • 97. 그러면 왜 iOS 만 언급을 ?
  • 98. 그러면 왜 iOS 만 언급을 ? iOS 이외엔 browser Audio 를 잘 지원하지 않는다 . 정확히는 모바일류에서 iOS 이외에는 HTML5 Audio 는 서비스에 쓸만하지 않다 .
  • 99. 예를 들면 , 안드로이드에서는 화면을 끄면 음악도 같이 꺼진다 . 홈버튼을 눌러 브라우저가 내려가는 순간 음악이 중지된다 . 물론 , 최신 버전 기준이다 .
  • 100. 그래서 예제에는 빠져있지만 , iOS 에서는 Audio 객체를 활성화시키는 다음과 같은 류의 코드가 필요하다 .
  • 101.
  • 102. 다시 Player 정리로 돌아와서 , 이제 audio 객체에 직접 접근이 불가능 하다 . 뭐가 달라졌나 ?
  • 104. 앞에서 본 코드 1 • 오디오 상태 관리가 필요없다 . – 매번 Player.status() 를 통해 얻는다 . • Audio 의 함수를 직접 호출 해서 발생되는 side effect 도 없다 . – 실제 Audio 객체가 의도하지 않은 곳에서 직 접 호출되고 그 여파로 , 제어 플래그들의 값이 올바르지 않게 되고 있었다 .
  • 105. 앞에서 본 코드 2 • 여러 기능을 가진 Prev() 를 기억하는가 ?
  • 106. 앞에서 본 코드 2 • 여러 기능을 가진 Prev() 를 기억하는가 ? – 재생목록의 기능이 계속 추가되면서 걸레가 된 것이 분명 !
  • 107. 앞에서 본 코드 2 • 여러 기능을 가진 Prev() 를 기억하는가 ? – 재생목록의 기능이 계속 추가되면서 코드가 길 어 진 것이 분명하다 . • 재생목록은 크게 3 가지 기능을 가진다 . – 무작위재생과 순차재생 – 반복모드 – 재생목록의 변경에 따른 기타처리
  • 108. 셔플재생과 일반재생 • 단지 재생 순서 차이다 .
  • 109. 셔플재생과 일반재생 • 단지 재생 순서 차이다 . • Iterator 는 어떨까 ? – hasNext() – next()
  • 110. 셔플재생과 일반재생 • 단지 재생 순서 차이다 . • Iterator 는 어떨까 ? – hasNext() – next() • OrderedIterator vs ShuffleIterator
  • 111.
  • 113. PlayIndex, PlaySongID, LoopFlag, OneLoopFlag, ShuffleFlag, SongInfos, SongIDS.. 등의 속성이나 컨트롤 플래그들이 사라지거나 숨겨졌다 .
  • 114. 그럼 , " 이전곡이 없습니다 ." 같 은 UI 표현은 어떻게 하나요 ?
  • 115.
  • 116. function Loop(flag) { ... if (flag == "one") { document.getElementById("btnLoop1_1").style.display = "none; document.getElementById("btnLoop1_2").style.display = "none" document.getElementById("btnLoop2_1").style.display = "" document.getElementById("btnLoop2_2").style.display = "" document.getElementById("btnLoop3_1").style.display = "none" document.getElementById("btnLoop3_2").style.display = "none" OneLoopFlag = true; LoopFlag = false; } if (flag == "all") {...} if (flag == "") {...} ... } 앞에서 본 코드 3
  • 117. CSS 에 관련된 개발문제들 • 웹의 장점 중 하나는 CSS 를 통한 유연한 HTML Layout, 그러나 갈수록 복잡해지는 UI • 더없이 높아진 고객 눈높이 – UI 요건 변경이 자주 생김 • JavaScript 에서는 UI 변경을 위해 CSS 클래스 만 추가 / 삭제 하는 것이 추세 • 커스터마이징 하기가 힘든 ExtJS 를 아세요 ? • 디자이너나 퍼블리셔와 개발자간 협업은 서로에 게 영향이 적어야 한다
  • 118.
  • 119. 앞에서 본 코드 4 function SongPlay(songID) { // 곡재생 ... 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 조건문의 많은 코드 ... }
  • 120. Pull Up Method • 동일한 일을 하는 메소드를 여러 서브클래 스에서 가지고 있다면 , 이 메소드를 수퍼 클래스로 옮겨라 .
  • 121. Pull Up Method • 동일한 일을 하는 메소드를 여러 서브클래 스에서 가지고 있다면 , 이 메소드를 수퍼 클래스로 옮겨라 . • “ 조건문 많은 코드”인데 갑자기 수퍼클래 스는 무엇인가요 ?
  • 122. Pull Up Method • 동일한 일을 하는 메소드를 여러 서브클래 스에서 가지고 있다면 , 이 메소드를 수퍼 클래스로 옮겨라 . • “ 조건문 많은 코드”인데 갑자기 수퍼클래 스는 뭔가요 ? • 모두 곡 재생에 대한 권한 처리 들이다 . – 이용권 , 19 세 , 서비스 불가곡 , XXX 차감 , 기 타 .
  • 123. Pull Up Method • 동일한 일을 하는 메소드를 여러 서브클래 스에서 가지고 있다면 , 이 메소드를 수퍼 클래스로 옮겨라 . • “ 조건문 많은 코드”인데 갑자기 수퍼클래 스는 뭔가요 ? • 모두 곡 재생에 대한 권한 처리 들이다 . – 이용권 , 19 세 , 서비스 불가곡 , XXX 차감 , 기 타 . • checkAutority(memberInfo, songInfo) 정도 면 공통점이 된다
  • 124.
  • 125. Task 는 이전 Task 의 결과에 따라   실행여부가 결정된다 . 결과가 false 이면 다음 task 를 실행하지 않는다 . 간단해 졌다 .
  • 126. 기술에 대한 잘못된 이해와 활용은 심 각한 문제다 . 그렇지만 , 문제 진단만 되면 , 서핑과 시간으로 해결 될 수 있다 .
  • 127. 문제 진단 능력은 경력과 비례한다 . 코드의 디자인 능력은 노력에 비례한다 . 틈틈이 코드를 정리하는 습관을 지닙시다 .
  • 129. 여담 • UI 를 조작하는 부분의 예시가 부족합니다 .
  • 130. 여담 • UI 를 조작하는 부분의 예시가 부족합니다 . – 저도 소위 , ‘ 날코딩’을 했던 터라 뺐습니다 .
  • 131. 여담 • UI 를 조작하는 부분의 예시가 없네요 ? – 저도 소위 , ‘ 날코딩’을 했던 터라 뺐습니다 .
  • 132. 여담 UI 를 조작하는 부분의 예시가 없네요 ? – 저도 소위 , ‘ 날코딩’을 했던 터라 뺐습니다 . • UI 날코딩은 대책이 없나요 ?
  • 133. 여담 • UI 를 조작하는 부분의 예시가 없네요 ? – 저도 날코딩을 했던 터라 뺐습니다 . • UI 날코딩은 대책이 없나요 ? – 잘 구조화된 CSS – 템플릿 엔진 또는 프레임워크
  • 134. 여담 • UI 를 조작하는 부분의 예시가 없네요 ? – 저도 날코딩을 했던 터라 뺐습니다 .. • UI 날코딩은 대책이 없나요 ? – 잘 구조화된 CSS – 템플릿 엔진 또는 프레임워크 • 왜 사용 하지 않았나요 ?
  • 135. 여담 • UI 를 조작하는 부분의 예시가 없네요 ? – 저도 날코딩을 했던 터라 뺐습니다 . • UI 날코딩은 대책이 없나요 ? – 잘 구조화된 CSS – 템플릿 엔진 또는 프레임워크 • 왜 사용 하지 않았나요 ? – 187 request, – 1.7 MB transferred, – 5.8 s ( onload 3.08s, DOMContentLoaded 2.07s) – 이미 페이지 로딩이 너무 느려서 추가 라이브러리를 사 용하기엔 다소 무리가 있었습니다 .