애플(Apple)의 마이크로소프트(Microsote)화?

Programming/Etc 2010. 2. 12. 15:11
- Adobe CTO Kevin Lynch의 WSJ 기자와 인터뷰 내용입니다.

Wall Street Journal
OPINION: The Microsofting of Apple?
February 9, 2010
By Holman W. Jenkins, Jr.

애플은 증오적 라이벌 관계로 인해 제로섬 전략에 집착하는 회사로 전락할 위험에 놓여있습니다.

현재를 언급하는 것이 아니라 애플의 시가총액이 상상할 수 없는 규모에 달하여 마이크로소프트의 시가총액을 뛰어넘는 해의 이야기가 될 수 있습니다. 당연히 축하 인사가 따르겠지만 위로의 말도 함께 따를 것입니다. 제품 개발에만 전념하는 회사의 경우 전략에 집착하는 회사가 될 위험의 소지가 있기 때문입니다. 그리고 여기서 “전략”이란 증오적 라이벌 관계로 인한 제로섬 전략을 의미합니다.

안타깝게도 현재 우리는 신뢰를 찾기 힘든 타락한 세상에 살고 있습니다.

아이패드(iPad)의 예를 들어보겠습니다. 아이패드는 세상에 공개되자마자 “구세주 태블릿”이라는 별명을 얻었습니다. 아이패드는 상상하지 못할 만큼 탁월한 제품이 아닌 단지 애플이 넷북 경쟁에 뛰어들기 위해 출시한 제품으로, 아이팟 터치(iPod Touch)를 확대해 놓은 버전에 불과합니다. 아이패드는 최상의 웹 브라우징 시스템으로 부각될 수 없을 수도 있습니다. 왜냐하면 애플이 웹 상에서 비디오를 전달하는 데 75% 가량 사용되고 있는 플래시(Flash) 지원을 거부했기 때문입니다. 그러나 아이패드(iPad)(‘지불’이라는 영어 PAID의 철자 순서를 바꾸어 만든 말)는 애플의 온라인 서비스를 통해 판매되고 있는 e북, 음악 및 비디오를 사용하기에는 적합한 디바이스로 보입니다. 단도직입적으로 말하자면 아이패드는 마치 아이튠즈(iTunes) 스토어를 후원하기 위해 최적화된 디바이스로 보입니다.

그렇다면 왜 애플은 플래시를 제외시키기로 결정했는지 궁금하지 않을 수 없습니다. 애플과 애플의 후원업체들은 플래시가 짜증나는 웹 광고를 만드는데 사용되는 제품이라는 미학적이고 철학적인 이유를 내세우고 있습니다.

애플이 플래시를 거부하는 이유는 바로 여기에 있습니다. 플래시를 사용하면 아이폰(iPhone) 및 아이패드 사용자는 아이튠즈를 통하지 않고 비디오 및 기타 엔터테인먼트를 사용할 수 있을 것이고 애플 앱 스토어(Apple App Store)에서만 현재 구입할 수 있는 다양한 기능을 무료로 얻을 수 있게 됩니다.

네트 중립성 옹호자들이나 독점 금지법 집행자들이 스티브 잡스(Steve Jobs)를 연행해가는 오류를 범하지 않도록, 한 가지 덧붙이자면 애플은 플래시를 거부할 수 있는 적법한 권리를 가지고 있습니다. 그러나 한 가지 짚고 넘어가야 할 것은 애플은 엄청난 양의 웹 컨텐츠와 사용자를 분리시키려는 전략적 선택을 내세우고 있다는 점입니다. 플래시가 버그를 부른다는 주장 등에 대해 플래시 옹호자의 시점에서 잠시 벗어나 설명해 보겠습니다. 플래시는 다른 비디오 플레이어와의 시장 경쟁에서 우위를 점하고 있으며 10억 명에 달하는 PC 사용자가 정기적인 업데이트를 다운로드하고 있다는 사실은 엄청난 성공이라고 해도 과언이 아닐 것입니다. Hulu.com에서 TV 프로그램을 시청하거나 MLB.com에서 야구 경기를 보거나 Facebook을 통해 친구와 커뮤니케이션할 때에도 플래시가 필요합니다.

현재로선 플래시를 소유하고 있는 어도비는 최소한 플래시 프로그래머가 애플의 앱 스토어를 통해 자신이 개발한 컨텐츠나 애플리케이션을 제공할 수 있도록 몇 가지 툴을 출시하고 있다고 말하고 있습니다. 이것도 애플의 축복이 있어야 가능할 것입니다. 그러나 애플은 미래의 웹 표준은 독점적인 플래시를 대체하게 될 것이라고 주장하고 있습니다. 이것은 지켜봐야 할 일입니다. 플래시는 현재 전세계 95%의 PC에 설치되어 있어 하루 아침에 웹 표준이 바뀔 가능성은 극히 희박합니다. 또한 파이어폭스(Firefox) 같은 브라우저 제작업체 모두가 애플이 말한 새로운 표준과 생각을 함께 하고 있는 것도 아닙니다.

더 크게 우려되는 바는 여기에 있습니다. 애플이 이러한 무모한 목표로 인해 자사의 모바일 디바이스 사용자층을 확대하여 단지 더 많은 사용자가 아이튠즈만 이용하도록 사용자를 가두는 “네트워크 효과”의 매혹적인 유혹에 무릎을 꿇을 수 있다는 점입니다. 애플은 최근까지 제휴 관계를 유지했던 구글(Google)과 전면전에 돌입했습니다.

지난달 말 애플 직원과의 미팅에서 스티브 잡스가 “지금까지 애플은 검색 시장에서 구글과의 경쟁을 피하기 위해 노력했지만 ‘아이폰 타도’ 를 위해 자사의 모바일 디바이스르 출시했다.” 면서 “사악해지지 말자(Don't be evil) " 라는 구글의 모토를 폄하한 발언이 일파 만파 퍼졌습니다.

구글폰으로 인해 아이폰이 없어지지는 않을 것입니다. 시장은 수많은 모바일 디바이스를 수용할 수 있는 여건을 충분히 갖추고 있습니다. 그러나 실제 위협이 되는 것은 수천만 명의 소비자를 앱 스토어인 아이튠즈만 이용할 것을 주입시킬 수 있는 애플의 능력입니다. 구글이 아이패드가 공개되기 며칠 전 자사의 슬레이트 모양의 디바이스 모델을 발표한 것은 의미 있는 행보였습니다. 구글의 모바일 디바이스는 플래시를 지원하고 있습니다. 애플 사용자가 사용할 수 없는 비디오 및 기타 웹 기능을 사용자가 구매하거나 사용할 수 있도록 했습니다.

애플이 아이폰에서 구글을 대체하기 위해 마이크로소프트의 검색 엔진인 빙(Bing)과 거래를 고려하고 있다는 소문이 돌고 있습니다. 또한 애플이 광고 사업에도 뛰어들어 구글의 서비스와 경쟁하기 위해 클라우드 서비스를 확대할 것이라는 소문도 들리고 있습니다. 어디서 많이 들어본 스토리 아닌가요?

네트워크 효과는 권력과 부를 가져오는 방법이 될 수는 있지만 마이크로소프트의 사례에서 볼 수 있듯이 너무 많은 성과는 특권의 지위를 유지하기 위한 방어적이고 망상적 시도로 인해 물거품이 될 수 있습니다. 회사의 최고 심미가이자 완벽주의자가 더 이상 정상적인 의사 결정을 내리지 못하게 되면 과연 애플은 어떤 회사가 될 것인지 많은 전문가들은 의문을 가지고 바라보고 있습니다. 애플이 점점 더 많은 사용자들에게 아이튠즈 앱 스토어만 사용할 수 있는 질이 나쁜 디바이스를 출시하는 회사로 전락되지 않을까 우려되는 바입니다.

- 번역: adobe korea

원문:
Apple is in danger of becoming preoccupied with zero-sum maneuvering versus hated rivals.

Don't look now but this may be the year when Apple's market cap does the unthinkable and surpasses Microsoft's. Congratulations will be in order but so will condolences. For a company preoccupied with products is in danger of becoming a company preoccupied with strategy. And by "strategy," we mean zero-sum maneuvering versus hated rivals.

Oh well, it's a fallen world we live in.

Take the iPad, which instantly shed the moniker "Jesus tablet" once it saw the light of day. It's a blown-up iPod Touch, rolled out not to be insanely great but to give Apple an entry in the netbook derby. The iPad may not be the best Web-browsing machine simply because Apple refuses to support Flash, which delivers 75% of the video on the Web. But the iPad (an anagram for paid) looks like a good device for consuming the e-books, music and video sold through Apple's online service. In fact, let's not mince words: The iPad looks like a device optimized to patronize the iTunes store.

And what about Apple's decision to exclude Flash? Apple and its supporters stake out aesthetic and philosophical grounds: Flash is buggy. Flash is a power hog. Flash is "proprietary" (horrors). Flash is used to create those annoying Web ads (never mind that advertising is what pays for most of the Web).

Uh huh. Flash would also allow iPhone and iPad users to consume video and other entertainment without going through iTunes. Flash would let users freely obtain the kinds of features they can only get now at the Apple App Store.

We hasten to add, before the net-neut crazies and antitrusters seek to perp-walk Steve Jobs, that Apple is perfectly within its rights to do so. But the thing to notice is that Apple is making a strategic choice to cut off its users from a huge amount of Web content. We'll leave Flash's acolytes to defend it against charges of bugginess, etc. Flash has been amazingly successful in crowding out other video players and amazingly successful in getting perhaps a billion PC users to download regular updates. If you want to watch TV shows at Hulu.com or baseball at MLB.com or play games at Facebook, you need Flash.


For now, Adobe, owner of Flash, says it's issuing tools to allow Flash programmers at least to offer their creations through the App Store (provided Apple gives its blessing). Apple insists a forthcoming Web standard will replace the proprietary Flash anyway. We'll see. Flash is installed on 95% of PCs, so its displacement won't happen overnight. And not all browser makers (e.g., Firefox) are on-board with the new standard.

Here's the bigger worry. Apple may be succumbing to the seductive temptations of "network effects," in which the all-consuming goal becomes getting its mobile devices into more and more hands simply for the purpose of locking more and more users into iTunes. Enter nemesis in the form of Google, a company with which Apple was recently allied.

Widely circulated have been remarks by Mr. Jobs at a meeting with Apple employees late last month in which he unceremoniously dumped on Google's "don't be evil" mantra. Apple had played nice, he reportedly said, steering clear of competing with Google in search, while Google traitorously plotted to launch its own mobile devices in order to "kill the iPhone."

Google won't kill the iPhone. The market is plenty big enough to support lots of mobile devices. What's really threatened is Apple's ability to keep convincing tens of millions of consumers to lock themselves into iTunes., the App Store, etc. Not for nothing Google flaunted a mockup of its own slate-like device a few days before the iPad unveiling. And Google's mobile devices support Flash—i.e., they allow users to patronize the video and other Web goodies that Apple users can't.

Rumors abound that Apple is considering a deal with Microsoft's search engine Bing to displace Google on the iPhone. Rumors abound that Apple will get into the advertising business, that it will expand its cloud services to compete with Google's. Who is this beginning to sound like?

Network effects can be a path to power and riches, but (as Microsoft has shown) much of the proceeds can also end up being squandered on defensive and paranoid attempts to secure the privileged position. Pundits have wondered what might become of Apple once its chief aesthete and perfectionist is no longer calling the shots. An Apple that rolls out increasingly junky devices merely to lock more and more customers into the iTunes-App Store mall is one gloomy possibility.


- 본인은 Kevin Lynch의 인터뷰 내용을 모두 수용할 수 없지만 현재 시장 상황에 대한 객관적인 주장과 우려가 담겨 있다고 생각한다. 물론 단적으로 "그럴 것이다"라는 내용에는 일부 선급한 판단일 수도 있을 것이다. IT에서의 표준이란 무엇인가에 대한 정의를 본인은 솔직히 모르겠다. 

- 표준이란?
1. 독점하지 않는 기술?
2. 이해관계가 투명하고 나누워 가질 수 있는 기술?
3. 이미 보편적으로 사용하고 있는 기술?
4. 돈을 받고 팔지 않는 기술?
5. 대체할 만한 기술이 없는 환경?
6. 거대한 기업에서 언급한 표준?
7. 계속적으로 투자할 수 있고 그 가치를 인정하는 기술?


    

설정

트랙백

댓글

스티브잡스의 발언과 플래시의 방향

Programming/Etc 2010. 2. 4. 11:51

Adobe CTO Kevin Lynch 가 Apple 디바이스에 플래시가 탑재하지 않는 것에 대하여 Adobe의 입장을 담았다.

원문 : http://blogs.adobe.com/conversations
/2010/02/open_access_to_content_and_app.html


컨텐츠 및 애플리케이션에 대한 오픈 액세스
게시자: Kevin Lynch, CTO

최근 출시되고 있는 우수한 디바이스에 Flash Player가 탑재되어 있지 않다는 사실에 적잖이 놀랐을 것입니다.
본래 Flash는 시장이 형성되지 않았던 약 15년 전에 펜(Pen) 컴퓨팅 태블릿을 위해 고안되었습니다. 초창기에는 낮은 대역폭의 벡터 그래픽을 지원했지만 지난 십여 년간 새로운 기능을 빠르게 추가해 나가면서, 웹의 틈새 시장을 공략했습니다. 현재는 새로운 활용 방안을 찾는 데 노력을 기울이고 있습니다. 일례로 웹상에서의 애니메이션, 스트리밍 오디오, 풍부한 인터랙션, 임의의 폰트, 양자간 오디오/비디오 커뮤니케이션, 로컬 저장소, 혁신적인 비디오 전달 등이 있습니다.

HTML 기능이 추가된 Flash는 상당히 높은 채택율을 기록하고 있는 가운데, 상위 웹 사이트의 85% 이상에서 Flash 컨텐츠를 사용하고 있으며, 인터넷이 연결된 컴퓨터의 98% 이상에서 Flash가 실행되고 있습니다. Flash는 웹상의 대부분의 캐주얼 게임, 비디오 및 애니메이션에 사용되고 있으며 Nike, Hulu, BBC, Major League Baseball 등 유명 브랜드에서 Flash를 사용하여 10억 이상에 달하는 전세계 사용자에게 매력적인 경험을 전달하고 있습니다.

Flash의 미래에 있어서 지금이 가장 중요한 시기입니다. 현재 PC 외에도 다양한 디바이스들이 하루가 다르게 출시되고 있으며, 많은 수의 디바이스가 인터넷 검색에 사용될 것입니다. 따라서 컨텐츠 및 애플리케이션 제작자와 사용자는 PC에서 Flash를 통해 얻어질 것으로 기대되는 경험, 즉 원활하고 일관되며 풍부한 경험을 디바이스에도 동일하게 전달하기 위해 많은 과제들을 해결해야 할 것입니다. Flash 엔지니어링 팀은 이를 실현하기 위해 다양한 디바이스에서 Flash Player를 철저히 분석해 왔습니다.

이러한 노력의 결과로 Adobe는 시장 선도적인 제조업체를 대상으로 한 스마트폰용 Flash Player 10.1을 선보이려고 합니다. 이러한 제조업체에는 스마트폰 뿐만 아니라 태블릿, 넷북, 인터넷 TV 등 시장을 형성하고 있는 Google의 Android, RIM의 Blackberry, Nokia, Palm Pre, 기타 업체들이 있습니다. Flash를 통해 고객은 전체 웹을 검색할 수 있으므로 브라우저에서 Flash를 사용하고 있는 이러한 디바이스는 경쟁력을 갖추게 됩니다. 이는 사실상 오픈 스크린 프로젝트(Open Screen Project)를 통해 이루어지고 있으며, Adobe는 50여 이상의 파트너와 협력하면서 다양한 디바이스에서 이를 실현하기 위해 노력하고 있습니다. 예를 들어, 최근 선보인 구글 넥서스원(Nexus One)은 Flash Player 10.1을 통해 탁월한 브라우저 경험을 선사할 것입니다.

그렇다면 Apple 디바이스에서 실행 중인 Flash는 어떨까요? Adobe는 Flash 기반으로 iPhone용 독립 실행형 애플리케이션을 구축할 수 있게 함으로써, Flash 기술은 이러한 디바이스에서의 사용을 넓혀 나가기 시작했습니다. 실제로 이러한 애플리케이션 중 일부는 FickleBlox, Chroma Circuit과 같은 Apple App Store(앱스토어)에서 이미 제공되고 있습니다. 이 동일한 솔루션은 iPad에서도 작동될 것입니다. Adobe는 이러한 디바이스의 브라우저에서 Flash를 지원하기 위한 준비를 마친 상태이며 이제 Apple에서 사용자를 위해 이를 허용하는 것만이 남아 있습니다. 그러나 Apple은 지금까지도 어도비의 이러한 협력 요청을 받아들이지 않고 있습니다.

장기적으로 볼 때, Flash에 대한 요구 사항을 대신하게 될 것으로 HTML이 꼽히고 있는 데, 특히 최근 개발된 HTML 5 버전이 출시되면 그 움직임은 본격화될 것으로 전망하는 사람들이 많아지고 있습니다. 그러나 오늘날은 물론이거니와 앞으로도 한 기술이 다른 한 기술을 대체하게 되지는 않을 것으로 예상됩니다.

Adobe는 HTML의 발전을 지원하고 있습니다. 앞으로 HTML이 진화를 거듭할수록 Adobe 소프트웨어에 더 많은 기능이 추가될 것으로 기대하고 있습니다. HTML이 Flash의 기능을 안정적으로 수행할 수 있다면, Adobe는 많은 시간과 수고를 덜 수 있지만, 사실상 그렇게 될 가능성은 거의 없습니다. 비디오 부문의 경우 현재 웹상에 있는 비디오의 75% 이상에서 Flash가 사용되고 있는 데도 불구하고, 브라우저 간 포맷 통일이 이루어질 수 없으므로 사용자와 컨텐츠 제작자는 비호환성이라는 문제를 안게 되고 결국 HTML 비디오 구현은 어두운 뒤안길에 남겨질 것입니다.

HTML의 진보에도 불구하고 Flash의 생산성과 표현 기능은 웹 커뮤니티에서 가희 독보적이라고 할 수 있습니다. Flash 팀은 지난 십여 년간 불가능하다고 여겼던 경험을 구현해 왔던 것처럼 앞으로도 더욱 혁신에 박차를 가할 것입니다. 1년도 채 안 되는 짧은 시간 동안 대다수의 웹 클라이언트를 업데이트할 수 있었던 Flash는 다양한 브라우저 전반에 걸쳐 HTML이 수행하는 것보다 훨씬 빠른 시간 내에 고객에게 이러한 혁신 기술을 선보일 수 있을 것으로 기대를 모으고 있습니다.

Adobe는 시간, 장소, 매체에 구애 받지 않고 아이디어와 정보를 생성하고 전달할 수 있는 방식을 혁신하고 있으며 디자이너와 개발자가 자신의 독창적인 아이디어를 마음껏 펼칠 수 있는 방법을 고안해 내는 데 전력을 다하고 있습니다. 또한 가장 생산성이 우수한 툴과 컨텐츠 및 애플리케이션을 배포할 수 있는 광범위한 기능을 창의적인 관리 방법과 접목시키는 것 또한 Adobe의 미션이라고 할 수 있습니다. Adobe는 고객이 목표를 달성하고 기술 격차를 극복할 수 있는 기술 혁신을 이뤄내는 데 필요한 모든 기술과 포맷을 지원하고 있습니다. Flash와 HTML이 결합되면 최고의 기술이 탄생하게 될 것입니다. 그렇게 되면 누구나 웹상에서 이 기술을 사용하여 최상의 경험을 제공할 수 있게 될 것입니다.

아이디어와 정보를 활용하는 것은 사용자가 선택한 컨텐츠와 애플리케이션을 보고 서로 인터랙션할 수 있는 개방된 에코시스템과 자유가 존재한다는 것을 의미합니다. 이 오픈 액세스 모델은 가장 효율적인 모델로 그간의 여러 시행착오를 거쳐 그 효과가 입증되었습니다. 이와 반대로 폐쇄 모델에서는 사용자가 개별 컨텐츠와 애플리케이션을 보거나 승인 및 거부할 수 있는 사항을 제조업체에서 결정하려고 했습니다. 웹은 디바이스에 상관없이 컨텐츠와 애플리케이션을 일관되게 액세스할 수 있는 개방된 환경으로 존재해야 한다는 데는 이견이 없을 것입니다.

Adobe는 고객들이 최상의 업무 성과를 달성하고 운영 체제, 브라우저 및 다양한 디바이스 전반에 걸쳐 효과적이고 안정적으로 전세계 모든 사용자에게 다가갈 수 있도록 지속적으로 지원해 나갈 것입니다.

번역 : adobe korea


아래 김국현님이 ZDnet에 올린 컬럼 내용이 공감이 갑니다. "후발주자의 입장에서 선두주자에게 타격을 입히는 가장 쉬운 방법은 게임의 룰을 바꿔 버리는 것이다."

http://www.zdnet.co.kr/Contents/2010/02/04/zdnet20100204092647.htm



    

설정

트랙백

댓글

[CS4] 플래시 플레이어 디버거 버전 참고

보통 플래시 콘텐츠를 개발을 할 때, 많은 개발자들이 플래시 플레이어 디버거버전을 설치하여 사용하고 있다. 이유는 개발자가 미처 예상하지 못한 버그나 에러를 확인 하기 위해서 사용한다.

물론 개발자도 사용자인지라 웹서핑 중에 에러창을 확인 해야하는 짜증을 감당하지 못하고 일반 플래시플레이어 버전을 사용하는 개발자도 많은 것 같다. 사실 디버거버전은 개발자들을 위해 엄격한 런타임 환경을 제공하는 것이기 때문에 일반 사용자 환경으로 고려해야하는 대상은 아니라고 할 수 있다. 하지만 다른 개발자들에게 보여질 에러화면을 생각하면 개발자로써 포기할 수 없는 문제이다.

일전에 진행했던 프로젝트에서 예상하지 못한 문제로 골머리를 앓았던 적이 있다. 문제는 이러하다.

컨테이너가 되는 플래시에서 개별적인 컨텐츠 플래시를 로드하여 사용한다. 개별적인 컨텐츠에 해당하는 플래시들은 타임라인에 몇 줄의 코드만 삽입하면 되기 때문에 특별히 document class를 할당하지 않았다. 이런 상태에서 컨테이너에서 개별 플래시들을 로드하여 사용할 경우, 일반 플래시 플레이어에서는 문제가 없지만 디버거 버전에서는 처음 로드한 컨텐츠는 문제가 없으나 이후에 로드하는 컨텐츠에서는 문제가 발생한다.

디버거버전에서는 초기에 로드한 객체를 unload하더라도 이후에 로드하는 플래시가 독립된 document class명이 없다면 기존의 객체로 간주하고 기존 객체가 unload되면서 새로 로드된 객체의 참조 마저도 잃어버리는 현상이 나타난 것이다.

물론 컨테이너에서 로드하는 개별 플래시 내부의 함수를 호출하는 형태이기 때문에 엄밀히 말하면 플래시 플레이어에서 권장하는 설계는 아니다. 그러나 구조상 퍼포먼스를 높이기 위해서는 어쩔 수 없는, 나름대로의 선택이 있었다.

그래서 어쩔수 없이 개별 컨텐츠에 해당하는 플래시에 모두 가상의 document class를 설정하는 것으로 해결했지만 만약에 로드되는 플래시가 기존에 사용했던 document class와 동일한 class명을 사용할 경우 문제가 발생할 여지가 있다.

엄밀히 말하면 동일한 패키지, 네임스페이스 영역 내에 있기 때문에 문제가 발생할 수 밖에 없겠지만 이 하나의 문제로 인하여 유지보수의 복잡성이 증가한 문제는 나에게 무엇을 포기해야 하는가라는 고민을 하게 했다.

결론적으로 디버거버전에서의 문제는 심각한 수준이었기 때문에 플래시플레이어 디버거 버전의 성질을 건드리지 않는 쪽으로 일단락 되었다.

iPhone 에서 작성된 글입니다.
    

설정

트랙백

댓글

[CS4] Flash10에서 추가된 Loader 객체의 unloadAndStop 메소드

Programming/ActionScript 3.0[CS4] 2009. 11. 10. 21:11

function unloadAndStop(gc:Boolean = true):void

기존에 unload 메소드의 경우 load 메소드를 사용하여 로드된 Loader 객체의 자식을 제거할 수 있었으나 해당 자식이 다른 객체로부터 참조가 남아 있을 경우에는 메모리상에서 완전히 제거할 수 없었다. 따라서 부모 swf에서 또 다른 자식 swf를 로드할 경우, Event.UNLOAD 이벤트를 받아서 unload가 발생할 때 남아있는 스트림을 닫거나 이벤트 리스너를 일일히 제거해줘야 하는 개발자의 부담이 있었다.

구현된 형태가 복잡할 경우 사실상 완전하게 제거하는 것이 불가능할 정도다. 이로 인해서 참조가 남아 있을 경우, 메모리 리스크가 발생하고 남아 있는 객체에서 프레임이 돌고 있는 상황이라면 결과적으로 CPU 사용량도 계속적으로 쌓이게 되는 문제가 있었다.

이러한 문제를 해결하기 위해서 Flash10버전에서는 Loader 객체에 unloadAndStop 함수가 추가 되었는데 unloadAndStop함수는 unload로 완전하게 제거할 수 없었던 자식의 참조를 삭제하여 메모리가 쌓이는 현상을 해결할 수가 있다. 아래는 플래시 도움말에 있는 내용이다.

/////////////////////////////////////////////////
unloadAndStop () 메서드  
flash10 function unloadAndStop(gc:Boolean = true):void
언어 버전:  ActionScript 3.0
런타임 버전:  AIR 1.0, Flash Player 9

자식 SWF 파일 내용을 언로드하고 로드된 SWF 파일의 명령 실행을 중지합니다. 이 메서드는 자식 SWF 파일의 EventDispatcher, NetConnection, Timer, Sound 또는 Video 객체에 대한 참조를 제거하여 Loader.load() 또는 Loader.loadBytes()를 사용하여 로드되고 있는 SWF 파일을 언로드합니다. 따라서 자식 SWF 파일 및 자식 SWF 파일의 표시 목록에서 다음 동작이 발생합니다.

•사운드가 중지됩니다.
•Stage 이벤트 리스너가 제거됩니다.
•enterFrame, frameConstructed, exitFrame, activate 및 deactivate의 이벤트 리스너가 제거됩니다.
•타이머가 중지됩니다.
•Camera 및 Microphone 인스턴스가 분리됩니다.
•무비 클립이 중지됩니다.

매개 변수
gc:Boolean (default = true) — 자식 SWF 객체를 대상으로 가비지 수집기를 실행할지 여부(true 또는 false)를 나타내는 힌트를 제공합니다. 여러 객체를 비동기적으로 언로드하는 경우 gc 매개 변수를 false로 설정하면 응용 프로그램 성능이 향상될 수 있습니다. 그러나 이 매개 변수를 false로 설정하면 자식 SWF 파일의 미디어와 표시 객체가 unloadAndStop() 명령을 실행한 후에도 메모리에 유지될 수 있습니다.
/////////////////////////////////////////////////

이 메소드를 이용하면 그 동안 swf로드하는 과정에서 발생했던 메모리 리스크는 어느 정도 해결 할 수가 있게 되었다.

    

설정

트랙백

댓글

네이트 앱스토어 공모전

Programming/Etc 2009. 10. 30. 20:39

요즘 프로젝트 일정으로 많이 바쁜 생활을 하고 있지만 플래시 개발자들에게 재미있는 서비스를 하나 소개할까 합니다. 소개하고자 하는 서비스가 공교롭게도 네이트 서비스입니다만, ^^ 그렇기 때문에 소개하는 것은 아닙니다. 플래시 개발자들에게는 재미있는 경험이 될 수도 있을 것 같고, 더 나아가서는 개인적으로 개발한 어플리케이션으로 수입을 창출할 수도 있는 서비스이기에 소개를 합니다.

네이트에 접속해 보시면 앱스토어라는 개발자 놀이터가 생겼습니다. 네이트 앱스토어는 쉽게 말해서 사용자의 정보(본인 개인정보, 일촌 정보 등등)을 이용하여 다양한 어플리케이션을 만들 수 있습니다.




간단한 예를 들면, 게임을 진행하고 본인의 랭킹과 일촌들의 랭킹을 확인할 수가 있고, 일촌에게 도전장을 발송할 수도 있습니다. 플래시는 웹에서 접근하기에 간단하면서도 중독성이 강한 게임들을 만들 수 있는 좋은 툴이죠, 물론 게임뿐만이 아니라 OpenAPI로 제공하는 데이터들을 활용하여 다양한 어플리케이션을 만들고 싸이월드의 수많은 사용자들과 함께 참여할 수 있습니다.

소셜 네트워크를 이용하고, 페이먼트 시스템(도토리)을 적용하여 만든 게임으로 수입이 발생할 수도 있습니다. 네이트 앱스토어가 서비스를 라이브한지 얼마 되지 않은 beta 서비스이지만, 현재 페이먼트 시스템을 적용한 게임의 경우 하루에 적지 않은 수입이 발생하고 있다고 합니다. 개발자의 말초신경을 자극하는 대목이지요^^

네이트가 소셜 네트워크를 이용하여 개발자들이 놀 수 있는 공간을 만든 것은 개인적으로 바람직한 현상(!) 이라고 생각합니다.

이번에 2009년 제1회 네이트 앱스토어 앱스 공모전이 있습니다. 이에 맞춰서 제2회 개발자 세미나(Hello, Dev.Square)가 진행될 예정이라고 합니다. 현재 아래 경로에서 선착순으로 모집을 하고 있으니 관심이 있으신 분들은 참여해 보시기 바랍니다.

2009 제 1회 네이트 앱스토어 앱스 공모전

1. 참가 대상
   - 대학생, 직장인 등 개인자격으로 참여 가능.
   - 팀을 구성할 수 있으며 팀 제한은 4명 이내로 함

2. 시상 내역


3. 진행 일정
   - 앱스 제작 설명회 : 2009년 11월 12일 [시간/장소 별도 공지예정]
   - 앱스 접수 : 2009년 12월 12일~12월 21일
   - 심사 : 2009년 12월 22일~ 12월 29일
   - 발표 : 2009년 12월 30일
   - 시상 : 별도 공지
 
4. 접수 방법
   - http://devsquare.nate.com 통해서 접수
   - OpenSocial API v0.81기반으로 앱스 개발
   - 필수 활용 API : 친구목록 API

5. 심사 기준
    (앱스가 꼭 복잡할 필요는 없어요! 간단할수록, 그래서 쉽고 재미있다면 많은 점수를 받을 수 있습니다.)
   - Social Network를 활용하여 일촌들이 함께 즐길 수 있는가?
   - 앱스 이용방법이 쉽고 간단하여 누구나 쓸 수 있는가?
   - 재미있고 유쾌한 사용 경험을 제공하는가?
   - 아이디어가 얼마나 새롭고 창의적인가?
=========================

앱스토어 관련 정보 경로

네이트 앱스토어 섹션페이지
http://appstore.nate.com/

개발자 등록 및 개발 가이드 페이지
http://devsquare.nate.com/

Dev.Square Forum_앱스정복을 꿈꾸는 개발자 세상
http://club.cyworld.com/club/main/club_main.asp?club_id=53489290

저도 시간이 허락된다면 좋은 아이디어가 있을 때마다 실행해볼 예정입니다.

    

설정

트랙백

댓글

즐거운 만남 두 번째 이야기

액션스크립트까페에서 주관한 2차 컨퍼런스가 Adobe의 후원으로 강남 교보타워에서 열렸다. 하반기에 일복이 터져 준비를 제대로 하지 못하고 소통을 한 것 같아서 아쉬웠던 시간 이었다. 짧은 시간에 많은 것을 공유하고자 했던 것이 오히려 많은 분들에게 도움이 되지 않은 것은 아닌지 약간 걱정이 되기도…

항상 좋은 자리를 마련해주시는 땡굴이형님과 스탭분들 준비하시느라 고생 많으셨습니다. 특히 바쁜 업무에도 주어진 시간을 멋지게 소통하신 블랙키즈님, 언노운님, 땡굴이형님 고생 많으셨습니다. 그리고 황금 같은 주말을 반납하고 오래도록 자리를 빛내주신 참가자분들도 고맙고 반가웠습니다.






출처 : 마넴이리님

출처 : 마넴이리님



다음에 또 기회가 있다면 저에게 주어진 시간을 효율적으로 사용해 보도록 하겠습니다. 항상 아쉬움이 남네요 ^^;
감사합니다.

    

설정

트랙백

댓글

2009년 6월 18일 Tweener의 개발종료를 선언하다.

Programming/ActionScript 3.0 2009. 8. 20. 00:15

본인이 ActionScript 3.0을 처음 접할 때 사막의 오아시스처럼 큰 도움을 주었던 Tweener 라이브러리가 최종 버전을 끝으로 개발을 종료한다고 한다. 현재 본인은 TweenLite, TweenMax를 사용하고 있지만 ActionScript 3.0을 재미있게 공부하고, 연구할 수 있도록 나에게 동기를 준 멋진 라이브러리가 아닌가 생각한다.

MC Tween 시절부터 플래시의 발전 속에서 역사가 깊은 라이브러리이기에 여러 가지 생각이 머리 속에서 스쳐 지나간다. Zeh Fernando씨에게 박수를 보낸다. 아래는 원문을 번역한 내용이다. 명확히 알 수 없는 내용은 포함하지 않았으며 일부 문장은 나름대로 재 해석한 관계로 내용 전달이 정확하지 않을 수도 있지만 전체적인 요점은 파악할 수 있을 것이라 생각한다.


========================================================================================
원문 : Zeh Fernando Blog Archive Tweener, 4 years later - A post mortem

우선 시작부터 이야기 하자면 나는 몇 년 전에 Flash 개발 과정에서 애니메이션이 필요하여 MC Tween를 개발했다. MC Tween는 ActionScript의 기본적인 tween을 확장하여 사용했다. 당시에 뛰어난 tween 확장 기능이 존재하고 있었지만 모두 나의 취향과 맞지 않았다. API의 대부분이 너무 추상적이었고 내가 요구하는 것과 달랐기 때문에 prototype 형식을 채용하여 MovieClip의 오브젝트형에 새로운 기능을 추가해서 만들었다. MovieClip에 새로운 기능을 추가하는 형태에 찬사를 주는 사람들이 있었기 때문에 그만한 인기를 얻을 수 있었다.

그러나 2005년 해가 되면서 MC Tween의 변화가 필요하게 되었다. MC Tween은 의도대로 움직이고 있었지만 ActionScript의 문법이나 패러다임(특히 AS2의 등장)이 변화하고 객체지향프로그래밍을 이해하기 시작하면서 MC Tween은 이미 나의 개발 워크플로우에 맞지 않는다는 것을 깨닫게 되었다. 더욱이 MC Tween의 개발이 꽤 정체되어 있었다.

그러던 그 해 6월부터 나는 클래스를 사용하여 새롭게 tween 확장 기능을 실험적으로 개발하기로 했다. 개발 당초에는 인스턴스 베이스(tween 인스턴스를 생성)였지만 이후에 addTween() 이라는 하나의 메소드에 의해서 모든 tween을 생성하는 정적인 클래스 구조로 변경했다. 그리고 stopTween(), getTween()과 같은 부속 메소드를 사용하여 여러 가지 기능을 조작할 수 있도록 했다.

이후에도 클래스는 매우 많은 변경이 있었다. 클래스명이 바뀌거나(초기에는 Twina였던 것이 Tweener가 되고 ZTweener가 되었다가 다시 Tweener로 되돌아옴)  패키지의 위치가 바뀌거나(generic *에서 zeh.easing.*으로, 그리고 다시 caurina.transitions.*)  API가 변경되거나 인스턴스 베이스에서 정적 클래스로 변경한 것은 말할 것도 없고 그 외에도 내부 구조의 변경 등이 많이 있었다. 이러한 과정에서 스스로가 많이 배웠다는 것이 이 글의 취지이지만 자신을 위해서 무엇인가를 만드는 경우, 결과를 누군가가 보고 평가하거나 더욱이 그것을 누군가가 매우 소중한 일에 사용하지 않을 것이라고 생각하고 만든다면 결과적으로 많은 실수를 허용하게 된다. 그러나 그 과정에서 보다 좋은 방법을 찾아내게 되는 것이다.

내가 이 프로젝트를 시작했을 무렵, tween 확장 기능으로서 제일 유명했던 것은 Fuse Kit이였다. 나는 이것과 겨룬다는 생각은 없었다. 다만 나 자신을 위해서 무엇인가를 만들고 자신의 요구에 맞게 변경해 나가는 자유를 즐기고 있었다. Tweener는 긴 시간동안 비공개(나 자신만 사용) 였던 것이 그러한 이유다. 무엇보다 Gringo를 위한 프로젝트를 위해서 사용하고 있었지만 공개된 것은 2007년 1월 최초의 버전을 개발하고 나서 대략 2년 후였다. Nate Chatellier가 팀에 참가하여 AS3버전의 Tweener를 만들었었기에 이대로 비공개로 하는 것은 공정하지 않다고 생각했다. 더욱이 그 시점에서 생각하기에 앞으로 API에는 큰 변화가 있을 것 같지 않았기 때문에 다른 사람들로부터 피드백을 받고 싶은 생각도 있었다.

Tweener는 특별히 참신한 것도 아니고 API는 새로운 것이 없었다. Tweener가 채용한 새로운 tween생성 방식도 다른 tween의 확장에서도 채용되고 있었다. AS1 베이스 확장에서도 채용되고 있었다. 그렇지만 그것은 그 시기에 올바른 구문이었다. 그러한 형태는 인기가 있었고 다른 언어판까지 나오게 되었다.

이는 4년전의 이야기.(로그를 보면 Tweener은 2005년 6월 15일에 개발 개시한 것으로 되어 있다.) 현재는 이 밖에도 많은 tween 확장판이 등장하고 있고, 특히 유명한 것은 Go, TweenLite / TweenMax, GTween, BetweenAS3 등이 있다. 라고 하는 것은? 그래, 또 그 때가 찾아왔다고 하는 것이다. 현재와 같이 AS3버전이 있다고 해도 Tweener가 가지는 패러다임의 대부분은 이미 시대에 뒤떨어져 버렸다. 나는 점점 불안을 느끼게 되었다. 나는 그동안 많은 것을 배웠다. 이제 움직이기 시작할 때다.

바로 움직이기 시작할 수도 있었지만, 그 전에 되돌아보고, 잘 된 것, 가지 않았던 것을 되짚어 보려고 했다. 이 글은 말하자면 Tweener의 사망선고 글, 4년간 내가 무엇을 배웠고, Tweener와 같은 라이브러리가 어떻게 변화해 왔는가 하는 점에 대한 나름의 분석이다.

그런데 AS2에서 AS3로 이동하는 시점에 고려해야 할 중요한 포인트가 한 개 있다. ‘에러’다. AS2 에러는 null 오브젝트의 프로퍼티를 변경하는 스크립트를 실행해도 FlashPlayer는 그대로 지나쳐 버린다. 물론 오브젝트가 존재하지 않기 때문에 스크립트 자체는 기능하지 않지만 그것을 알려주는 에러 메시지가 없다.

이것은 엄밀한 동작이 기대되는 경우에는 문제가 된다. 취득한 데이터가 의도한 것인지를 알기 위해서는 몇 개의 레벨의 검증이 필요하고, 그렇게 해서 다른 방법으로 유저에게 경고를 보낼 수 있었다. Tweener의 AS2 버전에서는 유저에게 보다 안전하게 동작할 수 있도록 노력했다. 구체적으로는 tween 중에 대상이 되는 오브젝트가 존재하는지를 체크하고, tween 되고 있는 프로퍼티에 디폴트의 값이 설정되어 있는지를 체크하고 있다.

하지만 AS3 버전으로 만들면서 그 기능은 필요 없게 되었다. 존재하지 않는 오브젝트나 프로퍼티에 액세스 하려고 하면 코드의 실행은 중단되게 되었다. 이것은 좋은 일이다. 유저가 자신이 무엇인가 실수를 범하고 있고, 그것을 수정하지 않으면 안 된다고 하는 것을 이해하는데 도움이 되기 때문이다.

한편, AS3 버전으로 임포트하는 시점에 Tweener는 이러한 AS2의 패러다임을 계승해 버렸다. 조금 전에 쓴 것과 같이 체크 기능도 많이 남아 있다. 또한 존재하지 않는 프롭퍼티의 값을 tween하려고 하면 FlashPlayer의 에러가 아닌, Tweener 내에서 설정한 커스텀 에러를 표시하게 되어 있다.

if (rScopes[0][istr] == undefined) {
     printError("The property '" + istr + "' doesn't seem to be a normal object property of " + String(rScopes[0]) + " or a registered special property.");
}

속성을 업데이트하기 위한 반복 루프에서도 마찬가지다. 업데이트하는 개체가 있는지 확인하고, 속성이 존재하는지 확인하고 있다. 이 방식으로 인하여 성능이 저하되고, 크기가 증가라는 부작용도 제기됐다.

새로운 tween을 적용할 때, Tweener는 비슷한 tween (동일한 개체의 동일한 속성에 적용하는 tween)이 있는지를 찾아 그들을 제거하려고 한다. 별도로 애니메이션을 하기 위해 요구되는 행동이지만, 이로 인해서 2개의 문제가 발생한다. 먼저 tween 덮어쓰기를 강제로 실행하면서 옵션은 없다는 것, 그리고 새 tween을 생성할 때 성능을 크게 저하 시킨다는 것, 이미 많은 tween이 동일한 위치에 있는 경우에는 더욱 그러하다.

최근 tween 엔진 성능을 비교해보면 문제는 더 명백해 진다. 실제 tween 갱신에 소요되는 시간과 메모리 소비 등은 나쁘지 않지만, 생성 tween 양이 늘어나면 늘어날수록 Tweener 처리는 느려진다. 새로운 tween이 생성될 때마다 기존의 모든 tween과 충돌을 체크하기 때문에 tween 생성에 소요되는 시간이 증가하는 것이다. tween 수가 1000을 초과한 상태에서 새 tween을 생성하려고 하면, 애니메이션 자체의 소요 시간을 초과하거나 FlashPlayer가 잠깐 멈추는 경우도 종종 있다. Tweener는 tween 목록을 단지 하나의 배열에 관리하고 있기 때문이다. 더 유용한 AS3 기본 기술을 이용하여 위 사항은 해결할 수 있는지도 모른다. 어쨌든 Tweener은 너무 안전하게 작동하려고 한다. 사용자가 성능을 향상시키고 싶은 처리를 허용하지 않는다.

오늘 Tweener에 대해 언급하는 것은 더 이상 최적화 문제가 아니라고 생각하기 때문이다. 보완할 수는 있다. 몇 가지 검사하는 기능을 제거, 또는 Array 대신 Dictionary와 같은 AS3의 새로운 기능을 추가하여 목록을 관리하거나, Vector 기능을 추가하거나 할 수 있다. 하지만 솔직히 말해서 Tweener는 그 전성기가 끝났다고 나는 확신한다. 그렇기 때문에 그러한 변경을 해도 곧바로 모든 것이 단순히 해소될 수 없다. 그러니 더 이상 Tweener을 업데이트 하는 것은 무의미하다. 물론(특히 동시에 1000개 이상 같은 tween을 수행할 필요가 없는 경우) 현재도 작동하고, 앞으로도 계속 도움이 될 것이다.

숨어 있던 새로운 버그가 나타나지 않는다면 Tweener를 업데이트할 생각이 없지만 최근에 있었던 이슈들을 업데이트했다. 새로운 버전의 1.33.74 Google Code 프로젝트 페이지 subversion 서버에 공개된다. 이 업데이트는 기본 tween 덮어쓰기 내용은 남겨두면서 overwrite라는 새로운 매개 변수를 추가하고 (이 값을 true로 하면 그 동안의 기능과 같다.) autoOverwrite는 새로운 정적 속성을 추가했다.

Tweener Comparison

위 그림에서 파란색 그래프는 tween없는 상태를, 오렌지 그래프는 Tweener 1.31.74를, 노란색 그래프는 Tweener 1.33.74에서 overwriting을 false로 설정한 상황을 보여주고 있다.

대단한 일이 아닐지라도, 이것은 이 프로젝트에 참여했던 몇 년간 내가 받은 지원, 조언, 배움, 그리고 훌륭한 경험에 대한 감사의 표시로 받아들여 주길 바란다. 프로젝트를 직접 지원해 준 회원 뿐 아니라, 이 프로젝트를 다양한 측면에서 지원해 준 모든 분들에게 진심으로 감사한 마음이다.

내가 Tweener의 개발을 Google Code 사이트로 옮긴 후부터 집계해온 재미있는 그래프를 보여 주겠다. 이것은 버전별 안정 버전 Tweener 다운로드 비율(전체 다운로드 회수)을 비교한 것이다. AS3가 차지하는 비중이 늘고 있다는 것을 알 수 있다. 덧붙여서,

Tweener download statistics

오늘 출시 버전은 포함하지 않았다.

Tweener download statistics

후기로 여러분에게 전달하고자 하는 것이 있다. 나는 현재 tween에 있어서 개인적으로는 Tweener에 의해 소개된 것과 다른 접근을 사용하고 있다. 내 자신의 워크플로우는 조금 바뀌었다. 색 트윈 및 기타 특별한 지름길은 사용하지 않는다. 대신 독립적인 클래스와 getter / setter 및 decorator 등을 통한 특정 기능을 사용하게 되었다. 내가 Tweener를 개발한 이유는, 자신의 개발 흐름에 맞게 무언가를 적용하고, 수요가 있으면 다른 사람들이 사용할 수 있도록 하는 즐거움에 있었다. Tweener를 공개하는 데 많은 시간을 할애한 것은 그 때문이다. 나는 현재, 모든 사람의 요구에 부응하기 위해 만들어진 것을 사용하기보다는, 특정한 누구를 위해 만들어진 것을 사용하는 것을 선호한다.

분명한 것은, "Tweener2"나 그런 것은 나오지 않는다는 것이다.
다시 한번 감사합니다!

========================================================================================

세상의 모든 것들은 시간의 흐름에 따라 변화하고, 소멸하고, 다시 새로운 것이 탄생하기를 반복한다. 플래시의 경우도 예외가 아니다. 플래시는 1년이 멀다 하고 새로운 API와, 흥미로운 기능들이 추가되며 발전해 왔다. 하지만 그 화려한 변신에 가려진 개발자들의 눈물겨운 노력은 일반 사람들에게는 잘 알려지지 않는다. 더욱이 플래시라는 분야를 재미없는, 해야만 하는 일로 생각하는 개발자라면 그 정도는 더욱 심했을 것이다.

Zeh Fernando씨가 Tweener의 사망선고하는 글을 올리기까지 얼마나 많은 노력과 시간을 투자했을지, 그리고 스스로에게 의미가 있는 프로젝트를 종료하기까지 많은 고민과 생각을 했으리라. 다시 한번 멋진 프로젝트를 진행했던 Zeh Fernando씨에게 박수를 보낸다.

어쩌면 Zeh Fernando씨가 우리에게 도움을 준 것 보다 Tweener를 의미 있는 작업에 활용하며 피드백을 주었던 수 많은 사람들로부터 받은 관심이 Zeh Fernando씨가 불특정 다수에게 감사를 표하는 가장 큰 이유일 것이다. Tweener는 종료되었지만 앞으로도 더욱 다양한 작품으로 만날 것을 기대해 본다.

    

설정

트랙백

댓글

애플 아이폰/아이팟터치 앱 영상 리뷰 커뮤니티 “앱톡” 오픈

Programming/Mobile 2009. 6. 18. 18:11


애플 아이폰/아이팟터치의 앱스토어에 등록되어 있는 다양한 어플리케이션들의 정보를 공유할 수 있는 커뮤니케이션 사이트가 공식 오픈 했다. 활용도가 높은 다양한 어플리케이션 정보를 쉽게 접할 수 있고 리뷰를 통해 간접 체험을 할 수 있어서 많은 애플 아이폰/아이팟터치 유저들에게 반가운 소식일 듯 싶다. 아래는 관련 사이트 오픈 소식 내용을 발췌했다.

- 국내 개발자들의 앱 홍보 출구도 마련
- 사이트 오픈 이벤트 "앱의 달인을 찾아라", "앱 리뷰" 진행

2009년 6월 18일 (서울) ----- 애플 아이팟터치 및 아이폰 기반 애플리케이션을 영상으로 소개하는 ‘앱톡(www.apptalk.tv)’ 서비스가 오늘(18일) 공식 오픈했다.  앱톡은 애플의 앱스토어에 소개된 다양한 애플리케이션들을 영상으로 소개하는 사용자 영상 리뷰 커뮤니티이다.

앱톡에서는 모든 애플리케이션의 소개를 HD급 고화질 영상 컨텐츠로 제작, 사용자가 아이팟터치의 애플리케이션을 구매하기 전 간접 체험할 수 있는 서비스를 제공하는 것이 특징이다. 특히 미국 및 한국 앱스토어의 상위 랭킹 애플리케이션 가운데 활용도 높은 애플리케이션을 중심으로 ‘영상 리뷰’ 정보를 제공하고 있다.

이와 함께 한국 개발자가 만든 애플리케이션을 공개적으로 소개하고 홍보할 수 있는 ‘앱코리아’와 아이팟터치 애플리케이션을 자유자재로 활용하는 ‘앱의 달인’ 코너를 별도로 마련해 한국의 앱 개발자와 앱 마니아를 발굴하는데 힘을 싣는다.

앱톡의 박지훈 부장은 “애플 앱스토어를 통해 전세계적으로 앱들이 10억 이상 다운로드 됐으며, 하루에도 수백 개의 앱들이 업로드 되고 있다”며, “스마트폰의 앱이 사람들의 라이프 스타일 변화를 주도하고 있다. 이러한 트랜드에 맞춰 앱톡은 고화질 영상 서비스를 제공하며 앱을 통해 사람들의 라이프 스타일이 더욱 즐겁고 스마트해질 수 있도록 서비스 할 계획”이라고 말했다.

한편, 앱톡에서는 사이트 오픈 기념으로 오는 7월 17일(금)까지 앱 전문가를 선발하는 ‘앱의 달인을 찾아라’와 자신이 평소 즐겨 사용하는 앱이 있다면 누구나 참여할 수 있는 ‘앱 리뷰’ 이벤트를 진행, 290명에게 푸짐한 상품을 제공한다. 자세한 내용은 앱톡 사이트(www.apptalk.tv)를 통해 확인할 수 있다.

    

설정

트랙백

댓글

정보의 가시화 그리고 플래시 개발자의 역할

Programming/ActionScript 3.0 2009. 5. 31. 08:12


정보의 가시화.
컴퓨터가 발달하지 않았던 시대에는 그래프의 탄생이 정보의 가시화에 혁명처럼 다가왔던 시대가 있었다. 그로부터 몇 백 년이 지난 지금은 어떠할까, 컴퓨터가 발달하고 인터넷이 빠르게 발전하면서 대량의 정보, 그 자체를 분석하고 처리하는 능력은 그때와는 비교도 할 수 없을 정도로 발전했지만 아직까지도 정보를 효과적이고 완벽하게 가시화 할 수 있는 방법은 존재하지 않는 것 같다. 가면 갈수록 컴퓨터의 정보처리 능력과 더불어 인문학이 주요 이슈로 떠오르고 있는 이유도 여기에 있는 것이 아닐까.

데이터는 데이터 자체로 의미를 지닐 수는 없다. 데이터는 인간이 이해할 수 있는 것으로부터 그 가치를 가지게 된다, 그렇다면 데이터를 인간이 이해하기 편하게 표현하려면 어떻게 해야 할까.

정보 가시화에 필요한 기본적인 시각 요소들은 사이즈, 색채, 관련성, 좌표 등이 있다. 흑백 인쇄와 같이 제한적인 환경이 아닌 인터넷에서는 이러한 기본적인 시각 요소들을 다양하게 사용할 수 있다. 더욱이 모든 이용자의 접근성을 위한 대체 컨텐츠를 제공 해야 하는 부담을 줄이기 위해서는 앞에서 열거한 모든 요소들을 적절히 활용하는 것이 필요하다.



또한 인터넷 매체로 넘어오면서 정보를 단순히 가시화해서 보여주는 것에 머무르지 않고 사용자와 시스템간에 상호 의사소통을 함으로써 인간이 데이터를 이해하는데 보다 많은 도움을 주고 있다. 그러한 관점에서 본다면 플래시는 이러한 시대를 제대로 만났다고 할 수 있다. 플래시는 발전을 거듭하면서 데이터 분석과 처리를 효율적으로 수행하고 있으며 플래시만의 특화된 디자인적인 요소를 충분히 활용함으로써 다양한 시각화를 표현 할 수 있게 되었다. 물론 좋은 펜을 가지고 있다고 하여 글을 잘 쓰는 것은 아니겠지만 정보를 효과적으로 가시화할 수 있는 발판을 마련했다는 점에서 의미가 있다고 하겠다.

플래시는 앞으로도 많은 발전을 거듭하겠지만 그 동안은 도구 자체로써 발전을 했다면 이제는 그 도구를 최대한 활용하여 효과적이고 최적화된 콘텐츠를 생산하는 인력을 키우는데 노력 해야 할 것이다. 앞에서 언급한 것처럼 정보는 정보 자체로 그 의미를 지닐 수 없듯이 말이다.

플래시 개발자의 역할.
위에서 말한 효과적인 컨텐츠를 생산하기 위해서는 플래시 개발자에게는 다양한 역량을 요구하게 된다. 플래시 기술을 보유한 엔지니어를 넘어 정보를 어떻게 가공하여 가시화 할 것인가에 대한 근본적인 문제를 효과적으로 구상할 수 있는 기획력, 그리고 그러한 표현을 현실화 할 수 있는 디자인 능력이 요구된다. 물론 요즘은 전문적인 역량을 요구하게 되면서 각 분야의 기술력이 높아졌지만 그러한 업무 분담 시스템으로 인해 결과적으로는 컨텐츠의 퀄리티가 매끄럽지 않은 경우가 많이 발생한다.

이런 문제점을 보완하기 위해서는 플래시 개발자뿐만 아니라 모든 작업자는 수동적인 작업자가 되어서는 안 된다고 생각한다. 각 분야의 전문가들의 의견을 최대한 수렴하고 존중하되, 기획, 디자인, 플래시 기술을 떠나서 최종 사용자의 입장에서 문제점을 지적하고 더 나은 결과물을 얻기 위해 노력해야 한다. 따라서 끊임없이 각 분야의 전문가들과 커뮤니케이션을 해야 하는 것이다.

사실 본인 또한 다른 작업자들을 설득하는 것에 많은 부담을 갖는 것이 사실이다. 하지만 주관적인 자신의 생각이 아닌, 사용자의 입장에서 충분히 생각하고 제시하는 객관적인 설득은 다른 작업자들도 충분히 공감을 할 수 있을 것이라고 믿는다.

플래시라는 기술은 업무의 특정이 완벽하게 구분되는 분야가 아니다. 구조적인 부분에서는 기획, 비주얼 부분에서는 디자인, 기술적인 부분에서는 프로그래밍을 항상 고민해야 하는 특성이 있다. 따라서 플래시 개발자의 역할은 모든 작업자들에게 보다 많은 커뮤니케이션을 유도하는 윤활유 역할을 수행할 필요가 있다.

각 분야의 전문가들은 자신이 바라보는 관점에서 욕심을 내기 마련이다. 하지만 그 욕심이 해당 프로젝트가 나아갈 방향에 부합하지 않거나, 사용자의 사용 패턴을 충분히 고려하지 않은 욕심이라면 다시 생각해볼 필요가 있다. 보통 일선에서는 이러한 역할을 기획에서 하는 경우가 많지만 기획자의 역량에도 한계가 있기 때문에 무조건 기획자에게 책임을 전가해서는 안 된다고 생각 한다.

사실 본인도 그러한 역할을 조금이나마 수행하기 위해서 노력은 하고 있지만 커뮤니케이션 스킬이 많이 부족하다 보니 어려움이 많은 것이 사실이다. 하지만 이러한 노력조차 하지 않는다면 해당 프로젝트는 철학이 없는 이벤트로 끝날 가능성이 크다고 생각한다.

따라서 플래시 개발자는 모든 작업자의 편의를 위해 개발하기 보다는 최종 결과물을 받아들이는 사용자 입장을 항상 고민하고, 그것이 완벽하게 옳다고 스스로 판단되지 않을 경우에는 프로젝트의 완성도를 위한 커뮤니케이션을 회피해서는 안될 것이다.

물론 현실적으로 어려움이 있는 것은 사실이다. 프로젝트의 일정상 어려움도 있을 것이고 커뮤니케이션 과정에서 다른 작업자의 영역을 침범한다고 좋지 않게 바라볼 수도 있다. 하지만 자신이 옳다고 판단하는 것에 대해 다양한 의견을 들어보는 것만으로도 프로젝트 뿐만이 아니라 모든 작업자들에게 도움이 될 것이라고 생각한다.


 

    

설정

트랙백

댓글

AIR 애플리케이션 경연대회

Programming/AIR 2009. 4. 30. 14:37
부득이한 사정으로 ACC 모임에 항상 불참하게 되어 소식이 늦는 듯 하다. 이번에 adobe RIA 공식 사이트에서 AIR 애플리케이션 경연대회를 진행한다. 본인의 멋진 아이디어를 다른 개발자들과 공유할 수 있는 좋은 기회가 될 것으로 보인다. 개인적으로 경품은 썩 마음에 들지는 않지만 이런 대회의 좋은 점은 경품 보다는 그 주변에 있기에 충분히 응모해 볼만한 가치가 있다. 본인도 응모하고 싶지만 자격이 없는 것 같다.

<경품>
대상(1팀) : Adobe Flash CS4 Professional 1copy, 상장 수여
최우수상(1팀) : Adobe Flex Builder 3 Professional 1copy, 상장 수여
우수상(1팀) : Filco Majestouch 기계식 키보드, 상장 수여
장려상(4팀) : 우야꼬의 Flash CS4로 만드는 AIR 1.5 서적, 상장 수여
 
<특전>
입상한 7팀 중 대상 1팀과 최우수상 1팀에게는 2010년 ACC(Adobe Community Champion) 후보가 될수 있는 자격을 부여해 드립니다.
 
<일정> 
선정기준 : 응모된 작품 중 ACC(Adobe Community Champion)이 심사해 7건을 선정
마감 : 2009년 5월 17일까지
입상작 발표 :  2009년 5월 25일
현장심사, 발표 : 2009년 5월 28일
 
<선정 과정>
1. 접수된 작품 중 ACC 사전심사를 실시해 1차 7팀의 작품을 선정한다.
2. 7팀의 작품을 가지고 최종 발표회 심사를 실시해 대상을 선정한다.
 
<심사기준>
작품의 기술성(40)
-데스크톱 리소스 응용도(20) : AIR의 장점인 데스크톱의 리소스를 효과적으로 응용하는가?
-성능(10) : 애플리케이션의 성능이 이용에 불편없는가?
-완성도(10) : 구현하고자 하는 기능과 제출문서 등이 모두 완성되었는가?
주제의 창의성(20) : 기존 애플리케이션과 주제면에서 차별화되는가?
작품의 활용성(20) : 사용자의 생활에 도움을 주는 애플리케이션인가?
사용자 편의성(20) : 사용자가 이용하는데 효과적인 UI로 구성되었는가?

응모 방법 및 자세한 사항은 아래 웹 경로에서 확인 할 수 있다.
http://www.adoberia.co.kr/iwt/blog/blog.php?tn=flex&id=302
    

설정

트랙백

댓글

[CS4] Vector의 이해

FlashCS4(FlashPlayer10) 버전에서 지원하고 있는 Vector 객체에 대해서 정확히 무엇이며 어떤 역할을 하는지에 관한 자료를 정리하는 차원에서 이야기 해 볼까 한다.

일단 아래는 FlashPlayer10 레퍼런스 문서에 있는 Vector에 관한 기본 내용이다.











----------------------------------------------------------------
Vector 클래스를 사용하면 벡터에 액세스하고 이를 조작할 수 있습니다. 벡터는 요소의 데이터 유형이 모두 같은 배열입니다. 요소의 데이터 유형을 Vector의 기본 유형이라고 합니다. 기본 유형은 내장 클래스 및 사용자 정의 클래스를 포함한 모든 클래스일 수 있습니다. 기본 유형은 Vector 변수를 선언할 때 및 클래스 생성자를 호출하여 인스턴스를 만들 때 지정됩니다.

Array와 마찬가지로 배열 액세스([]) 연산자를 사용하여 Vector 요소의 값을 설정하거나 검색할 수 있습니다. 또한 몇 가지 Vector 메서드를 통해 요소 값을 설정 및 검색하는 메커니즘이 제공됩니다. 이러한 메서드로는 push(), pop(), shift(), unshift() 등이 있습니다. Vector 객체의 속성 및 메서드는 Array의 속성 및 메서드와 비슷하며 대부분의 경우 동일합니다. 사용하는 Array의 모든 요소가 같은 데이터 유형인 경우 항상 Vector 인스턴스를 사용하는 것이 좋습니다.

Vector의 기본 유형은 접미사 유형 매개 변수 구문을 사용하여 지정됩니다. 유형 매개 변수 구문은 다음 예제와 같이 마침표(.), 여는 각괄호(<), 클래스 이름, 닫는 각괄호(>) 순서로 구성됩니다.

var v:Vector.<String>;
 v = new Vector.<String>();

예제의 첫 번째 행에서는 변수 v를 Vector.<String> 인스턴스로 선언합니다. 즉, 이 변수는 String 인스턴스만 포함할 수 있으며 String 인스턴스만 검색할 수 있는 Vector(배열)를 나타냅니다. 두 번째 행에서는 동일한 Vector 유형(요소가 모두 String 객체인 Vector)의 인스턴스를 생성하여 v에 할당합니다.

Vector.<T> 데이터 유형으로 선언된 변수에는 같은 기본 유형 T로 생성된 Vector 인스턴스만 저장할 수 있습니다. 예를 들어 new Vector.<String>()을 호출하여 생성된 Vector를 Vector.<int> 데이터 유형으로 선언된 변수에 할당할 수는 없습니다. 기본 유형은 정확히 일치해야 합니다. 예를 들어 다음 코드에서는 객체의 기본 유형이 변수의 선언된 기본 유형과 다르므로 코드가 컴파일되지 않습니다. Sprite가 DisplayObject의 하위 클래스이지만 결과는 마찬가지입니다.

// This code doesn't compile even though Sprite is a DisplayObject subclass
 var v:Vector.<DisplayObject> = new Vector.<Sprite>();

기본 유형이 T인 Vector를 T의 수퍼 클래스의 Vector로 변환하려면 Vector() 전역 함수를 사용합니다.

Vector 클래스에는 데이터 유형 제한뿐만 아니라 Array 클래스의 경우와 다른 몇 가지 제한이 더 있습니다.

    * Vector는 밀착형 배열입니다. 1에서 6 사이의 위치에 값이 없어도 인덱스 0과 7에 값이 있을 수 있는 Array와 달리 Vector의 경우에는 모든 인덱스에 값 또는 null이 있어야 합니다.
    * Vector는 고정 길이일 수도 있습니다. 즉, 포함된 요소 수를 변경할 수 없을 수 있습니다.
    * Vector의 요소에 액세스할 때는 경계가 검사됩니다. 마지막 요소(length - 1)보다 큰 인덱스에서는 값을 읽을 수 없습니다. 현재 마지막 인덱스를 벗어난 인덱스에는 값을 설정할 수 없습니다. 즉, 기존 인덱스나 [length] 인덱스에만 값을 설정할 수 있습니다.

이러한 제한 사항으로 인해 Vector에는 모든 요소가 단일 클래스의 인스턴스인 Array 인스턴스보다 두 가지 우수한 점이 있습니다.

    * 성능: Vector 인스턴스를 사용하면 Array를 사용할 때보다 훨씬 빠르게 배열 요소에 액세스하고 반복할 수 있습니다.
    * 유형 안전: 엄격 모드를 사용하면 Vector에 잘못된 데이터 유형의 값을 할당하거나 Vector에서 값을 읽을 때 잘못된 데이터 유형을 사용하는 등의 데이터 유형 오류를 컴파일러에서 식별할 수 있습니다. 그러나 push() 메서드나 unshift() 메서드를 사용하여 Vector에 값을 추가할 때는 인수의 데이터 유형이 컴파일 타임이 아닌 런타임에 검사됩니다.
----------------------------------------------------------------

Array와 Vector
Vector는 ECMAScript4에서 도입된 기능으로 이번 FlashPlayer10에서도 적용이 되었다. 모든 요소가 동일한 객체를 포함해야 한다는 제약이 따르지만 위 레퍼런스의 내용과 같이 Array 배경보다 몇 가지 장점을 가지고 있다. 속도와 엄격한 유형검사가 그것이다.

Vector는 Array와 같이 Object를 확장하며 dynamic 클래스 이지만 Array와 같이 정의되지 않은 프로퍼티에 값을 할당할 수는 없다. 예를 들어

var arrStr:Array = new Array();
arrStr.name = "jasu";
trace(arrStr.name);

이런 형태로 실행을 하면 arrStr에 있는 name 속성을 런타임에서 생성하여 값을 참조할 수 있다. 하지만 Vector의 경우 컴파일에서 에러를 throw 한다.

var vecStr:Vector.<String> = new Vector.<String>();
vecStr.name = "jasu"; // error 1119: Access of possibly undefined property name through a reference with static type __AS3__.vec:Vector.<String>.
trace(vecStr.name);


Vector의 연속된 배열과 고정 길이
var arrStr:Array = new Array();
arrStr[0] = "100";
arrStr[1] = "200";
trace(arrStr[1]); // 정상적으로 컴파일 됨.

var vecStr:Vector.<String> = new Vector.<String>(2, true);
vecStr [0] = "100";
vecStr [1] = "200";
vecStr [2] = "300"; // vecStr의 고정된 길이(2) 값을 벗어난 인덱스 참조로 에러 발생
trace(vecStr[2]);

var vecStr:Vector.<String> = new Vector.<String>(2, false);
vecStr [0] = "100";
vecStr [1] = "200";
vecStr [2] = "300";
trace(vecStr[2]); // 정상적으로 컴파일 됨.

Vector의 constructor 첫번째(length), 두번째(fixed) default 값은 0과 false이다.


Vector에서 push 메소드의 암묵적 형 변환
var vetStr:Vector.<int> = new Vector.<int>();
vetStr[0] = true; // TypeError 발생
trace(vetStr[0]);

var vetStr:Vector.<int> = new Vector.<int>();
vetStr.push(true);
trace(vetStr[0]); // output 1 (push 메소드 실행시 암묵적으로 할당된 값의 형을 강제 변환함.

Vector의 push 시에도 Type 체크를 하여 TypeError를 throw 해주는 것이 좋을 것 같으나 현재 Vector의 경우 push로 값을 넣을 경우 암묵적으로 강제 형 변환을 하고 있다.

정리
Vector의 경우 기존에 사용하는 문법과 약간은 다른 형태를 취하고 있기 때문에 처음 접할 때는 생소하다. 하지만 기존에 사용하던 방식 “:객체명”에서 :객체명.<단일형> 으로 추가하되, 그 Vector에는 포함하고자 하는 형태만 사용한다는 것을 머리 속에서 명확하게 인지한다면 기존에 Array를 사용하여 생기던 속도 문제와 에러를 예방할 수 있다는 차원에서 좀더 명확하고 빠른 알고리즘을 작성할 수 있지 않을까 싶다.



    

설정

트랙백

댓글

ACC(Adobe Community Champion)

Programming/Etc 2009. 1. 22. 20:40


기존에 플렉스 개발자로만 구성되었던 ACC(Adobe Community Champion)가 adobe flash platform으로서 플래시, 플래시 라이트, 플렉스가 통합되어 활동하게 되었습니다. 송구스럽게도 실력 있는 분들과 함께 임명장을 받게 되어 스스로 소식을 전하는 것이 조심스럽습니다. 앞으로도 더욱 많이 배워야 하는 저이지만 임명장을 받은 마당에 의무감도 없지 않은 듯싶어서 소식을 전합니다.

임명식이 있던 날, 회사 업무로 부득이하게 참석을 하지 못하였는데, 마음을 담은 카드까지 전달해 주셨네요. Adobe ACC 관계자 분들에게도 감사를 전합니다.

제가 격식에 따라 활동하는 타입은 아니지만 앞으로 꾸준히 활동하도록 하겠습니다. 다소 부족한 부분이 있더라도 배우는 자세로 이해해 주시고 잘못된 부분이 있으면 서슴없이 말씀해 주시면, 앞으로 ACC 활동을 통해서 또 다른 진정한 커뮤니티 챔피언을 발견할 수 있지 않을까 생각해 봅니다.

감사합니다.

    

설정

트랙백

댓글

[AS3] 좋은 코드를 작성하기 위한 길

Programming/ActionScript 3.0 2008. 12. 27. 11:30
플래시는 에니메이션 저작툴이라는 디자인적인 탄생 배경을 탈피하고 많은 프로그래머들이 매력을 느끼는 컴퓨터 프로그래밍 언어로 발전하였다. 나는 어린 시절 장래 희망을 물어보면 컴퓨터 프로그래머라고 이야기하던 시절이 있었다.(그때는 5.25인치 디스크 한 장에 게임 하나가 들어가던 시절이었는데 아마도 게임을 하면서 스토리를 내 마음대로 바꾸고 싶었던 것 같다.)

하지만 그런 꿈은 삶의 역경 속에서 잊혀지고 나아가 컴퓨터 프로그래머라는 직업이 돈이 되는 직업은 아니라는 것을 알았을 무렵에는 이내 나의 꿈은 컴퓨터 프로그래머가 아니었다고 부정하였다. 결국 부정하던 장래희망의 굴레에 나를 몰아넣은 것은 플래시라고 할 수 있다. 내가 플래시를 처음 접했을 때는 이런 형태로 발전할지는 꿈에도 몰랐었으니 고로 나는 플래시에게 사기를 당한 것이다. ^^


나는 배우는 과정에 서있다. 항상 플래시의 발전을 따라가느라 정신 없이 허우적거리는 생활을 반복하고 있으니 아마도 내가 플래시라는 툴에서 손을 놓을 때까지 이러한 배움의 길은 끝이 없을 듯싶다.

배우는 과정에서 느꼈던 좋은 코드를 작성하는 방법에 대하여 이야기 해 볼까 한다. 본 내용은 일본 잡지에 실린 연재 코너의 내용을 ActionScript 버전으로 본인의 생각을 덧붙여 작성한 것임을 밝혀둔다.

좋은 코드란?
좋은 코드는 조직이나 프로젝트, 프로젝트 메니저에 따라서 그 정의가 다르게 해석될 수 있다. 하지만 보편적으로 좋은 코드로서 바람직한 방향은 있다.

정확하게 동작하는 것.
정확한 결과값을 도출하는 것은 신뢰할 수 있는 코드다.

빠르고 효율적으로 동작 하는 것.
결과 값을 도출하는 방법은 여러 가지가 있을 수 있다. 좋은 코드는 적절한 퍼포먼스로 동작한다.

방어적으로 버그를 생산하지 않는 것.
방어적 프로그래밍 방법론에 기초하여 정상적인 값이 들어 올 것이라고 가정하지 않고 부정확한 값이 와도 문제가 발생하지 않도록 방어적으로 코드를 작성한다. 이것은 처음에 열거한 정확하게 동작하는 것을 도와준다.

유지보수를 하기 쉬운 것.
프로젝트는 단기간에 수명을 다할 수도 있지만 우리가 상상하는 것보다도 길게 생명을 유지하는 것도 많다. 유지보수성을 높이는 것도 좋은 코드에 있어서 중요하다.

다른 사람이 봐도 이해하기 쉬운 것.
현재 작성한 코드를 미래에 자신이 보는 것과 현재 타인이 보는 것은 비슷하다고 볼 수 있다. 미래에 자신이 봐도 이해할 수 있는 코드는 좋은 코드라 할 수 있다.

쓸데없는 부분이 없는 것.
쓸데없는 코드를 작성하는 개발자는 없을 것이다. 다만 코드의 구현과정에서 기능 추가 및 다른 로직과의 연동 과정에서 불필요하게 파생하는 코드들은 지양할 필요가 있다.


좋은 코드를 작성하면 무엇이 좋은가?
좋은 코드는 프로젝트를 추진하고 성공적으로 이끌기 위한 기본적인 요소가 된다. 프로그래밍의 달인들은 심플하고, 유지보수성이 좋고 안정적인 코드를 빠른 속도로 작성한다. 테스트가 어려운 코드를 테스트가 가능하고 검증할 수 있는 코드로 변경함으로써 품질이나 생산성을 수백 배 높이기도 한다. 이것은 프로젝트의 성공에 있어서 큰 요소이다. 물론, 좋은 코드가 있으면 반드시 프로젝트가 성공하는 것은 아니다. 개발 프로세스나 메니지먼트, 커뮤니케이션등으로 좌우되는 경우가 더 많지만 이런 것들을 제외한다면 개발에 있어서 좋은 코드의 힘은 크다고 볼 수 있다.

프로그래머로서의 평가가 높아진다.
좋은 코드를 작성하는 프로그래머는 대체적으로 프로그래머로서 신뢰한다. 프로그래머로서의 평가가 조직으로서의 실제 평가나 이익에 결합될지는 소속하는 조직의 평가 제도나 프로그램 이외의 일도 포함하여 정해지는 것이 현실이다. 그렇다고 좋은 코드를 쓸 수 있는 것이 마이너스 평가로 이어지지는 않을 것이다.

일에 대한 만족감이나 자신감을 가질 수 있다.
두 번 다시 손대고 싶지 않은, 유지보수가 불가능한 코드를 써본 적이 있을 것이다. 이러한 낮은 퀄리티의 일을 해 놓으면 일에 대한 만족감을 얻을 수 없다. 반면 자신의 의지로 적절히 좋은 코드를 작성함으로써 품질이 높고 안정된 소프트웨어를 개발했을 때는 그에 대한 만족감도 높고 자신감을 갖고 일에 임할 수 있다. 앞으로 오랜 시간을 프로그래머로써 살아갈 것이라고 생각한다면 좋은 코드를 쓸 수 있는 레벨을 목표로 하는 것은 합리적인 일이다.

사실 좋은 코드를 작성하기 위해서는 하루아침에 이룰 수 없다. 그렇다면 좋은 코드를 작성하기 위해 구체적으로 무엇을 어떻게 해야 하는지를 살펴보자.

코드 리딩 - 읽어라, 코드를 읽고, 읽고, 또 읽어라.
음악이나 회화, 건축의 세계에서도 자신만의 발상으로 작품을 완성시키는 예술가는 없다. 다른 사람들의 작품을 보고 영향을 받거나 좋은 곳을 훔치거나 해서 자신의 작품을 만드는 것으로 작품을 낳아 왔다.

프로그래밍도 같다. 좋은 코드를 작성 하려면 좋은 코드이건 나쁜 코드이건 간에 다른 사람이 작성한 코드를 평소에 의식하고 읽는 것이 중요하다. 플래시는 특히 많은 오픈 소스가 인터넷에 열려 있기 때문에 다른 사람이 작성한 좋은 코드를 언제라도 부담 없이 읽을 수 있다. ActionScript 중급 정도의 실력자이지만 구조를 어떻게 만들어야 하는지 막막한 분은 특히 주목할 필요가 있다. 이런 단계에 머물러 있는 분이라면 코드리딩을 통해서 한 단계 발전한 자신을 발견할 수 있을 것이다.

코드리딩의 좋은 점은 알아도 코드를 읽는 방법을 모른다면 시작하기 힘든 일이다. 아래의 간단한 코드를 보면서 이야기 해보자.

package classes.data{

    import flash.events.Event;
    import classes.data.*;
    import classes.net.SimpleXMLLoader;
   
    public class DProvider extends SimpleXMLLoader{ // [1] 여기부터
           
        private var _xmlUrl:String;   
        private var _keywords:Array;
       
        public function DProvider(inUrl:String):void { // [2] 여기부터
            _xmlUrl = inUrl;
            addEventListener(Event.COMPLETE, onLoadedXmlHandler);
            loadXML(_xmlUrl);
        }    // [2] 여기까지

        private function onLoadedXmlHandler(e:Event):void { // [3] 여기부터
            var xml:XML = XML(data);
            _keywords = [];
           
            var len:int = xml.item.length();
            for (var i:int = 0; i < len; i++)
            {
                // [4] 여기부터
                _keywords.push(createKeyword(xml.item[i]));
            }
        }    // [3] 여기까지
       
        private function createKeyword(inKeywordNode:XML):KeywordBase
        {
            var keyword:KeywordBase;
            switch(int(inKeywordNode.level)) {
                case 1: keyword = new Keyword1(inKeywordNode);
                break;
                case 2: keyword = new Keyword2(inKeywordNode);
                break;
                case 3: keyword = new Keyword3(inKeywordNode);
                break;
                case 4: keyword = new Keyword4(inKeywordNode);
                break;
            }
            return keyword;
        } // [4] 여기까지
       
        public function get keywords():Array { return _keywords.concat(); } // [5]
    } // [1] 여기까지
}

위 클래스는 본인이 실무에서 작업했던 태그클라우드에서 사용했던 코드이다. 클래스의 기능은 xml데이터를 불러들여 level 노드 값에 따라서 해당 클래스들을 배열로 생성하여 제공한다.

위 클래스 외적으로 사용된 클래스는 다음과 같은 기능을 포함한다.
SimpleXMLLoader : 단순히 xml 데이터를 불러오는 기능을 한다. loadXML 메소드가 포함되어 있다.
KeywordBase : 키워드 무비클립의 기본이 되는 기능을 제공한다. (마우스 다운, 오버, 아웃등)
Keyword1 ~ Keyword4 : KeywordBase 를 상속하는 각 레벨에 따라 디자인이 서로 다른 클래스들

코드리딩을 할 때는 기본적으로 nest 단위로 읽어 내려가면 된다. 중간에 나타나는 다른 클래스들은 현재 블록을 전체적으로 훑어 보면서 유추하도록 하자. 중간에 다른 파일을 열어 읽게 되면 현재 읽고 있는 흐름을 놓칠 수 있기 때문이다.

50줄도 안 되는 코드지만 이 코드만 가지고도 작업된 클래스들의 절반 이상은 이해할 수 있다. 복잡한 기능을 하는 클래스는 아니기 때문에 읽으면서 구조적으로 어떻게 작성이 되었는지 알 수 있을 것이라 믿는다. 이런 훈련을 반복 하다 보면 현재 읽고 있는 클래스 이외의 다른 클래스들도 머리 속으로 그리는 과정을 얻게 된다. 이를 통해서 하나를 보면 열을 알게 되는 경지에 다다를 수 있을 것이다. ^^

구글에서 코드 검색엔진을 통해서 웹에 있는 원시 코드들을 검색할 수 있는 서비스를 제공하고 있다. 자신이 원하는 기능의 클래스명이나 메소드명으로 검색해서 코드리딩 연습을 하는 것도 좋은 방법이다. 또한 많이 알려진 클래스나 패키지들은 구조적으로 잘 설계된 것들이 많이 있다. 구조적인 관점에서는 그런 것들을 분석해 보는 것도 큰 도움이 된다.

http://www.google.com/codesearch
인터넷상에 공개되어있는 Subversion(repository)나 archive파일 등을 기계적으로 빠르게 검색 할 수 있다.

좋은 이름을 붙이자.
우리가 프로그래밍을 하고 있을 때 가장 막히는 부분은 변수명, 메소드명, 클래스명 이름을 붙이는 것이다. 그만큼 좋은 이름을 붙이는 것은 중요하다. 좋은 이름을 붙이는 것이 중요한 이유는 위에서 언급했던 코드리딩에서도 느낄 수 있듯이 관련 기능에 부합하는 좋은 이름을 붙이지 않으면 코드를 읽기가 어려워진다.(생각해보니 위에서 예로 든 코드에서도 어려움을 느낀 분들이 있을 것 같다 ^^;)

그렇다면 좋은 이름의 조건이 있을 법하다.

좋은 변수명, 메소드명, 클래스명은 이름이 그 코드의 내용을 올바르게 나타내고 있다. 그러한 이름은 이름을 보는 것만으로도 코멘트를 읽을 필요도 없이 그 역할을 이해할 수 있다. 좋은 이름은 코드의 이해를 돕지만 나쁜 이름은 읽는 사람을 혼란 시키고 착각을 낳아 버그 발생을 조장한다.

위 코드를 예로 들면 onLoadedXmlHandler 메소드 명을 onComplete로 했을 경우에 어떤 것이 Complete 되었다는 것인지 인지하기 어렵다. 위 클래스의 경우는 단순한 클래스이지만 클래스의 내용이 많고 complete 핸들러 함수를 여러 개 포함하고 있을 경우에는 메소드의 중복이 발생할 수도 있다.

public function get keywords():Array { return _keywords.concat(); }
의 경우에는 keyword에 복수를 뜻하는 s를 붙임으로써 전달 받는 keyword가 하나가 아니라 복수이며 배열이라는 것을 유추할 수 있다. 이 밖에도 아래와 같은 방법이 있다.

어두 이외의 모음을 삭제 (image ->img)
강한 소리를 남긴다. (server -> svr)
약어의 이용 (database -> db)

일관성이 있다.
좋은 이름은 코드 전체에서 일관된 흐름을 가져야 한다.

대칭성을 유지하는 것
begin <-> end
write <-> read
on <-> off

단어의 조합의 일관성
scoreAvg
scoreAverage
avgScore
위 이름은 하나의 클래스에서 중복 사용하지 않을 것.

관용어에 따라서
언어, 프로젝트, 회사나 팀 마다 명명에 관한 관용어(관습)가 있다. 예를 들면 Java의 경우는 메소드명은 소문자로 시작하는 것이 관습이며, C#은 대문자, C++은 멤버 변수에 prefix로 m_를 붙이는 것이 일반적이다. 관용어에 따른 명명은 누가 보더라도 알기 쉬운 이름이라고 이야기 할 수 있다.(ActionScript의 경우는 보통 자바와 언어적 문법이 비슷하기 때문에 자바와 같은 명명 관용어를 사용하는 경우가 많지만 개인적인 취향에 따라 다르게 사용하는 경우가 대부분이다.)

코딩 표준에 따라서
위와 같이 좋은 코드의 조건을 채우기 위해서도 코딩 표준이나 명명 규약을 정해 팀 멤버 전원이 맞추는 것이 중요하다. 작업자 1명이 단기적으로 작업하는 프로젝트에서는 본인이 원하는 규칙을 사용하면 되겠으나 조직의 힘을 바탕으로 얻을 수 있는 큰 프로젝트의 경우는 협업의 중요성이 대두되므로 이러한 코딩 표준을 맞추는 것이 장기적으로는 바람직하다고 볼 수 있다.

좋은 이름을 붙이기 위한 습관
항상 좋은 이름을 붙이는 것을 의식한다.
좋은 이름을 붙이려면 우선 의식적으로 노력을 해야 한다. 이것은 A라는 이름이 좋은가? 아니면 B라는 이름이 좋은가를 항상 신중하게 검토해 보고 적절한 이름을 결정하는 프로세스를 반복할 필요가 있다.

코드의 리딩이나 리뷰
자신이 모르는 완전히 새로운 이름을 만드는 것은 코드를 분별없게 만들 가능성이 크다. 본인이 작성한 코드를 스스로 리딩해 보거나 다른 사람에게 리뷰를 함으로써 사용할 수 있는 이름을 조금씩 늘려간다. (본인 같은 경우는 아는 단어의 수준이 메롱이기 때문에 코드작업을 할 때 항상 사전을 열어놓고 작업을 하는 습관이 있다. 이때도 주의할 것은 일회성으로 모르는 단어를 만들어 명명하는 것 보다는 그 단어를 충분히 숙지한 상태에서 이름으로 사용하는 것이 바람직하다 – 간혹 내가 만든 이름을 내가 이해하지 못하는 어처구니 없는 경우가 발생 하기도 한다. 메롱;;)

좋은 변수명
설명적인 변수명
변수에는 값이나 오브젝트가 대입된다. 변수명을 보는 것만으로도 무엇이 어떠한 역할을 하는지 명확한 것이 좋은 이름이라 할 수 있다.

예를 들어
var n:int;                                                 // 무슨 수치?
var languages:Array = [“kr”, “en”];     // 무슨 언어?
var flg:Boolean = false;                      // 무슨 플래그?
var userAgent:UserAgent                  // 무슨 유저 에이전트?

위와 같은 변수명은 나중에 되돌아보면 변수의 역할을 알 수 없다. 아래와 같이 좀더 구체적이고 명확한 이름으로 해 두면 되돌아 보거나 다른 사람이 봐도 이해하기 쉬운 코드가 된다.

var orderCount:int;                                                // 오더수
var availableLanguages:Array = [“kr”, “en”];     // 이용 가능한 언어
var existsSameName:Boolean = false;           // 동성동명이 존재할까?(존재 true)
var unknownUserAgent:UserAgent                  // 미지의 유저 에이전트

다만 변수는 변수의 종류와 그 변수의 스코프(변수의 값을 참조할 수 있는 범위, 변수의 선언으로부터 시작되어 변수의 값을 참조할 수 없게 될 때까지의 범위)에 의해서 좋은 이름의 성질이 다르다. 스코프가 넓으면 다양한 곳으로부터 참조되므로 영향 범위가 크다고 할 수 있다. 따라서 보다 구체적인 이름이 요구된다. 종류별로 보면 아래와 같다.

필드 변수, 클래스 변수
필드 변수는 인스턴스 변수이다. 필드 변수, 클래스 변수는 로컬 변수등과 비교하면 변수의 스코프가 넓기 때문에 특히 그 변수의 의미를 올바르게 표현한 이름이 바람직하다.

메소드의 파라미터
파라미터명은 알기 쉽고 간결한 이름이 좋을 것이다. 파라미터명은 이용자가 API레퍼런스로 참조하거나 Eclipse, FlashDevelop등의 통합 개발 환경으로부터 변수명의 후보로서 이용되므로 극단적으로 짧은 이름을 붙이는 것은 피해야 한다.

로컬 변수
메소드 내에서 일시적으로 선언되는 변수이다. 스코프가 긴 것도 있지만 for문과 같이 짧은 것도 있다. 스코프가 긴 것은 필드 변수와 같이 변수의 의미를 올바르게 표현하는 구체적인 이름을 붙이는 것이 좋다. 스코프가 짧은 것은 아래와 같이 사용구분만 적당히 해주면 된다.

관용어에 따르는 또는 따르지 않는다.
배열의 내용을 순서대로 처리하는 루프 카운터 변수(i,j,k)등과 같이 잘 사용되는 관습적인 변수명은 그대로 관용어에 따르는 편이 알기 쉬운 코드가 된다.
// 루프 카운터의 변수명이 관습적이지 않고 너무 길다 [X]
for (var empCounter:int=0 ; empCounter < employes.size ; empCounter++) {
          var emp:Employee = employees[empCounter];
    ...
}

// 루프 카운터의 이름이 관습적으로 짧고, 가독성이 높다 [O]
for (var i:int=0 ; i<employes.size ; i++) {
         var emp:Employee = employees[i];
    ...
}


다만 예외적인 경우도 있다. 구체적인 이름을 변수명으로 하는 편이 알기 쉬운 경우는 그렇게 사용한다. 예를 들어 좌표계를 취급하는 경우에는 아래와 같이 사용하여 가독성을 높일 수 있다.
// i,j의 어느 쪽이 x좌표, y좌표인지를 모른다 [X]
for (var i:int=0 ; i<width ; i++) {
    for (var j:int=0 ; j<height ; j++) {
        var color:uint = getColor(i, j);
        ...
    }
}

// 변수명을 x,y로 했으므로 알기 쉽다 [O]
for (var x:int=0 ; x<width ; x++) {
    for (var y:int=0 ; y<height ; y++) {
        var color:uint = getColor(x, y);
        ...
    }
}

위 for문의 경우, 중첩되는 var y:int=0 변수 선언은 for문 밖에서 선언해 주는 것이 바람직하다. 중첩된 for문 안에서 x가 카운팅 될 때마다 메모리상에서는 y라는 변수의 어드레스를 매번 push해야 하는 불필요한 리소스 낭비가 발생하기 때문이다. (이 부분에 대한 논쟁 이슈가 있다. 이후에 이야기할 로컬 변수의 스코프 부분에서 로컬 변수의 스코프는 가능한 작게 한다는 변수의 의존성에 따른 대원칙에 위배되는 것이기 때문이다. 이것은 사용하는 상황에 따라 적절히 혼용하는 것이 좋을 것이다.)
var x:int;
var y:int;
for (x=0 ; x<width ; x++) {
    for (y=0 ; y<height ; y+) {
        var color:uint = getColor(x, y);
        ...
    }
}

변수명을 짧게 하는 편이 가독성이 향상되는 경우도 있다.
충분히 인지할 수 있는 범위인 경우로 루프내의 변수나 짧은 메소드 내의 변수처럼 일시적인 변수는 짧게 하는 편이 반대로 가독성이 향상되는 경우도 있다.
// 변수명 siteContactChangelog는 너무 길다 [X]
for (var i:int=0; i<siteContactChangelogs.length ; i++) {
    var siteContactChangelog:SiteContactChangelog = siteContactChangelog[i];
    siteNames[i] = siteContactChangelog.getSiteName();
    siteTitles[i] = siteContactChangelog.getSiteTitle();
    sitePicIds[i] = siteContactChangelog.getPicId();
    sitePicNames[i] = siteContactChangelog.getPicName();
}

// 변수명 log는 충분히 그 의미를 이해할 수 있기 때문에 가독성이 좋다.[O]
for (var i:int=0; i<siteContactChangelogs.length ; i++) {
    var log:SiteContactChangelog = siteContactChangelog[i];
    siteNames[i] = log.getSiteName();
    siteTitles[i] = log.getSiteTitle();
    sitePicIds[i] = log.getPicId();
    sitePicNames[i] = log.getPicName();
}

좋은 메소드명
좋은 메소드명은 이름으로부터 그 기능을 예상할 수 있다. 메소드는 처리를 담당함으로 메소드명은 동사+목적어 형태인 것이 많다. 아래는 자주 사용되는 메소드명의 예이다.
 메소드의 역할                                         메소드명
 값 취득에 관한 메소드                           getXXX
 값 세트에 관한 메소드                           setXXX
 생성에 관한 메소드                                create, build, make, generate
 초기화에 관한 메소드                            initialize, setupXXX
 파기에 관한 메소드                               destroy, dispose
 상태 확인에 관한 메소드                      contains, exists

인스턴스 메소드는 dataFormat.parse와 같이 오브젝트명으로 조합하므로 합쳐졌을 때는 중복 없게 의미가 통하는 이름으로 한다. 메소드와 클래스명도 이와 동일하다.
// parseDateString은 클래스명 DateFormat과
// date라는 이름이 중복되어 약간 장황
var dateFormat:DateFormat = new DateFormat("yyyy-MM-dd");
var startDate:Date = dateFormat.parseDateString("2008-04-01");

// 클래스명 DateFormat과 메소드명 parse로
// 무엇을 처리하는지 충분히 이해할 수 있음.
var dateFormat:DateFormat = new DateFormat("yyyy-MM-dd");
var startDate:Date = dateFormat.parse("2008-04-01");

좋은 클래스명
변수명이나 메소드명과 비교해서 클래스명은 가용 범위가 크기 때문에 적절하고 좋은 클래스명을 붙이는 것이 중요하다. 좋은 클래스명은 이름만으로 무엇을 실시하는 클래스인가를 알 수 있다.

클래스명이 잘 떠오르지 않을 때는 자신이 만들려고 하는 클래스의 역할을 제대로 정리 할 수 있는지 없는지를 판단해 보아야 한다. 1개의 클래스에 복수의 책무를 넣거나 역할이 애매한 기능은 없는지를 생각해보고 해당 클래스에서 해결하고자 하는 문제를 차분히 생각해보고 클래스명을 다시 선택할 필요가 있다.

클래스명의 어휘 설계 능력
이름 명명에 관하여 자신이 모르는 표현, 개념은 쉽게 생각하기 어렵다. 보다 나은 표현을 선택하려면 여러 가지 코드나 서적을 읽거나 실제로 코드를 쓰고 시험하는 것이 중요하다. 그 경험을 통해서 이름에 관한 어휘가 조금씩 늘어난다. 본인 같은 경우는 영어권의 개발자가 작성한 기능과 메소드명을 보면서 의미해석을 한다. 사실 프로그래밍 과정에서 이름을 짓는 것은 생활에서 보편적으로 사용하지 않는 단어들도 많이 존재한다. 하지만 그만큼 자주 사용되는 단어들은 한정되어 있기 때문에 틈나는 대로 기억을 되살려 사용해 보는 것이 중요하다.

좋은 패키지명
ActionScript의 패키지명은 클래스나 자원의 논리적인 그룹을 만들어 계층 구조를 나타낸다 이것은 주로 이름의 충돌을 막기 위해서 사용된다. 패키지명은 그룹의 논리적인 내용을 나타내는 간결한 명사를 선택한다.

간혹 클래스를 만들지 않고 라이브러리에서 특정 무비클립을 동적으로 참조하기 위하여 Linkage에 클래스명만 기입하여 사용하는 경우가 있다. 이럴 경우 클래스가 플래시 컨텐츠전역에 오픈 되기 때문에 팀의 협업에 있어서 클래스명의 충돌을 야기할 수 있다. 이럴 경우 해당 클래스가 없더라도 관련된 패키지명을 명시함으로써 그러한 충돌을 줄일 수 있다. 

처음부터 좋은 이름을 사용할 수 있는 사람은 없다. 좋은 이름에 대해서 의식적으로 사용하려고 노력하는 것이 중요하다. 누구라도 알기 쉽고, 이해하기 쉬운 코드라고 하는 것은 항상 의식하고 노력하다 보면 점차적으로 좋은 이름을 지을 수 있는 요령이 생길 수 있을 것이다.


스코프를 의식한 프로그래밍
사실 모든 프로그래밍에서 스코프는 존재한다. 의식적으로 스코프를 컨트롤 할 수 있으면 보다 좋은 프로그래밍 스타일에 가까워질 것이다. 이번에는 스코프에 대한 이야기를 해보자.

우선 스코프는 Wikipedia에 다음과 같이 정의되어 있다.
프로그래밍에서 스코프란, 어느 변수나 함수가 특정 이름으로 참조되는 범위, 어느 범위의 밖에 있는 변수 등은 통상 그 이름만으로는 참조할 수 없다. 이때 이러한 변수는 스코프 밖에 있어 보이지 않는다 라고 말한다.

스코프는 변수, 메소드, 클래스등이 보이는 범위다. 그렇다면 보인다는 의미는 무슨 뜻일까? 보인다라는 것은 프로그래밍상에 있다는 것이다. 변수이면 변수명을 지정해 값을 읽고 쓰기가 가능하고 메소드는 호출해 사용할 수 있는 범위에 있는 것이다.

사용할 수 있다라는 것은 바꾸어 말하면 그것에 의존한다라고 이야기할 수 있다. 하나의 코드를 변경하고 싶을 뿐인데 수십 곳을 수정할 필요가 있을 수 있다. 이것은 변경하고자 하는 코드가 여러 곳에 의존하고 있으면 이와 같은 변경이 다른 부분에 영향을 준다.

스코프 == 보이는 범위 == 사용할 수 있는 범위 == 의존하는 범위

변수나 메소드의 스코프를 작게 하는 것으로 보이는 범위가 작아져 사용할 수 있는 범위, 의존하는 범위도 작게 할 수 있다. 스코프를 작게 하는 것으로 보다 의존성이 적어 변경이 용이한 프로그램을 작성 할 수 있는 것이다.

기억해 두는 것을 줄이자.
의존이 작아지는 것 이외에도 스코프를 작게 하는 것으로부터 도움이 되는 것이 있다. 프로그래밍은 본질적으로 복잡한 것이다. 복잡함에 대한 대책으로서 문제 영역을 가능한 작고, 이해 가능한 상태로 취급하는 것이 중요하다. 스코프를 의식적으로 작게 하는 것으로 프로그래머가 기억해 두지 않으면 안 되는 것, 주의하지 않으면 안 되는 범위는 작아져서 쉽게 이해할 수 있게 된다. 이것이 스코프를 작게 하는 것의 본질이라고 할 수 있다.

로컬 변수의 스코프
로컬 변수란 메소드 내에서 선언된 일시적인 변수다. Java나 Ruby의 로컬변수는 선언된 장소로부터 스코프가 시작되어 선언된 블록이 끝나면 스코프가 종료된다. ActionScript 2.0 에서도 순차적으로 메모리 할당이 이루어 졌기 때문에 메소드 내에서 상위에 선언된 변수와 하위에서 선언된 변수가 서로 다른 영역 범위의 스코프를 갖기 때문에 컴파일 시에 충돌이 발생하지 않았다.(Java, Ruby와 동일)

반면 ActionScript 3.0에서의 로컬변수는 스코프의 시작은 컴파일러가 블록에 접근했을 때 블록 내의 위치와는 상관없이 미리 메모리 주소가 할당된다. 이는 컴파일 시에 메모리 할당이 한꺼번에 선행되어 스코프가 동일하기 때문에 변수명 중복 에러 메시지를 출력하는 것이다.

하지만 일반적인 프로그래밍 언어에서는 변수의 의존도를 최소화하여 프로그램의 변경이 쉽게 하기 위하여 [로컬변수의 스코프는 가능한 작게 한다.] 라는 것이 대원칙이다.

필드 변수의 스코프
필드 변수는 인스턴스 변수다. 필드 변수의 스코프는 private / public 등과 같은 키워드를 통해서 정해진다. ActionScript의 경우 필드 변수에 대한 가시성은 스코프가 작은 순서로 4개가 지원된다.
private    : 오브젝트 내에서만 변수에 액세스 할 수 있다.
internal    : 같은 패키지 내에서 액세스 할 수 있다.
protected : 오브젝트 내 그리고 하위 클래스로부터 액세스 할 수 있다.
public : 오브젝트 밖에서 액세스 할 수 있다.

필드 변수는 모두 private가 기본 전략이다. 필드 변수에 외부나 하위 클래스로부터 액세스 하고 싶은 경우에는 set/get 등 액세스용 메소드를 따로 만들어 공개하는 것이 캡슐화에 도움을 준다. 하지만 기본 전략이 바람직하다고는 하지만 상속에 따른 장황함을 배제하기 위해서 protected나 public 접근자를 사용하는 경우도 발생한다.

인스턴스 메소드의 스코프
인스턴스 메소드는 인스턴스에 속하는 메소드를 말한다. ActionScript에서 메소드의 스코프 가시성도 필드 변수와 같이 4개이다. 메소드의 접근 제한은 최소인 private로부터 시작하여 점차적으로 internal -> protected -> public으로 나아가는 것이 바람직하다.

메소드 파라미터의 정보량
스코프에서 조금 벗어난 이야기이지만 메소드의 인수로 건네주는 정보량을 어느 정도로 하는 것도 의존성이라는 관점에서 보면 중요한 선택이다.

예를 들면 아래의 두 코드는 사원 정보를 취득하는 메소드이지만 1번은 인수가 사원ID이고 2번은 인수가 사원 오브젝트이다. 이 두 개의 코드 중에 어느 쪽이 좋은 코드라고 할 수 있을까?
// [1] 인수가 사원ID인 경우
public function getEmployee(inEmpId:int):Employee {
    return empDao.findById(inEmpId);
}

// [2] 인수가 사원 오브젝트의 경우
public function getEmployee(inEmp:Employee):Employee {
    return empDao.findById(inEmp.getId());
}

일반적으로 1번이 인수의 정보량이 적기 때문에 의존이 적고 좋은 코드라고 할 수 있다. 반면 2번은 사원 오브젝트가 가지는 모든 정보로 액세스가 가능하기 때문에 의존이 커지게 된다. 필요한 것은 사원의 ID이므로 그것에만 의존하여 코드를 작성하는 것이 바람직하다.

메소드를 이용하는 측면에서 사원 ID만으로 메소드를 이용할 수 있는 것과 사원 오브젝트가 필요한 것은 전혀 다르다. 더욱이 2번 메소드 내에서 구체적인 처리는 사원 오브젝트의 사원 ID만을 사용해 사원 정보를 검색하고 있다. 이것이 문서화 되어 있지 않을 경우, 코드를 읽지 않으면 그 사실을 알지 못한다. 인수에 불필요한 정보가 포함되어 있으면 사원 ID가 포함된 사원 오브젝트를 건네주어야 한다는 암묵적인 요구가 발생하기 쉽다.

위와 같은 문제 때문에 메소드의 인수는 필요 최저한의 정보를 가지는 것이 의존성이 적고 좋은 코드라고 말할 수 있다.

다만 인수가 너무 많아지는 경우는 인수를 오브젝트로 변경하는 편이 좋다. 기준으로서 인수의 개수가 5개를 넘는 메소드는 인수를 오브젝트로 변경하는 것을 검토할 필요가 있다.

static 메소드
static메소드(클래스 메소드)는 클래스에 속하는 메소드이다. ActionScript에서는 static 키워드를 붙여서 선언한다. static 메소드의 가시성은 인스턴스 메소드의 가시성과 같다. 반면 다른 점은 static 메소드는 필드 변수에 액세스 할 수 없다. static 메소드는 메모리에 미리 할당이 되는 반면 인스턴스 변수는 오브젝트가 인스턴스화 된 시점에서 메모리 할당이 되기 때문에 static 메소드 내에서 인스턴스 변수를 참조할 방법이 없는 것이다.

필드 변수에서 보면 인스턴스 메소드를 static 메소드로 변경했을 경우, 자신이 영향을 주는 메소드가 줄어 들게 되어 결과적으로 스코프는 작아진다. 필드 변수에 액세스 할 필요가 없고, 오버라이드가 필요하지 않는 메소드는 static 메소드로 하는 편이 좋은 경우가 많다. 물론 무조건 static으로 하는 것이 좋은 것은 아니다. 인스턴스가 생성되지 않은 시점에서 메모리에 할당이 되기 때문에 사용하지 않는 클래스의 static 메소드가 메모리에 상주하는 메모리 차원에서의 단점도 있다.
// 인스턴스 메소드의 경우
private var count:int;                                                           ┓
...                                                                                           |
private function regexGroup(inRegex:String):String { |변수 count의 스코프
    // 필드에 액세스 가능                                                     |
    return "(" + regex + ")";                                                   |
}                                                                                             |
...                                                                                            ┛

//static 메소드로 변경했을 경우
private int count;                                                                  ┓
...                                                                                            ┛변수 count의 스코프
static private function regexGroup(inRegex:String):String {
    // 필드에 액세스 불가
    return "(" + regex + ")";
}
...     ―변수 count의 스코프


코드의 분할
몇 천행이 넘는 메소드로 너무 많은 기능을 포함하고 있거나 메소드를 너무 세세하게 분할하여 흐름을 파악하기 어려운 코드는 좋은 코드라 할 수 없다. 좋은 코드가 되기 위해서는 가독성이 좋고, 유지보수성이 우수한 것이라고 위에서 언급했다. 메소드를 적절한 단위로 분할하는 것은 좋은 코드를 만드는 것에 중요한 역할을 한다.

코드를 분할하면 무엇이 좋은가?

가독성의 향상
메소드 코드의 길이가 100줄을 넘으면 처리의 흐름을 읽는데 어려움이 있다. 반면 30행 이하이면 내용을 이해하는 것이 용이하다.

유지보수성의 향상
분할에 의해 변수의 스코프가 작아지거나 처리 기능이 본래 있어야 할 클래스나 메소드로 이동하는 것으로 의존관계가 정리되어 유지보수성이 향상된다.

재이용성 향상
코드를 분할하면 코드의 중복이 줄어들어 이용 가능한 부품으로서의 메소드나 클래스를 만들 수 있다. 이것은 OOP 언어에서 좋은 방법이다.

캡슐화를 지킬 수 있다.
객체 지향에서는 캡슐화라는 개념이 있다. 메소드나 클래스의 상속에 의한 구체적인 구현이나 오브젝트 상태를 몰라도 메소드를 호출하는 것만으로도 각각의 오브젝트가 처리를 이행해 주는 것이다.

클래스의 관점에서도 비슷한 이득을 얻을 수 있다. ActionScript는 타 언어보다 MVC 페턴을 예로 들면 view에 해당하는 클래스가 Model에 비해 상대적으로 비대하다. 따라서 구조 작업에 있어서 이러한 view 그룹을 어떻게 분할하느냐에 따라서 유지보수성의 성패를 좌우한다고도 볼 수 있다.

위에서 좋은 코드를 위한 방법에 관하여 이야기를 했다. 연재에 실린 내용과 그것을 ActionScript에 맞게 수정하는 관계로 문장이 다소 매끄럽지 않는 점이 있을 것이다. 그런 부분은  이해해 주길 바란다.

사실 플래시는 타 언어에 비해서 버그가 발생할 가능성이 크다. 그 이유는 플래시의 강점인 모션을 항상 고민해야 하는 작업이기 때문이다. 일반적인 언어에서는 어떤 오브젝트가 나타나고 사라지는 사이에 시간이라는 개념을 포함할 필요성을 인식하지 못하지만 플래시는 모션에 따라 그 사이에 시간이 존재할 수 있다. 모션이 있는 사이에 예측하지 않은 사용자 반응이 있을 경우에는 버그가 발생할 수 있다. 플래시 개발자는 항상 이런 부분까지 예상하고 방어적 프로그래밍을 해야 한다.

위에서 이야기한 좋은 코드를 작성하는 것은 플래시의 작업에 많은 도움을 주지만 그런 것이 플래시 개발의 모든 약점을 보완해 주지는 못한다. 때로는 일반적인 좋은 코드로서의 방향에 영향을 주지 않는 범위 내에서 플래시의 장점을 극대화 할 수 있는 방법을 고민 해야 하는 것이다.

간혹 좋은 코드를 작성하는 방법을 물어보시는 분들이 있다. 물론 그것이 모르는 부분을 빨리 이해할 수 있는 좋은 방법일 수 있지만 쉽게 얻은 지식은 지식으로 머물러 지혜로 발전하지 못하는 경우가 많다. 더구나 본인 또한 그 방법을 찾고자 고민하고 배워가는 입장이기 때문에 도움을 주지 못하는 경우도 있다.

또한 플래시의 발전은 지식에 목말라 스스로 지혜를 얻으려 노력했던 선배들의 도움으로 커왔다고 나는 믿고 있기 때문이기도 하다. 위에서 이야기 한 내용은 본인 또한 노력하는 부분이고 이 포스트를 읽는 분들도 지혜를 얻기 위해 노력하다보면 좋은 코드를 생산할 수 있을 것이라 믿는다.



    

설정

트랙백

댓글

[AS3] swf가 임베드된 html 경로 알아내기

Programming/ActionScript 3.0 2008. 12. 25. 02:01
swf가 임베드 되어 있는 html의 도메인 경로를 알아내기 위해서는 아래와 같이 ExternalInterface를 이용하여 자바 스크립트 문법에 도움을 받아 location 경로를 리턴 받을 수 있다.

var locationUrl:String = ExternalInterface.call("document.location.href.toString");

그러나 이렇게 했을 경우 하나의 문제가 있다.

만약 임베드된 object의 id값을 설정하지 않거나 설정하더라도 동영상 플레이어처럼 여러 개의 swf를 하나의 페이지에 임베드 할 경우에는 오브젝트의 id값이 같기 때문에 ExternalInterface를 이용하여 자바스크립트 함수를 호출할 수 없는 상황이 발생한다. ExternalInterface를 사용할 경우 아래와 같은 경우에는 자바스크립트를 호출할 수 없다.

HTML 페이지의 Flash Player 인스턴스에 제공된 이름(object 태그의 id 속성)에 JavaScript에서 연산자로 정의된 하이픈(-)이나 다른 문자가 포함되어 있으면(예: +, *, /, \, . 등) Internet Explorer에서 컨테이너 웹 페이지를 보면서 ActionScript에서 ExternalInterface를 호출할 수 없습니다.
뿐 만 아니라 Flash Player 인스턴스를 정의하는 HTML 태그(object 및 embed 태그)가 HTML form 태그에 중첩되어 있는 경우에도 ActionScript에서 ExternalInterface가 호출되지 않습니다.

따라서 하나의 html 페이지에 여러 개의 같은 swf를 임베드 할 경우에는 각각의 object 아이디를 다르게 설정해 주어야 한다. 그러나 상황에 따라서 중첩되는 object태그들의 id를 서로 다르게 부여하기 위해서는 여러 가지 난제가 있을 수 있다. 그렇다면 object 의 id 값을 같게 하더라도 자바스크립트 함수를 호출할 수 있는 방법이 없을까? 위와 같은 상황이라면 IE가 파이어폭스처럼 object id가 같은 상황이라도 ExternalInterface가 자바스크립트 함수를 호출해 줄 수 있을 때까지 기다리거나 ExternalInterface가 위와 같이 호출할 수 없는 상황이 발생하지 않기를 바랄 수밖에 없다. 그렇다고 해결할 수 없는 문제로 남기기에는 플래시가 서운할 것이다. object id가 같아도 ExternalInterface가 자바스크립트 함수를 호출할 수 있도록 만들어 보자.

방법은 ActionScript에서 요긴하게 사용할 수 있는 SharedObject 객체이다. SharedObject객체는 기본적으로 도메인당 최대 100KB의 데이터로 공유 객체를 만들 수 있다. SharedObject의 data속성에는 String, Array, Number, Boolean, ByteArray, XML와 같은 공유 객체를 담을 수 있다.

위에서 언급한 상황처럼 같은 swf가 여러 개 임베드 되어 있고 object id가 같을 경우 IE에서는 첫번째 임베드 되어 있는 swf에서는 정상적으로 ExternalInterface를 통하여 자바스크립트를 호출해 준다. 그러나 아래에 임베드된 swf에서는 자바스크립트를 호출하지 못한다. 따라서 첫번째 임베드된 코드에서 제대로 리턴 받은 경로를 SharedObject를 이용하여 flush(쓰기)를 하고, 반면 ExternalInterface를 통해서 리턴 받은 값이 “null”일 경우에는 SharedObject를 통해서 저장된 기존의 domain 경로를 불러와서 사용하는 것이다.

아래는 그러한 방법으로 처리한 코드 예이다.

private function getLocationUrl():String
{
    var domain:String = String( ExternalInterface.call(" function(){ return document.location.href.toString();}"));
    var so:SharedObject = SharedObject.getLocal("location");
   
    if (domain != "null"){
        so.data.domain = domain;
        so.flush();
    }else{
        domain = so.data.domain
    }
   
    return domain;
}

위 방법은 그럴듯 하다. 그런데 문제가 있다. 브라우저가 자바스크립트를 호출해 주는 object를 먼저 참조하지 않는다는 것. 따라서 위 방법으로 했을 경우 페이지를 한 차례 재로드해 줘야 제대로 적용이 된다.

결국 object id 값을 서로 다르게 설정하는 것으로 가야만 했다는... 삽질의 길은 멀고도 험하구나...

    

설정

트랙백

댓글

웹에서 컴파일하는 서비스 Wonderfl

Programming/ActionScript 3.0[CS4] 2008. 12. 24. 09:32
Kayac의 Wonderfl 서비스가 재미있다. 웹페이지 상에서 ActionScript를 작성하는 순간 일정 시간에 작성한 ActionScript 코드를 실시간으로 컴파일을 하여 오른쪽에 결과물을 swf로 보여준다. FlashPlayer10 버전의 코드도 제대로 컴파일 되는 것 같다. 이런 것을 보면 앞으로 웹에서 돌아가는 플래시툴도 개발 가능할 것으로 보인다.











    

설정

트랙백

댓글

[AS3] interface 에 관한 이해

Programming/ActionScript 3.0 2008. 12. 17. 17:04

이웃 블로그를 순방하다가 오랜만에 블로그에 글을 남기게 된다. 자수 블로그가 한동안 무척이나 푹~ 잠들었었다. 개인적으로 풀리지 않는 일들도 있고, 회사 일도 그렇고, 여러 가지로 말문을 열지 못하게 요인들은 앞으로 과감히 무시하고 이제는 조금씩 잃어버린 여유를 찾아서 나를 더욱 여유롭지 않게 해야겠다는 생각을 하게 된다.

오랜만에 땡굴이 형님의 불로그에 방문했다가 IEventDispatcher 인터페이스에 관한 설명들을 보고 보충해서 설명하고자 포스트를 쓴다. 일단 프로그래밍 언어(OOP언어)에서 인터페이스에 관한 것은 책에 많이 기술되어 있기 때문에 그 개념은 어느 정도 느끼고 있지만 그 활용 방법에 대해서는 구체적으로 떠오르지 않는 분들이 많은 것 같다. 사실 나 또한 그러하다. 설명하고자 하는 내용은 지극히 개인적인 작업을 바탕으로 설명하는 것임을 밝혀둔다.

단적으로 말해서 인터페이스는 open 개념이 아닌 close 개념에 가깝다. 이 이야기는 객체를 개방하는 것이 아닌 하나의 종속된 틀 속에 관련 객체를 구속하여 외부의 다른 잡음으로부터 보호하고 다른 객체와 대체할 수 있는 기반을 만드는 것이 주 목적 이라는 것이다.

예를 들어 “문” 이라고 일컬어 지는 것들은 대부분 공통의 요소가 존재한다. 손잡이, 열림, 닫힘…, 이런 요소들은 문이 창문이건, 여닫이, 미닫이이건 간에 상관없이 공통으로 사용할 수 있는 요소일 것이다. 따라서 프로그래밍 언어에서는 이러한 공통의 요소를 하나의  interface로 만들어 implements 키워드를 통해서 구체적인 구현을 클래스에서 이행하게 되는 것이다.

그렇다면 의문이 생길 수 있다. 이렇게 한다고 하여 개발자 입장에서 더 좋은 것이 무엇이냐고…, 물론 인터페이스를 굳이 사용할 필요가 없는 곳에서 사용을 하게 되면 손가락만 피곤하다. 하지만 위에서 언급한 “문”이라는 객체가 프로젝트 안에서 하나가 아니라 대문, 창문, 화장실문, 서랍장문… 등이 사용되고 이러한 문들은 행위자(문을 사용하는 사람)에 따라서 어떤 문이건 간에 손잡이를 잡고 열고 닫을 수 있어야 한다면 이야기는 달라진다.

여기서 간단한 클래스 구조를 통해서 위에서 이야기한 부분에 대해서 다시 한번 생각해 보도록 하자.

문인터페이스 : IDoor
package {
    public interface IDoor {
        function open():void;
        function close():void;
    }
}


대문 : Gate <- IDoor
package {
    public class Gate implements IDoor {
        public function Gate() {
        }
        public function open():void {
            trace("open in Gate Class");
        }
  
        public function close():void {
            trace("close in Gate Class");
        }
    }
}

창문 : Window <-- IDoor
package {
    public class Window implements IDoor {
        public function Window() {
   
        }
        public function open():void {
            trace("open in Window Class");
        }
  
        public function close():void {
            trace("close in Window Class");
        }
    }
}

행위자 : Person
package {
    import flash.events.Event;
    import flash.events.EventDispatcher;
    public class Person extends EventDispatcher{
  
        static public const OPEN_DOOR:String = "openDoor";
        static public const CLOSE_DOOR:String = "closeDoor";
        private var _door:IDoor;
  
        public function Person(inDoor:IDoor) {
            _door = inDoor; 
        }

        private function doAction(isOpen:Boolean):void {
            if(isOpen){
                _door.open();
                dispatchEvent(new Event(OPEN_DOOR));
            }else {
                _door.close(); 
                dispatchEvent(new Event(CLOSE_DOOR));
            }
        }
    }
}

메인 클래스 : MainDocument
package {
    import flash.events.Event;
    public class MainDocument extends Sprite {
        private var _person:Person;
        public function MainDocument() {
            _person = new Person(new Gate()); // or _person = new Person(new Window());
            _person.addEventListener(Person.OPEN_DOOR, onOpenHandler);
          _person.addEventListener(Person.CLOSE_DOOR, onCloseHandler);

            _person.doAction(true); // or _person.doAction(false);
        }
  
        private function onOpenHandler(e:Event):void {
            trace("open in Person Class");
        }
  
        private function onCloseHandler(e:Event):void {
            trace("close in Person Class");
        }
    }
}

위에서 설명한 바와 같이 클래스들을 보면 어느 정도 이해할 수 있으리라 생각한다. Person 클래스에서 정의한 속성 _door은 IDoor 인터페이스 형으로 선언이 되었다. 그리고 이 속성에는 메인 클래스에서 Gate 또는 Window 인스턴스를 생성하여 Person 생성자에 인자로 전달하여도 문제 없이 객체를 담을 수 있다. 이렇게 할 수 있는 이유는 IDoor 인터페이스에서 정의한 함수(open, close)를 두 객체(Gate, Window)에서 포함하고 있으며 IDoor 인터페이스를 implements 키워드를 통해서 이행하고 있기 때문에 가능한 일이다. 다시 풀어서 이야기하면 _door 속성에 할당된 오브젝트는 무조건 open, close 함수를 사용할 수 있다는 것으로 곧 IDoor 인터페이스를 이행하고 있는 클래스라면 모두 허용한다는 것이다.

따라서 위와 같이 클래스 구조를 작성하게 되면 MainDocument 클래스 내에서 Person을 생성할 때 인자로 전달하는 객체는 IDoor 인터페이스를 이행하고 있는 모든 클래스를 담을 수 있게 되는 것이다. 이것이 OOP언어에서 장점으로 이야기하는 폴리모피즘(다형성)에 기초한다.

추가적으로 위에서 Person 클래스에서는 EventDispatcher를 상속 받고 있다. EventDispatcher 클래스는 다시 IEventDispatcher 인터페이스를 이행하는 클래스로서 자신으로부터 이벤트를 전달하는 역할을 할 수 있는 권한을 갖게 된다.(권한을 갖는다는 의미는 EventDispatcher클래스를 상속함으로써 EventDispatcher클래스 안에서 이미 정의되어 있는 함수들을 사용할 수 있다는 의미)

그러므로 위 코드와 같이 Person 클래스 내에서는 doAction 함수의 분기에 따라서 이벤트를 전달(방송)할 수 있으며, MainDocument 클래스 내에서는 생성한 Person 객체의 인스턴스로부터 전달되는 이벤트를 청취할 수 있도록 addEventListener 메소드를 통해서 핸들러 함수를 정의할 수 있는 것이다.

그렇다면 EventDispatcher 클래스만 상속하면 모든 문제가 해결될 것 같다. 하지만 그렇지만은 않다. ActionScript는 extends 키워드를 통해서 상속 받을 수 있는 것은 하나의 슈퍼클래스만 가능하다. 자바의 경우는 복수의 슈퍼클래스 정의할 수 있으나 ActionScript는 그렇지 않다. 따라서 Person 클래스가 Kind라는 클래스를 상속해야만 하는 상황이라면 어떻게 해결할 수 있을까? 이럴 때는 Person클래스에서 Kind 클래스를 상속하고 implements 키워드를 통해서 IEventDispatcher 인터페이스를 이행하여 IEventDispatcher 인터페이스에 있는 함수들을 구체적으로 기술하는 것으로 해결할 수 있다.

또 한가지 방법은 OOP에서는 상속이라는 기술만이 폴리모피즘을 구현할 수 있는 것이 아니라 위임 또는 합성을 사용할 수도 있다. 이는 extends 키워드를 통해서 특정 슈퍼클래스를 상속하는 형태가 아니라 생성자, 또는 함수를 통해서 전달된 객체를 클래스 내부에서 연결 구현해줌으로써 다형성을 만들어 낼 수가 있다. 이때 필요한 것이 바로 인터페이스라 할 수 있다.(인터페이스는 implements 키워드를 통해서 복수의 인터페이스를 이행할 수 있다.)

쓰다 보니 내용이 길어졌다. 위 코드는 포스트를 작성하면서 개념을 설명하기 위하여 임의로 작성한 코드인 관계로 실제 컴파일에서 에러가 발생할 수 있다.

    

설정

트랙백

댓글

[AIR] AIR 1.5 (Cosmo) 출시 예정...

Programming/AIR 2008. 10. 26. 02:19
올해 안으로 AIR 의 업데이트가 예정되어 있다. AIR 1.5로서 릴리스 될 예정으로, 주된 목적은 Flash Player 10 의 신기능을 서포트하는 것이라고 한다.

주요한 신기능,

    * Flash Player 10 의 통합
          o Pixel Bender 를 이용한 커스텀 필터
          o 3D 효과나 화면처리 API
          o 새로운 텍스트 엔진에 의한 향상된 레이아웃 기능
    * 새로운 스트리밍 기능, 코덱
    * SquirrelFish 의 Webkit 에의 통합에 의한 JavaScript 실행 속도의 개선
    * SQLite 데이타베이스에의 레코드 단위로의 암호화

또한 1.5 버전 이후부터는 Linux를 정식으로 지원한다고 한다.
    

설정

트랙백

댓글

수퍼개발자의길 - 나눔과 교육으로 날아라

Programming/Etc 2008. 9. 8. 01:02

[수퍼개발자의 길 ③] 나눔과 교육으로 날아라

상훈형님의 블로그에 방문했다가 보게 된 칼럼이다. 사실 본인 또한 자수라는 이름으로 본인에 대해서 잘 모르는 분들의 찬사를 듣기도 했던 것 같다. 하지만 가만히 생각해 보면 과연 내가 그러한 찬사를 받을 만한 실력과 인내심을 가지고 있는지에 대해서 되묻지 않을 수 없다.

블로그를 통해서 소통을 한다고는 하지만 과연 나에 대해서 모든 것을 들어내고 순수한 마음으로 전달하고 소통하기를 바라고 있는지 모르겠다. 사실 요즘 들어서 나의 개발 성향과 가치관에 많은 의문을 제기했었다. 내가 생각하는 것이 과연 옳은 것인가, 무엇보다도 나에게 득이 없더라도 실이 되면 어쩌나 하는 두려움이 크지 않았을까 하는 생각도 든다.  그 동안 순수성을 상실한 이득에만 초점을 맞춘 소통을 하고 있지는 않았는지 반성하게 된다.

목표 보다는 과정이 중요하다는 말의 의미를 이 칼럼을 통해서 느끼게 된다. 만약 앞으로 그러한 두려움에 나눔을 실천하지 않는다면, 나는 현재로부터 더 이상 발전하지 않았다고 판단 하는 것이 옳을 것이다.

단순히 오늘의 충족보다 내일 느끼게 될 스스로의 만족에 더 충실한 내가 되기 위해서 더욱 노력해야 하겠다.
    

설정

트랙백

댓글

[AS3] ActionScript의 방향성

Programming/ActionScript 3.0 2008. 9. 3. 23:50
FlashPlayer9 발표 이후 adobe에서는 ActionScript를 ECMA-262 Edition 4 (ES4)에 준하도록 진행한다는 이야기가 있었다. ES4는 현재 Adobe, Mozilla, Opera, Google등이 주축이 되어 표준화가 진행 중이지만 작년 Microsoft와 Yahoo 주도로 ECMA-262 Edition 3.1(ES 3.1)의 워킹 그룹이 결성된 이후 위와 같이 두 개가 다른 ES3 후속 안으로 병존하는 상황이 계속되고 있다고 한다.

ES3.1은 ES4의 부분집합이 아니기 때문에 ActionScript 3.0은 ES3.1와 호환되지 않는다. 예를 들어 ES3.1의 문법에는 namespace, package가 포함되지 않는다. ES3.1은 추가 버전업을 진행하더라도 이러한 문법은 포함하지 않을 것을 분명히 하고 있다.

이러한 상황에 대해서 Adobe측에서는 정식으로 코멘트를 하고 있지 않지만 Adobe의 오픈소스팀 디렉터 Dave는 블로그를 통해서 아래와 같이 이야기를 전하고 있다.

* ECMAScript 표준화 위원회 참가 기업의 이해 불일치에 의하여 사양의 일원화가 어려운 상황이다.
* Web에 공통의 언어를 가지는 것이 필요하다는 관점으로부터 Harmony에 찬성한다.
* Web의 혁신을 더욱 진행하기 위해 ActionScript의 확장은 계속된다.
* 오픈소스 커뮤니티 활동의 발전도 표준화 위원회와의 활동과 함께 중요하게 인식하고 있다.

ECAMScript의 표준화에는 계속 참가하지만 ES3.1의 레벨까지 AS3의 기능을 되돌리는 것은 생각하지 않는 것으로 보인다. 눈에 보이는 제품의 성능에 대해서는 어느 것이 좋다 나쁘다로 판단할 근거가 명확하지만 이러한 프로그래밍 언어적 문법에 대한 표준화에는 상당한 이해관계가 얽혀 있는 듯하다.

처음 언어를 배우는 사람에게는 영어이건, 독일어이건 처음 배우는 과정에서 생산되는 엔트로피는 비슷하겠지만 이미 영어를 배우고 익숙한 학생이 독일어를 접하면 적지 않게 혼란스러운 것이 사실이다. 물론 자연어와 다르게 컴퓨터로 명령을 내리는 프로그래밍 언어의 경우는 그 안의 알고리즘 측면에서 본다면 크게 다르지 않겠으나 나와 같이 천천히 흘러가는 뇌의 전류로는 감당하기 버거울 것이다.

AS2에서 AS3로 넘어오면서 가장 나를 혼란스럽게 했던 것은 Void와 void, _alpha와 alpha, _alpha = 100과 alpha=1이었다. 지금도 그 추억에 사로잡혀 멤버변수로 _alpha와 같이 쓰고 있다. 쿠쿠

    

설정

트랙백

댓글

[CS4] Adobe Creative Suite 4 (CS4) 의 발표일 공개

Programming/ActionScript 3.0 2008. 9. 3. 23:11
Adobe 사이트에서 CS4의 발표 일정이 공개되었다. 한국판이 나오기 까지는 한두달 소요될 것으로 예상되지만  영문판이 9월 23일 예정이므로 실질적으로 사용자 컴퓨터에 FlashPlayer10 업데이트가 되는 것은 올해 안으로 50%가 넘지 않을까 싶다.

    

설정

트랙백

댓글

[AS3] DigiMix

Programming/ActionScript 3.0 2008. 7. 23. 13:27
    

설정

트랙백

댓글

[FlashPlayer10] Flash Player 10에서 보완된 기능 리스트

Programming/ActionScript 3.0 2008. 7. 21. 14:55
< 사용자 필터&효과 >

After Effects CS3에서도 사용되고 있는 Adobe Pixel Bender를 사용하여 사용자 필터, 브랜드 모드 등을 작성할 수 있습니다. Pixel Bender는 하이 퍼포먼스 화상 처리 언어입니다. Pixel Bender를 사용하여 Flash Player의 업데이트를 통해서 주어진 효과를 사용하는 것이 아닌 개발자의 독자적인 효과나 필터를 추가할 수 있습니다. 독자적인 효과나 필터는 기존의 Flash Player에 탑재되고 있는 필터와 함께 사용할 수 있습니다. 또 벡터, 비트맵, 비디오 등 모든 오브젝트에 적용할 수 있으며 오브젝트가 가지고 있는 인터랙티브적인 성질은 그대로 유지합니다. 사용자 효과는 런타임으로 적용할 수 있습니다. 또한 사용자 필터의 사이즈는 보통 1KB정도의 파일 사이즈를 갖기 때문에 플래시 콘텐츠의 용량 증가의 문제가 발생하지 않습니다.

 

< 3 차원 3D효과 >

모든 2차원 오브젝트를 3차원 형태로 변형할 수 있습니다. 사용자 필터와 같이 2차원 오브젝트가 가지고 있던 인터랙티브 성질은 그대로 유지됩니다. 기존의 Papervision3D나 Sandy, Away3D를 사용하여 3차원 처리를 고속으로 처리할 수 있습니다. 플래시툴에 기본적으로 제공하는 3차원 변형을 통해서 복잡한 3차원 처리를 간단한 코드로 기술할 수 있습니다.

 

< 새로운 텍스트 엔진 >

새로운 텍스트 엔진은 매우 유연한 텍스트 레이아웃을 제공합니다. 기존에 텍스트, 컨트롤을 통해 새로운 텍스트를 만드는 기술 보완했으며, 사용하기 쉬운 API를 제공합니다. 이로서 다양한 환경에서의 텍스트를 사용할 수 있게 되었습니다. Right-to-Left 식의 세로 형태의 레이아웃 타이포그래피도 지원됩니다.

 

<  텍스트 레이아웃 컴퍼넌트 >

레이아웃과 스타일 텍스트, 테이블, 인라인 이미지, 그리고 열 정렬을 지원합니다. 이로써 신문과 같이 복잡한 테이블 형태를 지원하게 되어 텍스트필드를 다양하게 사용할 수 있게 되었습니다.(기존에는 이러한 텍스트 필드 자체에서 지원되는 기능적 제약이 있어서 디스플레이 오브젝트에서 처리 프로세스를 따로 만들어야 하는 번거로움이 있었다.)

 

< 랜더링 API의 개선 >

기존에 화면처리에서는 특정 shape를 화면에 표시하고자 할 때 기존에 화면상에서 존재하던 그래픽 객체를 지우고 다시 그려야 하는 문제로 인하여 메모리나 성능 면에서 불필요한 시스템 자원을 낭비했었습니다. 이번 버전에서는 그러한 문제점을 보완하기 위해서 특정 shape의 일부분만을 교체할 수 있는 것이 가능하게 되어 메모리와 성능 면에서 효율적으로 처리할 수 있게 되었습니다.

 

< 컬러 관리 >

Flash Player 10은 비교적 정확한 색을 재현할 수 있게 되었다. 컬러 관리에서 swf를 sRGB 색공간(color space)으로 변경가능하며, 컬러 관리는 모니터의 ICC 칼라 프로파일과 동조하여 SWF의 색을 정확하게 재현합니다. 이는 런타임에서 실시간 컬러를 swf에 적용할 수 있습니다.

 

< 시각적인 퍼포먼스 개선 >

기존의 랜더링은 CPU가 모두 처리하였던 것을 GPU를 통해서 처리할 수 있게 되었습니다. 이로써 기존에 CPU처리 만으로 한계가 있던 화면처리 포퍼먼스를 향상시킬 수 있는 길이 열렸습니다. 결과적으로 그래픽 카드(하드웨어가속)을 이용하여 어플리케이션이 보다 매끄러운  반응 속도를 낼 수 있도록 향상되었습니다. (길이 열렸다는 의미는 아직은 GPU를 사용한 최적화에 따른 개발적인 이슈와 그에 대한 개발 가이드가 아직 나와 있지 않은 상태이기 때문이다. 앞으로 개발에 따른 문제점은 보완될 것이라 기대해 본다.)

 

< GPU로의 화상 처리 >

화상을 합성·필터의 적용·비디오의 재생이 보다 빠르게 실시할 수 있게 되었습니다. 모든 래스터 오브젝트는 비디오 카드를 사용해 처리됩니다. 하드웨어로 비트맵, 필터, 비디오를 처리하는 것은 기존의 소프트웨어로 랜더링하던 것보다도 빠르게 재생할 수 있습니다. GPU로 화상 처리하는 것은 HTML 파라미터로 사용 여부를 설정할 수 있으며 하드웨어를 사용할 수 있는 사용자 시스템에서만 적용됩니다. 사용자 하드웨어가 GPU를 사용할 수 없는 경우에는 기존대로 소프트웨어로 처리 합니다. Open GL 2.0으로 GLSL를 지원하고 있는 비디오 카드가 있는 경우에만 이 기능을 사용할 수 있습니다. Flash Player의 베타판에서는  GPU 가속으로 처리되고 있을 때는 좌측 상단에 녹색의 사각이 표시됩니다.

 

< GPU로의 비트맵 전송 >

새로운 HTML 파라미터의 설정을 통해서 SWF를 브라우저에 표시 할 때에 비디오 카드를 사용하도록 할 수 있습니다. 이 기능은 SWF를 새롭게 컴파일 할 필요 없이 사용할 수 있습니다. 이 기능은 Flash Player 9 Update 3으로 도입된 풀 스크린으로의 비디오 표시에 하드웨어 가속화 기능을 확장한 것으로, 랜더링 포퍼먼스가 개선되어 CPU 사용도 효율적으로 관리할 수 있습니다. 결과적으로 비디오나 화상을 사용하는 어플리케이션의 포퍼먼스가 개선됩니다.

 

< Anti-Aliasing 제거 엔진(Saffron 3.1) >

Saffron를 개량하여 특히 아시아권의 언어를 렌더링 할 때의 Anti-Aliasing 제거의 포퍼먼스나 품질이 개선되었습니다. 또 stroke 폰트를 지원하여 필요한 메모리를 경감시켰습니다.

 

< Vector 데이터형 >

Flash Player 10의 ActionScript 3.0에서는 ECMAScript 4를 통해서 제안되고 있는 Vector 데이터형을 지원합니다 .Vector 데이터형은 배열과 비슷하지만 요소가 모두 같은 형태가 아니면 안 되는 제약이 있습니다. 요소의 형태에 제약을 두는 것으로 배열 조작보다 포퍼먼스가 획기적으로 개선되었습니다. (일반 배열을 사용할 때 보다 10배 이상의 속도향상이 기대됨)

 

< 리치 미디어 >

Flash Player 10에서는 다음의 Adobe Flash Media Server나 다른 Adobe 제품으로 제공될 예정인 새로운 오디오·비디오 기능을 탑재했습니다.

 

< 다이나믹스 트리밍 >

네트워크의 상황에 따라 항상 최적인 비디오 품질을 유지하는 것이 가능하게 되었습니다. bit rate를 변화시키는 것을 통해서 비디오가 재생 중에 끊김이 없도록 할 수 있습니다. 이는 비디오 시청자의 대역에 맞는 비디오 전달이 가능하다는 것을 의미합니다. 앞으로 Flash Media Server에서는 네트워크의 상황에 따라 RTMP로의 비디오 전달로 bit rate를 변화시킬 수 있습니다. 리얼타임에 네트워크 상황과 CPU의 상황을 ActionScript로 확인할 수 있으므로 개발자는 그러한 정보를 바탕으로 비디오 전달을 컨트롤 할 수 있습니다. ( 동영상 플레이어로 동영상을 보다가 플레이되는 속도보다 다운로드되는 속도가 느릴 경우 중간에 버퍼링 시간으로 딜레이 되는 것을 개선할 수 있다는 의미)

 

< RTMFP (Real Time Media Flow Protocol) >

RTMFP는, 기존의 RTMP over TCP로 가고 있던 시큐어인 데이터 전달을 UDP로 실시하는 것입니다.이 기능을 이용하기 위해서는 앞으로 릴리스 되는 Flash Media Server나, 다른 Adobe 제품을 사용할 필요가 있습니다. UDP는 영상 전달을 위한 효율적인 프로토콜입니다. RTMFP로의 통신은 암호화를 위해서 영상을 보호할 수 있습니다. 이 기술은 2006년에 매수한 Amicima, Inc.에 의하는 것입니다 .

 

< File Reference runtime access >

Flash Player 9에서도 FileReference를 사용해서 로컬 파일에 액세스 하는 것은 가능합니다만 이 기능은 파일의 업 로드/다운로드를 수행하기 위한 것으로 Flash 어플리케이션에서는 일단 서버를 경유하지 않으면 로컬 파일의 데이터를 사용할 수가 없었습니다. 하지만 Flash Player 10에서는 파일의 읽고 쓰기를 위해서 서버를 사용할 필요가 없이 플래시 어플리케이션에서 읽어 들인 데이터를 바로 사용할 수 있게 되었습니다.

 

Flash Player 10의 flash.net.FileReference 클래스에 추가된 API

public function get data():ByteArray // 읽힌 데이터 (독해 전용의 프롭퍼티)

public function load():void          // 지정된 파일의 읽기 개시

public function save(data:*, name:String = null):void  // 저장처를 선택하는 다이얼로그를 표시, 그 후 데이터 저장

 

 

< 다이나믹 사운드 제너레이션 >

사운드 클래스는 사운드 오브젝트에 등록된 이벤트 리스너를 통하여 동적으로 생성된 오디오를 재생 가능하게 되었습니다.

 

< Large Bitmap Support >

Flash Player 10에서는 기존에 2880 x 2880픽셀로 제한했던 비트맵 최대 사이즈를16,777,216 픽셀(4096×4096 픽셀)까지 비트맵을 취급할 수 있게 되었습니다. (AIR를 통해서 듀얼 모니터에서 스트린캡쳐한 비트맵 데이터를 가공할 때 2880 사이즈를 벗어나 생겼던 에러로 고민한 적이 있는데 이를 통해서 쉽게 해결되었다.)

 

< context menu >

context menu용 ActionScript API를 사용하여 context menu를 좀더 자유롭게 제어가 가능하게 되었습니다. 표준 텍스트와 리치 텍스트의 양쪽 모두를 지원하고 있습니다. 클립보드 메뉴를 통해서 안전하게 제어된 방법으로 클립보드에 액세스 할 수 있으므로 텍스트의 페이스트용 핸들러를 쓸 수도 있습니다.

 

http://labs.adobe.com/technologies/flashplayer10/releasenotes.html


 

 

    

설정

트랙백

댓글

[AS3] Andre Michelle의 AudioTool

Programming/ActionScript 3.0 2008. 7. 8. 23:03
요즘 Andre Michelle이 음향 관련 놀이를 자주 한다는 생각을 했는데 결국 이런 멋진 결과물을 만들어 냈다. 오디오나 음향 관련 지식이 부족한 나에게 이걸 가지고 놀아보라고 하면 아마도 헬리콥터 장난감을 물 속에서 가지고 놀지 싶다. 플래시와 자바를 가지고 개발 했다고 하는데 앙드레의 고집스런 뚝심을 따라가려면 아직도 멀었다는 생각이 든다.










사용자 삽입 이미지

http://www.hobnox.com/index.1056.en.html
    

설정

트랙백

댓글

[Flash Player10] 의 GPU 서포트 기능에 관하여...

Programming/ActionScript 3.0 2008. 5. 24. 12:27
Flash Player10 의 GPU 서포트에 대해 Flash Player 팀의 스페셜리스트 Tinic이 blog에서 설명하고 있다.(What does GPU acceleration mean?)

Flash Player10에서는 direct 와 gpu 모드가 새롭게 추가된다.

•    direct 모드 : 화면에 최단 패스로 표시 하고 싶을 때에 사용한다.이 모드에서는 브라우저가 표시하는 영역과 Flash Player의 표시 영역이 겹쳐도 대체로 브라우저 측이 무시된다고 한다. 주로 비디오 재생에서 사용될 것으로 보인다.
•    gpu 모드 : 그래픽 카드의 기능을 이용해 오브젝트의 합성을 실시한다. 대부분의 무비 클립의 랜더링은 기존의 방식대로 소프트웨어가 처리한다.
이러한 GPU 서포트 모드를 이용하기 전에 우선 아래와 같은 사항을 주의해야 한다고 한다.
그래픽 카드의 기능을 사용했다고 반드시 랜더링이 빨리 되는 것은 아니다. 오히려 늦어지는 경우가 더 많을 가능성도 있다고 한다. GPU의 효과를 끌어 내려면 컨텐츠를 디자인할 때 GPU의 동작을 이해해 거기에 맞추어 설계할 필요가 있다고 한다. 그것을 위한 정보나 전용의 가이드는 가능한 한 빠른 시기에 제공할 수 있도록 할 것이라고 이야기 한다.

flashPlayer10에서는 아직은 시작 단계인 기능들이 새롭게 추가되고 있다. GPU기능은 아직은 시기상조이지만 앞으로 플래시의 성능을 높이는데 큰 역할을 할 것이라 본다. FileReference 또한 플래시가 서버와의 통신에 제한적이었던 부분을 좀더 자유로운 개발이 가능하도록 하고 있다.

New Text Engine이나 Text Layout Components 들은 html상의 레이아웃을 플래시 안에서 TextField로 구현이 가능할 것으로 본다. 다만 한글의 경우도 제대로 표현되기를 바란다.

이러한 성능의 발전 방향을 볼때 앞으로 플래시가 온라인과 오프라인의 경계를 무너뜨리는 크로스어플리케이션을 만드는 프로그래밍 언어의 중심이 될 수 있을 것으로 본다.
    

설정

트랙백

댓글

[AS3] TweenMax Bezier Tweening Released by Jack

Programming/ActionScript 3.0 2008. 4. 6. 21:33
TweenLite와 TweenFilterLite를 만들었던 jack이 이번에 TweenMax를 릴리즈하였다. 이번 TweenMax에서는 bezier 곡선을 지원한다.

http://blog.greensock.com/tweenmaxas3/


Tweener와 속도 비교해보면 많은 오브젝트를 tween 시킬 때의 속도 차이를 느낄 수 있다.

http://blog.greensock.com/bezier-speed-test/
    

설정

트랙백

댓글

[AIR] FlashDevelop, 플래시에서 AIR 퍼블리시

Programming/AIR 2008. 3. 7. 17:48
플래시를 이용하여 AIR를 퍼블리시할 때 플래시툴이 임시로 해당 폴더에 AppIconsForAIRPublish 폴더를 생성했다가 사라지는데 FlashDevelop 프로그램을 사용해서 코딩을 하고 있을 때라면 FlashDevelop 프로그램이 특정 시점에서 project 폴더를 리로드 하는 관계로 FlashDevelop 프로그램이 사라져야할 AppIconsForAIRPublish 폴더를 물고 있게 된다.

AppIconsForAIRPublish 폴더가 남아 있을 경우 플래시에서 AIR를 퍼블리시 할 때 에러메시지를 유발할 수 있으며 이때는 FlashDevelop 프로그램을 닫았다가 다시 열어야 한다.


    

설정

트랙백

댓글

[AIR] NativeWindow의 minSize = width:119, height:34 ?

Programming/AIR 2008. 3. 3. 16:43
NativeWindow.minSize의 최소 값은 read only 속성인 NativeWindow.systemMinSize 값 이하로 내려갈 수 없도록 되어 있는 듯 하다. NativeWindowSystemChrome을 NONE으로 하게 될 경우  SystemChrome을 사용하지 않기 때문에 최소 영역을 제한할 필요가 없을 듯 싶은데 말이다.

혹시나 싶어서 NativeWindowInitOptions의 Type를 NativeWindowType.LIGHTWEIGHT로 적용을 해 봐도 역시나 기본적으로 NativeWindow.systemMinSize 사이즈인 가로 : 119, 세로 34 이하로 세팅 할 수 없다.

어쩔 수 없이 가로와 세로 사이즈를 NativeWindow.systemMinSize 사이즈 이하로 하기 위해서는 transparent로 뚫어서 눈 속임을 해야 할 듯싶다. Transparent를 적용하면 화면 크기에 따라서 AIR가 CPU를 너무 잡순다… 웹에서 문제되던 transparent의 고질적인 CPU문제는 AIR도 여전히 가지고 다니니… AIR 2.0 버전에서는 하드웨어 그래픽 가속을 처리할 수 있는 멋진 녀석이 되길…

    

설정

트랙백

댓글

[AS3] FlashPlayer UPDATE3의 System.gc()

Programming/ActionScript 3.0 2008. 2. 9. 22:52
예전에 System.gc 내장 함수가 없었던 것으로 알고 있는데 업데이트 버전에서 생겨난 듯 하다. 기존에는 개발자가 강제로 CG를 실행시킬 수 없어서 완전한 메모리 테스트는 사실상 불가능 했다. 물론 강제로 많은 오브젝트를 생성하는 과정에서 일정한 메모리(FlashPlayer가 예상하는 적정 사용영역)을 벗어날 경우를 임의로 만들어서 확인할 수는 있었으나 이것 또한 어느 정도의 메모리 영역을 CG가 동작하는 시작점으로 보는가를 알 수 없기 때문에 어려움이 있었다.

System 클래스에서 지원하는 메소드에 gc가 있다. 이는 자바에서의 System.gc와 같이 이 함수를 실행하는 시점에서 강제로 CG가 동작하게 된다. 문제는 자바와 같이 플래시도 full gc를 할 경우 시스템 리소스 낭비가 예상된다는 것이다. System.gc 실행은 개발 테스트 과정에서 사용하되 작업물에서의 동적인 강제 실행은 피하는 것이 좋을 듯 싶으나 이는 이미 웹상에서는 System.gc가 작동하지 않는 듯 싶다. 경험상 flashPlayer9버전의 가비지콜렉터는 상당히 안정적이고 신뢰 할만 하다.

아래 예제로 만든 것을 보면 replay 버튼을 누름과 동시에 Event.ENTER_FRAME 이벤트가 등록된 sprite를 통해서 이벤트가 발생할 때마다 임의로 TextField를 생성과 소멸을 반복한다. 50개의 TextField가 생성되는 시점에서 Event.ENTER_FRAME가 등록된 sprite를 메모리해서 해제시킨다.

여기서 많은 개발자들이 Event.ENTER_FRAME 이벤트가 적용된 상태에서 removeEventListener로 이벤트를 해제하지 않고 sprite를 메모리 해제 시도를 했기 때문에 메모리에서 지워지지 않는다고 생각하는 듯 하다. 나도 예전에는 이 부분이 상당히 모호했다.  addEventListener로 강참조를 할 경우라도 역참조가 아닌 이상은 이벤트가 적용된 오브젝트가 메모리에서 해제하고 GC를 통해서 free memory가 되면 자동으로 등록되어 있는 이벤트도 발생하지 않는다.

여기서 혼돈했던 이유는 개발자가 강제로 가비지콜렉션을 실행하지 못하는 상황에서 sprite가 메모리에서 해제되지 않아서 이벤트가 계속 발생하는 것인지, gc가 동작하지 않아서 해제되지 않는 것인지 모호했기 때문이다.

아래의 예제에서 gc 동작버튼을 누르지 않더라도 일정한 시간이 지나면 flashplayer가 적당한 시점에서 gc를 가동하여 Event.ENTER_FRAME 이벤트가 등록된 sprite를 메모리에서 해제하면서 Event.ENTER_FRAME 이벤트도 발생하지 않게 된다. System.gc를 이러한 gc의 동작을 강제로 실행하므로써 개발자에게 즉시 free memory가 되었다는 것을 알려주므로 개발과정에서 요긴하게 사용될 듯싶다.

아래 swf상에서는 System.gc 함수가 실행되지 않는다. fla를 다운로드하여 로컬상에서 테스트 해보길 바란다.




    

설정

트랙백

댓글

[AS3] Tween Engine (TweenLite)

Programming/ActionScript 3.0 2008. 2. 5. 19:28
TweenBencher 을 이용해서 AS3용 Tween 엔진을 테스트 해 봤다. 1등은 단연 Simple AS3 Tween으로 나왔는데 이것은 따로 클래스화 되어 있는 것이 아니고 fl.motion.easing.Exponential 의 easeInOut 함수만을 따로 빼서 직접 width을 적용한 형태라서 빠를 수 밖에 없다. 테스트를 하지 않은 fl 기본 트윈 클래스나 기타 다른 것들은 비교할만한 속도를 내지 못하여 제외 하였다.

비교 대상이 되는 것들은 Tweener TweenLite이다. Tweener은 그 사용법과 Bezier 곡선 처리 기능을 제공하기 때문에 사용성면에서 좋은 엔진이지만 많은 기능들이 포함되어 있는 만큼 속도는 약간 떨어진다.








Benchmark results: Simple AS3 Tween
------------------
125 Sprites    ::    Start Lag: 0 seconds    ::    FPS: 57
250 Sprites    ::    Start Lag: 0 seconds    ::    FPS: 57
500 Sprites    ::    Start Lag: 0 seconds    ::    FPS: 55
1000 Sprites    ::    Start Lag: 0 seconds    ::    FPS: 47
2000 Sprites    ::    Start Lag: 0.01 seconds    ::    FPS: 38
4000 Sprites    ::    Start Lag: 0.06 seconds    ::    FPS: 26

Benchmark results: TweenLite
------------------
125 Sprites    ::    Start Lag: 0 seconds    ::    FPS: 61
250 Sprites    ::    Start Lag: 0 seconds    ::    FPS: 55
500 Sprites    ::    Start Lag: 0.01 seconds    ::    FPS: 40
1000 Sprites    ::    Start Lag: 0.01 seconds    ::    FPS: 31
2000 Sprites    ::    Start Lag: 0.02 seconds    ::    FPS: 23
4000 Sprites    ::    Start Lag: 0.18 seconds    ::    FPS: 19

Benchmark results: Tweener
------------------
125 Sprites    ::    Start Lag: 0.11 seconds    ::    FPS: 56
250 Sprites    ::    Start Lag: 0.02 seconds    ::    FPS: 61
500 Sprites    ::    Start Lag: 0.06 seconds    ::    FPS: 46
1000 Sprites    ::    Start Lag: 0.2 seconds    ::    FPS: 33
2000 Sprites    ::    Start Lag: 0.45 seconds    ::    FPS: 25
4000 Sprites    ::    Start Lag: 1.4 seconds    ::    FPS: 17

TweenLite는 filter에 관련된 기능들은 TweenFilterLite로 따로 빠져있다. 특별한 기능이 아닌 오브젝트의 모션 처리는 x,y,scaleX, scaleY, width, height, alpha 등과 추가하면 color 적용일 것이다. TweenLite는 tint 속성으로 그것을 대신하고 있다. 기본적인 사용법은 아래와 같다.

import gs.TweenLite;
TweenLite.to(mc, 1, {x:46, y:43, scaleX:1, scaleY:1, rotation:0, alpha:1, tint:0x3399ff});

사용법이 Tweener와 많은 부분 흡사하다. mc는 타겟이되는 Object, 1은 모션 time이고 {} 오브젝트 형태로 적용 속성들과 모션 함수를 적용할 수가 있다. ease 속성으로 모션 함수를 적용할 수가 있는데 함수는 fl.motion.easing 패키지 안에 있는 함수를 적용하게 되므로 fl.motion.easing 패키지를 import 시켜서 사용하면 된다. 그리고 Tweener에서와 같이 onStart, onUpdate, onComplete 를 지원한다. 아래 예,

        import gs.TweenLite;
        import fl.motion.easing.Back;
        TweenLite.to(mc, 5, {alpha:0.5, x:120, ease:Back.easeOut, delay:2,
                                        onComplete:onFinishTween, onCompleteParams:[5, clip_mc]});
        function onFinishTween(argument1:Number, argument2:MovieClip):void {
                trace("The tween has finished! argument1 = " + argument1 + ",
                and argument2 = " + argument2);
        }

[Flash] http://www.greensock.com/ActionScript/TweenLiteAS3/TweenLiteAS3_Sample_1.swf



USAGE

TweenLite.to(target:Object, duration:Number, variables:Object);

  • Description: Tweens the target's properties from whatever they are at the time you call the method to whatever you define in the variables parameter.
  • Parameters:
    1. target: Target MovieClip (or any object) whose properties we're tweening
    2. duration: Duration (in seconds) of the tween
    3. variables: An object containing the end values of all the properties you'd like to have tweened (or if you're using the TweenLite.from() method, these variables would define the BEGINNING values). Putting quotes around values will make the tween relative to the current value. For example, x:"-20" will tween x to whatever it currently is minus 20 whereas x:-20 will tween x to exactly -20. Here are some examples of properties you might include:
      • alpha: The alpha (opacity level) that the target object should finish at (or begin at if you're using TweenLite.from()). For example, if the target.alpha is 1 when this script is called, and you specify this parameter to be 0.5, it'll transition from 1 to 0.5.
      • x: To change a MovieClip's x position, just set this to the value you'd like the MovieClip to end up at (or begin at if you're using TweenLite.from()).

      Special Properties (**Optional**):

      • delay: The number of seconds you'd like to delay before the tween begins. This is very useful when sequencing tweens
      • ease: You can specify a function to use for the easing with this variable. For example, fl.motion.easing.Elastic.easeOut. The Default is Regular.easeOut.
      • easeParams: An array of extra parameter values to feed the easing equation. This can be useful when you use an equation like Elastic and want to control extra parameters like the amplitude and period. Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams.
      • autoAlpha: Same as changing the "alpha" property but with the additional feature of toggling the "visible" property to false if the alpha ends at 0. It will also toggle visible to true before the tween starts if the value of autoAlpha is greater than zero.
      • volume: To change a MovieClip's volume, just set this to the value you'd like the MovieClip to end up at (or begin at if you're using TweenLite.from()).
      • tint: To change a MovieClip's color, set this to the hex value of the color you'd like the MovieClip to end up at(or begin at if you're using TweenLite.from()). An example hex value would be 0xFF0000. If you'd like to remove the color from a MovieClip, just pass null as the value of tint. Before version 5.8, tint was called mcColor (which is now deprecated and will likely be removed at a later date although it still works)
      • onStart: If you'd like to call a function as soon as the tween begins, pass in a reference to it here. This can be useful when there's a delay and you want something to happen just as the tween begins.
      • onStartParams: An array of parameters to pass the onStart function.
      • onUpdate: If you'd like to call a function every time the property values are updated (on every frame during the time the tween is active), pass a reference to it here.
      • onUpdateParams: An array of parameters to pass the onUpdate function (this is optional)
      • onComplete: If you'd like to call a function when the tween has finished, use this.
      • onCompleteParams: An array of parameters to pass the onComplete function (this is optional)
      • overwrite: If you do NOT want the tween to automatically overwrite any other tweens that are affecting the same target, make sure this value is false.




TweenLite.from(target:Object, duration:Number, variables:Object);

  • Description: Exactly the same as TweenLite.to(), but instead of tweening the properties from where they're at currently to whatever you define, this tweens them the opposite way - from where you define TO where ever they are now (when the method is called). This is handy for when things are set up on the stage where the should end up and you just want to animate them into place.
  • Parameters: Same as TweenLite.to(). (see above)




TweenLite.delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array);

  • Description: Provides an easy way to call any function after a specified number of seconds. Any number of parameters can be passed to that function when it's called too.
  • Parameters:
    1. delay: Number of seconds before the function should be called.
    2. onComplete: The function to call
    3. onCompleteParams [optional] An array of parameters to pass the onComplete function when it's called.




TweenLite.killTweensOf(target:Object, complete:Boolean);

  • Description: Provides an easy way to kill all tweens of a particular Object/MovieClip. You can optionally force it to immediately complete (which will also call the onComplete function if you defined one)
  • Parameters:
    1. target: Any/All tweens of this Object/MovieClip will be killed.
    2. complete: If true, the tweens for this object will immediately complete (go to the ending values and call the onComplete function if you defined one).




TweenLite.killDelayedCallsTo(function:Function);

  • Description: Provides an easy way to kill all delayed calls to a particular function (ones that were instantiated using the TweenLite.delayedCall() method).
  • Parameters:
    1. function: Any/All delayed calls to this function will be killed.


EXAMPLES


As a simple example, you could tween the alpha to 50% (0.5) and move the x position of a MovieClip named "clip_mc" to 120 and fade the volume to 0 over the course of 1.5 seconds like so:
  1. import gs.TweenLite;
  2. TweenLite.to(clip_mc, 1.5, {alpha:0.5, x:120, volume:0});



If you want to get more advanced and tween the clip_mc MovieClip over 5 seconds, changing the alpha to 50% (0.5), the x coordinate to 120 using the Back.easeOut easing function, delay starting the whole tween by 2 seconds, and then call a function named "onFinishTween" when it has completed and pass in a few parameters to that function (a value of 5 and a reference to the clip_mc), you'd do so like:
  1. import gs.TweenLite;
  2. import fl.motion.easing.Back;
  3. TweenLite.to(clip_mc, 5, {alpha:0.5, x:120, ease:Back.easeOut, delay:2, onComplete:onFinishTween, onCompleteParams:[5, clip_mc]});
  4. function onFinishTween(parameter1_num:Number, parameter2_mc:MovieClip):void {
  5.     trace("The tween has finished! parameters: " + parameter1_num + ", and " + parameter2_mc);
  6. }


If you have a MovieClip on the stage that is already in its end position and you just want to animate it into place over 5 seconds (drop it into place by changing its y property to 100 pixels higher on the screen and dropping it from there), you could:
  1. import gs.TweenLite;
  2. import fl.motion.easing.Elastic;
  3. TweenLite.from(clip_mc, 5, {y:"-100", ease:Elastic.easeOut});

FAQ

  1. Can I set up a sequence of tweens so that they occur one after the other?
    Of course! Just use the delay property and make sure you set the overwrite property to false (otherwise tweens of the same object will always overwrite each other to avoid conflicts). Here's an example where we colorize a MovieClip red over the course of 2 seconds, and then move it to a _y coordinate of 300 over the course of 1 second:
    1. import gs.TweenLite;
    2. TweenLite.to(clip_mc, 2, {tint:0xFF0000});
    3. TweenLite.to(clip_mc, 1, {y:300, delay:2, overwrite:false});

  2. Do the properties have to be in a specific order?
    Nope. The only thing that matters is that the first parameter is the object you're tweening, the second parameter is the time (in seconds), and the third parameter contains all the properties you want to tween (in any order). So TweenLite.to(clip_mc, 1, {scaleX:120, y:200, x:1}) is the same as TweenLite.to(clip_mc, 1, {x:1, y:200, scaleX:120});

  3. Why are TweenLite and TweenFilterLite split into 2 classes instead of building all the functionality into one class?
    1. File size. Only a portion of projects out there require tweening of filters. Almost every project I work on uses TweenLite, but only a few require tweening filters (TweenFilterLite). TweenLite is 2k whereas TweenFilterLite is 5k. Again, one of the stated purposes of TweenLite is to minimize file size & code bloat. If someone only wants to use TweenFilterLite, fine. But I think many people appreciate being able to use the most lightweight option for their needs and shave off the 3k when possible.
    2. Speed. Tweening filters is a more complex task. There are additional if/else statements and calculations in the rendering loop inside TweenFilterLite which could potentially slow things down a bit, even for non-filter tweens (I doubt anyone would notice a difference unless they’re running hundreds or thousands of simultaneous tweens, but I’m a big fan of keeping things as efficient & fast as possible)

  4. Do I have to pay for a license to use this code? Can I use it for commercial purposes?
    Feel free to take the code and use it as you wish, even for commercial purposes. Some people have requested the ability to donate money to reward the work I put into the class(es), so i put a PayPal "donate now" button at the top and bottom of the page, but you certainly don't need to donate anything. I'm just glad to help the Flash community.

  5. Are TweenLite and TweenFilterLite better than Tweener, Fuse, MC Tween, and all the other tweening engines out there?
    Maybe, maybe not. It all depends on your objectives, coding style, etc. I certainly don't claim that TweenLite & TweenFilterLite are superior to all other tweening engines, but in terms of the power-to-file-size ratio, I certainly haven't seen anything that comes close. Feedback has been overwhelmingly positive. I've used TweenLite for many years and it hasn't let me down. I never found myself needing features that are available in another tweening engine. But hey, to each his own.

[Flash] http://www.greensock.com/ActionScript/TweenFilterLiteAS3/TweenFilterLiteAS3_Sample.swf



OBJECTIVES

  • Minimize file size
  • Maximize flexibility and efficiency by extending the TweenLite class. That way, if you don't need to tween filters, you can just use TweenLite (about 2k); otherwise, this class will only add another 3k (5k total)
  • Minimize the amount of code required to initiate a tween
  • Maximize performance
  • Allow for very flexible callbacks (onComplete, onUpdate, onStart, all with the ability to pass any number of parameters)

FITLERS & PROPERTIES:

  • type:"Blur" -
    blurX, blurY, quality
  • type:"Glow" -
    alpha, blurX, blurY, color, strength, quality
  • type:"Color" -
    colorize, amount, contrast, brightness, saturation, hue, threshold, relative
  • type:"DropShadow" -
    alpha, angle, blurX, blurY, color, distance, strength, quality
  • type:"Bevel" -
    angle, blurX, blurY, distance, highlightAlpha, highlightColor, shadowAlpha, shadowColor, strength, quality

USAGE

TweenFilterLite.to(target:DisplayObject, duration:Number, variables:Object);

  • Description: Tweens the target's properties from whatever they are at the time you call the method to whatever you define in the variables parameter.
  • Parameters:
    1. target: Target DisplayObject whose properties we're tweening
    2. duration: Duration (in seconds) of the tween
    3. variables: An object containing the end values of all the properties you'd like to have tweened (or if you're using the TweenFilterLite.from() method, these variables would define the BEGINNING values). Putting quotes around values will make the tween relative to the current value. For example, x:"-20" will tween x to whatever it currently is minus 20 whereas x:-20 will tween x to exactly -20. Here are some examples of properties you might include:
      • blurX
      • blurY
      • color: An example for red would be 0xFF0000. Several filters use this property, like DropShadow and Glow
      • colorize: Only used with a type:"Color" tween to colorize an entire MovieClip.
      • amount: Only used to control the amount of colorization.

      Special Properties:

      • type: REQUIRED. A string that indicates what type of filter you're tweening. Possible values are: "Color" (for all image effects like colorize, brightness, contrast, saturation, and threshold), "Blur", "Glow", "DropShadow", or "Bevel"
      • delay: Number of seconds to delay before the tween begins. This can be very useful when sequencing tweens.
      • ease: You can specify a function to use for the easing with this variable. For example, fl.motion.easing.Elastic.easeOut. The Default is Regular.easeOut.
      • easeParams: An array of extra parameter values to feed the easing equation. This can be useful when you use an equation like Elastic and want to control extra parameters like the amplitude and period. Most easing equations, however, don't require extra parameters so you won't need to pass in any easeParams.
      • autoAlpha: Same as changing the "alpha" property but with the additional feature of toggling the "visible" property to false if the alpha ends at 0. It will also toggle visible to true before the tween starts if the value of autoAlpha is greater than zero.
      • volume: To change a MovieClip's volume, just set this to the value you'd like the MovieClip to end up at (or begin at if you're using TweenFilterLite.from()).
      • tint:To change a MovieClip's color, set this to the hex value of the color you'd like the MovieClip to end up at(or begin at if you're using TweenLite.from()). An example hex value would be 0xFF0000. If you'd like to remove the color from a MovieClip, just pass null as the value of tint. Before version 5.8, tint was called mcColor (which is now deprecated and will likely be removed at a later date although it still works)
      • onStart: If you'd like to call a function as soon as the tween begins, pass in a reference to it here. This can be useful when there's a delay and you want something to happen just as the tween begins.
      • onStartParams: An array of parameters to pass the onStart function.
      • onUpdate: If you'd like to call a function every time the property values are updated (on every frame during the time the tween is active), pass a reference to it here.
      • onUpdateParams: An array of parameters to pass the onUpdate function (this is optional)
      • onComplete: If you'd like to call a function when the tween has finished, use this.
      • onCompleteParams: An array of parameters to pass the onComplete function (this is optional)
      • overwrite: If you do NOT want the tween to automatically overwrite any other tweens that are affecting the same target, make sure this value is false.



TweenFilterLite.from(target:DisplayObject, duration:Number, variables:Object);

  • Description: Exactly the same as TweenFilterLite.to(), but instead of tweening the properties from where they're at currently to whatever you define, this tweens them the opposite way - from where you define TO where ever they are now (when the method is called). This is handy for when things are set up on the stage the way the should end up and you just want to tween them to where they are.
  • Parameters: Same as TweenFilterLite.to(). (see above)



TweenLite.delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array);

  • Description: Provides an easy way to call any function after a specified number of seconds. Any number of parameters can be passed to that function when it's called too.
  • Parameters:
    1. delay: Number of seconds before the function should be called.
    2. onComplete: The function to call
    3. onCompleteParams [optional] An array of parameters to pass the onComplete function when it's called.




TweenFilterLite.killTweensOf(target:Object, complete:Boolean);

  • Description: Provides an easy way to kill all tweens of a particular Object/MovieClip. You can optionally force it to immediately complete (which will also call the onComplete function if you defined one)
  • Parameters:
    1. target: Any/All tweens of this Object/MovieClip will be killed.
    2. complete: If true, the tweens for this object will immediately complete (go to the ending values and call the onComplete function if you defined one).




TweenFilterLite.killDelayedCallsTo(function:Function);

  • Description: Provides an easy way to kill all delayed calls to a particular function (ones that were instantiated using the TweenFilterLite.delayedCall() method).
  • Parameters:
    1. function: Any/All delayed calls to this function will be killed.


EXAMPLES

As a simple example, you could tween the blur of clip_mc from where it's at now to 20 over the course of 1.5 seconds by:
  1. import gs.TweenFilterLite;
  2. TweenFilterLite.to(clip_mc, 1.5, {type:"Blur", blurX:20, blurY:20});

If you want to get more advanced and tween the clip_mc MovieClip over 5 seconds, changing the saturation to 0, delay starting the whole tween by 2 seconds, and then call a function named "onFinishTween" when it has completed and pass in a few arguments to that function (a value of 5 and a reference to the clip_mc), you'd do so like:
  1. import gs.TweenFilterLite;
  2. import fl.motion.easing.Back;
  3. TweenFilterLite.to(clip_mc, 5, {type:"Color", saturation:0, delay:2, onComplete:onFinishTween, onCompleteParams:[5, clip_mc]});
  4. function onFinishTween(argument1_num:Number, argument2_mc:MovieClip):void {
  5.     trace("The tween has finished! argument1_num = " + argument1_num + ", and argument2_mc = " + argument2_mc);
  6. }
If you have a MovieClip on the stage that already has the properties you'd like to end at, and you'd like to start with a colorized version (red: 0xFF0000) and tween to the current properties, you could:
  1. import gs.TweenFilterLite;
  2. TweenFilterLite.from(clip_mc, 5, {type:"color", colorize:0xFF0000});

FAQ

  1. Can I set up a sequence of tweens so that they occur one after the other?
    Of course! Just use the delay property and make sure you set the overwrite property to false (otherwise tweens of the same object will always overwrite each other to avoid conflicts). Here's an example where we colorize a MovieClip red over the course of 2 seconds, and then blur it over the course of 1 second:
    1. import gs.TweenFilterLite;
    2. TweenFilterLite.to(clip_mc, 2, {type:"color", colorize:0xFF0000, amount:1});
    3. TweenFilterLite.to(clip_mc, 1, {type:"blur", blurX:20, blurY:20, delay:2, overwrite:false});

  2. Do the properties have to be in a specific order?
    Nope. The only thing that matters is that the first parameter is the object you're tweening, the second parameter is the time (in seconds), and the third parameter contains all the properties you want to tween (in any order). So TweenFilterLite.to(clip_mc, 1, {type:"color", colorize:0xFF0000, amount:1}) is the same as TweenFilterLite.to(clip_mc, 1, {amount:1, colorize:0xFF0000, type:"color"});

  3. Can I use TweenFilterLite to tween things other than filters?
    Sure. It extends TweenLite, so you can tween any property you want. TweenFilterLite.to(my_mc, 1, {x:200}) gives you the same result as TweenLite.to(my_mc, 1, {x:200}). However, I'd recommend using TweenLite to tween properties other than filters for two reasons:
    1. In order to accommodate the specialized nature of filters, TweenFilterLite's code is a bit lengthier which translates into more work for the processor. It's doubtful that anyone would notice a performance hit unless you're tweening hundreds or thousands of instances simultaneously, but I'm a bit of an efficiency freak.
    2. TweenLite can tween any property of ANY object whereas TweenFilterLite tweens properties of DisplayObjects (like MovieClips, Sprites, etc.)

  4. Why are TweenLite and TweenFilterLite split into 2 classes instead of building all the functionality into one class?
    1. File size. Only a portion of projects out there require tweening of filters. Almost every project I work on uses TweenLite, but only a few require tweening filters (TweenFilterLite). TweenLite is 2k whereas TweenFilterLite is 5k. Again, one of the stated purposes of TweenLite is to minimize file size & code bloat. If someone only wants to use TweenFilterLite, fine. But I think many people appreciate being able to use the most lightweight option for their needs and shave off the 3k when possible.
    2. Speed. Tweening filters is a more complex task. There are additional if/else statements and calculations in the rendering loop inside TweenFilterLite which could potentially slow things down a bit, even for non-filter tweens (I doubt anyone would notice a difference unless they’re running hundreds or thousands of simultaneous tweens, but I’m a big fan of keeping things as efficient & fast as possible)

  5. Do I have to pay for a license to use this code? Can I use it for commercial purposes?
    Feel free to take the code and use it as you wish, even for commercial purposes. Some people have requested the ability to donate money to reward the work I put into the class(es), so i put a PayPal "donate now" button at the top and bottom of the page, but you certainly don't need to donate anything. I'm just glad to help the Flash community.

  6. Are TweenLite and TweenFilterLite better than Tweener, Fuse, MC Tween, and all the other tweening engines out there?
    Maybe, maybe not. It all depends on your objectives, coding style, etc. I certainly don't claim that TweenLite & TweenFilterLite are superior to all other tweening engines, but in terms of the power-to-file-size ratio, I certainly haven't seen anything that comes close. Feedback has been overwhelmingly positive. I've used TweenLite for many years and it has never let me down. I've never found myself needing features that are available in another tweening engine. But hey, to each his own.
    

설정

트랙백

댓글

[AS3] Linkage 클래스를 필요할때 참조

Programming/ActionScript 3.0 2008. 1. 29. 18:09

















public function getDefinitionByName(name:String):Object

플래시에서의 Public 함수 중에서 getDefinitionByName() 함수는 name 매개 변수로 지정된 클래스의 클래스 객체에 대한 참조를 반환해 준다.

var c:Class = getDefinitionByName("m"+2) as Class;  // 라이브러리에 있는 Linkage 클래스명 "m2"의 참조를 반환한다.

package {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.utils.getDefinitionByName;

public class GetDefinitionByNameExample extends Sprite {
private var bgColor:uint = 0xFFCC00;
private var size:uint = 80;

public function GetDefinitionByNameExample() {
var ClassReference:Class = getDefinitionByName("
flash.display.Sprite") as Class;
var instance:Object = new ClassReference();
instance.graphics.beginFill(bgColor);
instance.graphics.drawRect(0, 0, size, size);
instance.graphics.endFill();
addChild(DisplayObject(instance));
}
}
}

    

설정

트랙백

댓글