Apache Jakarta(이하 Web Server)와 Apache Tomcat(이하 WAS)로 구성되어 있는 홈페이지가 꾀 존재하는 것으로 알 고 있다.

그런데 이런 홈페이지 중에 금저의 이유로 L4를 쓰지 못해 L4와 유사 기능을 하는 소프트웨어를 설치하여(HA-Proxy) 로드발란싱과 Fail-Over 기능을 대체하고 있습니다.


그런데 HA-Proxy를 거쳐서 Web Server를 통하여 ajp1.3으로 WAS와 연동하는 구조에서 Web Server 까지는 Client의 실제 IP를 X-Forwarded-For라는 X-Host Header 정보로 확인이 가능하지만 Web Server에서 WAS로 보내지는 Reqeust에서는 이 X-Host Header 정보가 보내지지 않아 IP Filter 작업을 할 때 애를 먹게 되는 경우가 있습니다.



구성도시스템 구성도


위 구성도에서 보면 HA-Proxy1에서 Web Server와 통신할 때에는 HTTP 통신이기 때문에 Client의 실제 IP를 확인할 수 있습니다. 하지만 HA-Proxy2에서는 Web Server와 WAS의 통신이 AJP 1.3이라는 TCP/IP통신을 하게 되면서 실제 클라이언트 IP가 아닌 Web Sever에서 AJP1.3 통신을 하기위한 IP가 Client IP가 되어 WAS에서 확인하게 됩니다.


WAS에서는 Client IP가 Web Server가 됨WAS에서는 Client IP가 Web Server가 됨


이 처럼 HA-Proxy와 같은 소프트웨어 로드밴런싱 도구를 사용하는 경우 WAS에서 Client IP를 알 수 있는 방법은 없습니다. 해서 사용되는 것이 

X-Forwarded-For라는 X-Host 헤더정보 입니다. 사실 Web Server의 입장에서도 WAS와 동일하게 HA-Proxy1이 있는 Server가 Client가 됩니다. 해서 Web Server에서 로그를 남길 때 %h또는 %{c}a 를 할 때 HA-Proxy 서버의 IP가 확인 됩니다. 하지만 %{X-Forwarded-For}를 하면 실제 Client IP가 확인되게 됩니다. 물론 HA-Proxy에서 X-Forwarded-For 헤더정보로 Client IP를 실어서 보낼 수 있도록 설정을 미리 해두어야 합니다.


오늘은 HA-Proxy에서 X-Forwarded-For 헤더로 Client IP를 더하여서 Web Server로 보내고 있다고 가정하고 Web Server의 설정과 WAS의 설정을 확인해 보도록 하겠습니다.


사실 Web Server도 X-Forwarded-For 헤더를 WAS로 보내는 설정만 하면 됩니다. 문제는 mod_jk.so 파일의 버전입니다. mod_jk.so를 추가하고 <IfModule jk_module>에서 JkOptions라는 곳에 옵션으로 +ForwardPhysicalAddress라는 명령어를 추가해야 이 명령어를 추가하면 에러가 발생하는 경우를 보게 됩니다. 그래서 mod_jk의 버전별 ChangeLog를 확인해 보았는데 mod_jk 1.2.39버전부터 ForwardPhysicalAddress 옵션을 JkOptions로 사용할 수 있음을 보게 됩니다. 해서 mod_jk 소스를 최신버전으로 다시 받아서 compile하고 mod_jk.so파일을 변경해 주었습니다.


다음은 mod_jk소스를 받아서 compile하는 과정입니다.


1. 최신 mod_jk.so 컴파일 하기

우선 mod_jk 최신 버전을 다운로드 받습니다(현재 2014-04-22일 최고 버전은 1.2.40 입니다).

[root@localhost ~]# wget http://mirror.apache-kr.org/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.40-src.tar.gz


다운로드된 파일을 압축을 해제합니다.

[root@localhost ~]# tar -zxvf tomcat-connectors-1.2.40-src.tar.gz


압축해제된 디렉토리의 native 폴더로 이동합니다.

[root@localhost ~]# cd tomcat-connectors-1.2.40-src/native/


configure 파일에 apxs위치를 설정해 줍니다. 

[root@localhost native]# ./configure --with-apxs=${webserver.home:web server 설치 디렉토리}/bin/apxs


make 또는 make install 합니다. make install 하게 되면 아파치 홈 디렉토리의 /modules 폴더에 자동을 mod_jk.so파일이 복사된다고 하더군요.

[root@localhost native]# make


[root@localhost native]# make install


하지만 혹시 모르니 그냥 mod_jk.so파일을 아파치 홈 디렉토리의 /modules 폴더에 복사합니다.


자 이제 최신 mod_jk.so는 구했습니다. 다음은 아파치 설정을 하도록 하겠습니다.


2.아파치 설정하기

web server 홈 디렉토리의 설정파일로 이동합니다. 저는 Apache Jakarta(Web Server)를 사용하고 있기 때문에 ${webserver.home}/conf/httpd.conf 파일을 수정하도록 하겠습니다. httpd.conf 파일에 LoadModule하는 부분 마지막에 다음을 추가 합니다.


LoadModule jk_module modules/mod_jk.so


그리고 <IfModule jk_module>에 JkOptions를 추가합니다.


<IfModule jk_module>

        JkWorkersFile ...

        JkShmFile ...

        JkLogFile ...

        JkOptions +ForwardKeySize +ForwardPhysicalAddress +ForwardURIProxy

        JkLogLevel error

</IfModule>


이렇게 JKOptions에 +ForwardKeySize +ForwardPhysicalAddress +ForwardURIProxy 를 추가 합니다. JkOptions에는 어떤 값이 있고 의미하고 있는 것이 무엇인지는 아래 링크를 참조해주시기 바랍니다.


>>JkOptions링크 클릭<<


자 이렇게 한 후에는 한 가지 추가적으로 더 해줘야 할  것이 있습니다. 바로 mod_remoteip.so 파일을 추가해주는 것입니다. 이미 httpd.conf에는 mod_remoteip.so가 있습니다. 주석처리 되어 있는 것을 삭제해 주시면 됩니다. 그리고 이 또한 설정을 해줘야 합니다. 다음은 

<IfModule remote_module>에 대한 설정입니다.


<IfModule remoteip_module>

    RemoteIPHeader X-Client-IP

    RemoteIPInternalProxy 127.0.0.1

</IfModule>


remoteip_module에 대한 설정은 다음 링크를 확인해 주시기 바라빈다. X-Forwarded-For에 대한 내용을 jk_module로 WAS에 보내려면 위와 같이 RemoteIPHeader에 X-Client-IP라고 입력하고 RemoteIPInternalProxy에는 127.0.0.1을 입력합니다.


>>mod_remoteip 링크<<


자 이 것으로 Web Server에서는 모든 설정이 끝났습니다. 이제 WAS에서 request.getHeader("x-forwarded-for")로 Client IP를 확인해 보면 정상적인 Client IP가 확인되게 됩니다.


HA-Proxy에서 X-Forwarded-For를 구성하는 방법은 다음 링크 또는 X-Forwarded-For on HA-Proxy를 구글링 해보시기를 추천듭니다.


>>HA-Proxy 링크<<<


감사합니다.



Posted by gofly

댓글을 달아 주세요

  1. BlogIcon 성현 2015.06.24 18:56  댓글주소  수정/삭제  댓글쓰기

    제가 위와 같은 문제가 발생한 상태인데 글 내용대로 똑같이 따라했는데 잘 안되네요... 혹시 따로 연락 가능하시면 도움좀 받을 수 있을까요?... ㅠ

  2. BlogIcon 성현 2015.06.24 18:56  댓글주소  수정/삭제  댓글쓰기

    제가 위와 같은 문제가 발생한 상태인데 글 내용대로 똑같이 따라했는데 잘 안되네요... 혹시 따로 연락 가능하시면 도움좀 받을 수 있을까요?... ㅠ

Visual Studio에서 JavaScript 응용프로그램 개발하기


Before delving into the details of the application, I want to say a few things about JavaScript application development. One of the challenges facing the JavaScript developer is the dynamic nature of the language. With JavaScript you aren’t constrained by a rigid type system; instead, objects can be built dynamically. This poses a challenge to the developers of JavaScript editors and IDEs. With strongly typed languages such as C# and Java, the type information can be used to provide enhanced code navigation, refactoring and IntelliSense. With JavaScript, on the other hand, the lack of type information means that the IDE typically provides far fewer developer aids.
응용프로그램의 자세한 사항으로 들어가기 앞서, 저는 JavaScript 응용프로그램 개발에 대하여 몇 가지 이야기 하고 싶습니다. 훌륭한 JavaScript 개발자로 도전할만 한 것은 언어의 역동적 성질입니다. JavaScript와 함꼐라면 딱딱한 유형의 시스템으로 부터 구애받지 않을 수 있습니다; 그 대신에, 객체를 역동적으로 만들 수 있습니다. JavaScript 에디터와 통합개발툴(IDE) 개발자들의 도전 자세가 
C#또는 Java와 같은 강력한 유형의 언어와 같이 강력한 Refactoring 또는 IntelliSense한 안내 코드를 제공하여 사용할 수 있게합니다. 그러나 반대로 자바스크립트는 유형 정보의 뜻이 몇몇 개발자를 보조하는보통의 IDE에서 부족하게 제공되고있습니다.


Fortunately, things have improved recently, with Visual Studio 2010 performing pseudo-execution of your JavaScript code in order to determine the “shape” of each object, allowing it to provide JavaScript IntelliSense. In order to take full advantage of the IntelliSense support, we have to provide the IDE with a few “hints” in the form of “references” that tell the IDE which files to include in its pseudo-execution. With the demo project, all files start with a reference comment that tells the IDE to include the intellisense.js file. The content of this file is simply a list of references that ensure the IDE includes all the important application JavaScript files, providing quality IntelliSense support across the application, as shown here:
다행히도, 이런 것들은 비쥬얼 스튜디오 2010의 JavaScript IntelliSense 에서 제공된 각각의 JavaScript 객체의 "형"(Shape)을 측정하는 JavsScript 가상시현(pseudo-execution) 기능으로  현제 많이 개선되었습니다. IntelliSense의 모든 장점을 취하기 위해선 가상시현(pseudo-execution)을 위해 IDE 파일 내부에 몇가지 힌트를 참조양식(Form of "references")과  함께 제공해야했습니다. 시현(Demo) 프로젝트에는 모든 파일의 시작에 intelllisense.js파일을 포함하는 IDE 참조코멘트(Reference comment)가 있습니다. 다음에 보시는 크로스 응용프로그램을 지원하는 IntellliSense  파일의 내용은 IDE에서 포함한 중요한 응용프로그램 JavaScript파일들의 간단한 참조리스트입니다:



  1. /// Ensure IntelliSense includes all the files from this project.
  2. ///
  3. /// <reference path="app.js" />
  4. /// <reference path="viewModel/ApplicationViewModel.js" />
  5. /// <reference path="viewModel/SearchResultsViewModel.js" />
  6. /// <reference path="viewModel/TweetViewModel.js" />
  7. /// <reference path="viewModel/TwitterSearchViewModel.js" />
  8. /// <reference path="lib/jquery-1.6.4.js" />
  9. /// <reference path="lib/cordova-1.5.0.js" />
  10. /// <reference path="lib/knockout-1.2.1.js" />

JavaScript is a relaxed and forgiving language, with features such as value coercion and semi­colon insertion making it easy to use in a scripting environment. However, these same features often become problematic when managing large quantities of code. For that reason I highly recommend using JSLint, a tool that applies a more rigid set of coding standards to JavaScript. A popular Visual Studio Extension adds JSLint support (jslint4vs2010.codeplex.com), reporting lint errors within the error console. I’ve used JSLint for the Twitter Search application (and virtually every other JavaScript project I’ve worked on).
JavaScript는 느슨하고 관용적인 언어이지만, 스크립팅 환경에서 값의 강제성과 세미콜론(;)을 쉽게 삽입하는 특징을 이루고 있습니다. 그러나 이 것과 같은 특징들은 큰 규모의 코드를 관리하는데 있어 자주 문제시 되어지는 부분입니다. 그런 이유에서 저는 
툴에 더욱 완고한 표준 JavaScript 코딩을 설정 적용하고 싶다면, 강하게 JSLint를 사용할 것을 권하고 싶습니다. 대부분의 Visual Studio Extension 에는 JSLint 지원(jslint4vs2010.codeplex.com)하여 lint 오류를 오류콘솔을 통해서 통보하고 있습니다. 저는 트위터 검색 응용프로그램에 JSLint를 사용하였습니다(그리고 가상적으로 모든 JavaScript 프로젝트에 사용하고 있습니다).


You might notice a “globals” comment at the start of each JavaScript file within the project. JSLint helps prevent variables “leaking” into global scope by accidental omission of the var keyword. The “globals” comment provides JSLint with a formal definition of which variables are allowed to occupy a global scope.
당신은 프로젝트의 JavaScript파일에 "global"이라는 코멘트를 주의하셔야 할 것입니다. JSLint는 우발적인 키워드 생략으로 인한 전역적으로 발생하는 일명 "누수"현상을 막아줍니다. "global" 코멘트는 선점적으로 정의하여 제공하고 있습니다.


Model-View-View Model(MVVM) 응용프로그램 구조

The Twitter Search application is, from the perspective of the phone’s browser control, a single-page application. Conversely, from the user perspective, it has multiple pages, as seen in Figure 5. In order to support this, a Knockout ViewModel is constructed that contains a stack of ViewModel instances, each one representing a page within the application. As the user navigates to a new page, the corresponding ViewModel is added to this stack, and when the user navigates back, the topmost ViewModel is popped off the stack (see Figure 6).
트위터 검색 응용프로그램은 폰(phone)의 브라우저 컨트롤러로 보는 단일 
페이지 응용프로그램입니다. 반대로 사용자 시점에서 보면 Figure 5에서 보듯 다중 페이지로 보입니다. 응용프로그램간 페이지를 각각 대표하는 ViewModel 객체들의 더미(stack)을 포함하도록 지원하는 Knockout ViewModel이 구성되어졌습니다. 사용자에게 새로운 페이지를 안내하게 된다면 이에 상응하는 ViewModel을 ViewModel객체들의-더미(stack)에 추가하고 사용자에게 안내를 돌려주게 되고 가장 상위의 ViewModel은 ViewModel객체 더미에서 튀어나오게 됩니다(참조 Figure 6).


Figure 6 The Knockout ApplicationViewModel

  1. /// <reference path="..//intellisense.js" />
  2. /*globals ko*/
  3. function ApplicationViewModel() {
  4.   /// <summary>
  5.   /// The ViewModel that manages the ViewModel back-stack.
  6.   /// </summary>
  7.   // --- properties
  8.   this.viewModelBackStack = ko.observableArray();
  9.   // --- functions
  10.   this.navigateTo = function (viewModel) {
  11.     this.viewModelBackStack.push(viewModel);
  12.   };
  13.   this.back = function () {
  14.     this.viewModelBackStack.pop();
  15.   };
  16.   this.templateSelector = function (viewModel) {
  17.     return viewModel.template;
  18.   }
  19. }


When the application starts, an instance of the ApplicationViewModel is created and bound to the UI using Knockout:
응용프로그램이 시작되면 응용프로그램의 ViewModel의 객체가 생성 및 Knockout을 이용한 UI로 묶여지게 됩니다:


  1. document.addEventListener("deviceready", initializeViewModel, false);
  2. var application;
  3. function initializeViewModel() {
  4.   application = new ApplicationViewModel();
  5.   ko.applyBindings(application);
  6. }



The UI itself is quite simple, comprising a div element that uses the Knockout template binding to render the ViewModel stack:
div 엘레멘트를 포함한 Knockout 템플릿의 묶음과 
ViewModel 더미를 표현하는 UI 자체는 굉장히 단순합니다:



  1. <body>
  2.   <h1>Cordova Twitter Search</h1>
  3.   <div class="app" data-bind ="template: {name: templateSelector, foreach: viewModelBackStack}">
  4.   </div>
  5. </body>


The Knockout template binding works in a similar manner to the Silverlight ItemsControl in that it binds to an array of ViewModel instances and is responsible for generating the View for each via a template. In this case, the templateSelector function is invoked on the ApplicationViewModel in order to determine the named template for each ViewModel.
Knockout 템플릿 바인딩은 
SilverLight ItemControl의 템플릿을 통한 각각의 VIew를 생성하는 역활과 ViewModel 객체의 배열로 묶어주는 방식과 비슷하게 동작합니다. 이 경우에 각각의 ViewModel의 이름을 지정하기 위한 ApplicationViewModel을 templateSelector  가 호출하게됩니다.


If you run this application you’ll find that it doesn’t actually do anything—that’s because there aren’t any ViewModels to represent the pages of the application!
이응용프로그램을 실행하면 막상 아무 것도 하고 있지 않을 것을 발견할 것입니다. 왜냐하면 응용프로그램을 대표하는 페이지지 즉 ViewModel들이 어디에도 없기 때문입니다!


트위터 검색 뷰 모델(The TwitterSearchViewModel)

I’ll introduce the first ViewModel, TwitterSearchViewModel, which represents the first page of the application. This ViewModel exposes a few simple observable properties that support the UI, namely the searchTerm, which is bound to the user input field, and isSearching, which is a Boolean observable that disables the search button when the Twitter APIs are being queried via HTTP. It also exposes a search function that’s bound to the search button, in much the same way that you would bind an ICommand to a Button within Silverlight (see Figure 7).
제가 응용프로그램을 대표하는 첫 페이지 첫 ViewModel인 TwitterSearchViewModel을 소개하겠습니다. 이 ViewModel은 몇 가지 간단한 관찰가능한 UI요소들인 사용자 입력 필드(field)인 searchTerm과 Twitter API로 
HTTP를 통하여 질의할 때 조회 버튼이 사용불가능 하도록하는 Boolean 관찰자인 isSearching으로 나타내보여집니다. Silverlight에서 ICommand버튼에 바인드 하듯이, 이 것 역시 조회 기능을 조회버튼에 바인드 할 수 있습니다(참조 Figure 7).


Figure 7 The TwitterSearchViewModel

  1. /// <reference path="..//intellisense.js" />
  2. /*globals $ application ko localStorage SearchResultsViewModel TweetViewModel*/
  3. function TwitterSearchViewModel() {
  4.   /// <summary>
  5.   /// A ViewModel for searching Twitter for a given term.
  6.   /// </summary>
  7.   // --- properties
  8.   this.template = "twitterSearchView";
  9.   this.isSearching = ko.observable(false);
  10.   this.searchTerm = ko.observable("");
  11.   // --- public functions
  12.   this.search = function () {
  13.     /// <summary>
  14.     /// Searches Twitter for the current search term.
  15.     /// </summary>
  16.     // implementation detailed later in this article ...
  17.   };
  18. }


The template property of the ViewModel names the View that’s associated with this ViewModel. This View is described as a jQuery template within the index.html file:
ViewModel 템플릿 요소인 View를 ViewModel의 조합으로 이름하였습니다. 이 VIew는 index.html파일에 jQuery템블릿으로 기술되어진 것입니다:


  1. <script type=text/x-jquery-tmpl" charset="utf-8" id="twitterSearchView" 
  2.   <div>
  3.     <form data-bind="submit: search">
  4.       <input type="text"
  5.         data-bind="value: searchTerm, valueUpdate: 'afterkeydown'" />
  6.       <button type="submit"
  7.         data-bind="enable: searchTerm().length > 0 &&
  8.           isSearching() == false">Go</button> 
  9.     </form>     
  10.   </div>
  11. </script>



If you add an instance of the TwitterSearchViewModel to the application ViewModel stack, the application now shows the first page, as shown in Figure 8.
만약 TwitterSearchViewModel의 객체를 응용프로그램 ViewModel 더미(stack)에 추가했다면 Figure 8에서 보듯이 으용프로그램은 첫페이지를 보여주게 됩니다.



The TwitterSearchViewModel Rendered via the twitterSearchView Template
Figure 8 twitterSearchView템플릿을 통한 TwitterSearchViewModel 표현

Posted by gofly

댓글을 달아 주세요

Cordova Applications 개발하기

You can add your HTML, JavaScript and CSS files to the www folder and—as long as you mark them with a Build Action of Content—they’ll be included in your project and accessible via the browser control when your application executes. You can use any of the standard JavaScript/HTML5 libraries or frameworks in your Cordova application, as long as they’re compatible with the phone’s browser.
당신은 HTML, JavaScript그리고 CSS 파일을 www폴더에 추가 할 수 있고-어느정도 당신이 컨텐츠 표현을 위한 구현을 할 수 있게- 당신의 응용프로그램이 실행될 때 브라우저 콘트롤러를 통하여 접근할 수 있는 프로젝트에 포함되어야 할 것을 추가할 수 있습니다.


The Cordova APIs are documented on the Cordova Web site; I won’t describe them in detail here. One important thing to note is that you must wait for the deviceready event before making use of any of the other API methods. If you inspect the index.html file generated from the template, you can see that it waits until the device is ready before updating the UI:
Cordoba API는 Cordova Web site에 문서화되어 있습니다; 이 곳에서는 그 것들에 대해서 자세하게 다루지는 않겠습니다. 한가지 주의해야 할 중요한 점이 있다면 기계구동준비(Device Ready) 이벤트 전에 다른 API 메소드의 사용 할 수 있도록 기다려야 한다는 것입니다. 만약 당신이 템플릿으로 부터 생성된 index.html 파일을 검사해보면, 기계구동상태가 준비되기전에 UI(User Interface)를 수정(Updating)하는 것을 볼 수 있습니다:

  1. <script type="text/javascript">
  2.   document.addEventListener("deviceready",onDeviceReady,false);
  3.   function onDeviceReady()
  4.   {
  5.     document.getElementById("welcomeMsg").innerHTML
  6.       += "Cordova is ready! version=" + window.device.cordova;
  7.     console.log(
  8.       "onDeviceReady. You should see this " +
  9.         "message in Visual Studio's output window.");
  10.   }
  11. </script>


The console object used in the preceding code allows you to add debug output to your application. These messages are sent to the Visual Studio console by Cordova.
콘솔 오브젝트를 사용하여 디버그를 출력하는 선행 응용프로그램 코드입니다. 이 메세지들은 코르도바에 의해 비주얼 스튜디오 콘솔에 보내지게 됩니다. 


단일페에지 또는 다중 응용프로그램 아키텍쳐

When building Cordova applications, you can employ two distinct patterns:
Cordova 응용프로그램을 만들 때 당신은 크게 두 가지 패턴을 사용할 수 있습니다:

Multipage applications: In multipage applications, multiple HTML pages are used to represent the various screens of your application. Navigation between pages uses the standard browser mechanics, with links defined by anchor tags. Each HTML page includes script references to the Cordova JavaScript code and your application JavaScript.
다중페이지 응용프로그램: 다중페이지 응용프로그램 안에는, 당신의 응용프로그램이 대체적으로 여러 HTML 페이지들이 여러 스크린에 의하여 표현되어진다는 것을 뜻합니다. 페이지들을 안내(Navigation)하기 위해 사용되는 것은 기본 브라우저 메카닉과 앵커 태그에 의해 정의되어진 링크입니다. 각각의 HTML페이지는 Cordova JavaScript 코드 레퍼런스 또는 사용자 응용 JavaScript를 추가하고 있습니다. 

Single-page applications: In single-page applications, a single HTML file references Cordova and your application JavaScript. Navigation between the various pages of your application is achieved by dynamically updating the rendered HTML. From the perspective of the phone browser, the URL remains the same and there’s no navigation between pages.
The choice you make between these two patterns has a significant impact on the structure of your code.
단일페이지 응용프로그램: 단일 페이지 패턴의 응용프로그램은, 하나의 HTML 파일에 Cordova 또는 당신의 응용 JavaScript가 참조될 수 있습니다. 당신의 응용프로그램에서 여러 페이지들을 안내(Navigation)하기 위해서 HTML을 다이나믹하게 수정하여 그려내게(Rendered) 됩니다. 폰의 브라우저의 시점에서는 URL(Uniform Resource Locator)은 남아서 동일하고, 페이지 주소를 안내(Navigation)하진 않습니다.
이 두가지 패턴중에 한 가지를 선택하는 것은 코드의 구조에 중요한 영향을 미치게 됩니다.

Generally speaking, the multipage pattern is best suited to applications that mostly comprise static content. With this approach you can take HTML/CSS/JavaScript that’s currently used on your Web site and package it, using Cordova, for delivery to the phone as an application. But the multipage approach has some disadvantages. First, when the browser navigates from one page to the next, it has to reload and parse all the JavaScript associated with the new page. There’s a noticeable pause as the Cordova lifecycle, which creates the link between the JavaScript APIs and C# counterparts, is executed. Second, because your JavaScript code is being reloaded, all application state is lost.
일반적으로 말해서 다중페이지가 최고의 정적 컨텐츠 응용프로그램 패턴이라고 할 수 있습니다. 단일페이지 응용프로그램으로서 당신의 폰에 Cordova를 사용하여 전달한다는 접근은 현제 당신의 웹사이트나 패키지에서 사용되고 있는 HTML/CSS/JavaScript를 취할 수가 있다는 것입니다. 그러나 다중페이지 접근은 몇 가지 불리한 것이 있습니다. 첫 째, 브라우저로 하나의 페이지에서 다음으로 안내되어 질 때, 모든 것을 새로읽고 해독하고 JavaScript를 새로운 페이지에 조합하여야 한다는 것입니다. 여기 Cordova 생활주기에서는 중요한 실행 또는 정지되어 질 때 생성되는 JavaScript API와 C#의 응대(반응)하기위한 연결 상태값 등이 있습니다. 두 번째는 JavaScript코드가 있기 위해서 새로 읽어질 때 모든 응용프로그램 상태가 손실될다는 것입니다. 

The single-page pattern overcomes the issues associated with the multipage approach. The Cordova and application JavaScript code is loaded just once, resulting in a more responsive UI and removing the need to pass application state from one page to the next. The only disadvantage to this approach is the added complexity, with JavaScript code being required to update the UI when navigation occurs.
단일 페이지 응용프로그램 패턴은 다중 페이지 응용프로그램 접근과 같이 대두된 이슈를 극복하였습니다. Cordova와 JavaScript 응용프로그램 코드는 딱 한 번만 읽혀지고, 많은 UI(사용자 인터페이스)의 반응 값과 한 페이지가 소멸되고 남은 응용프로그램 상태 값을 다음 지우는 것입니다(Remving the need to pass application state from one page to the next). 이런 접근에 있어서 유일하게 불리한 점은 페이지들 간에 안내(Navigation)가 되고 있을 때 JavaScript코드로 UI의 상태 또는 모양을 업데이트하게 될 때 복잡해 진다는 것입니다.

The demo application described in this article uses the single-page pattern. For an example of the multipage approach in action, I recommend looking at the DemoGAP CodePlex project (demogap.codeplex.com), which provides a simple demonstration of the Cordova API features within a Windows Phone application.
현제 제공되는 데모 응용프로그램은 싱글 페이지 패턴의 문서를 가지고 기술 된 것입니다. 윈도우 폰 응용프로그램으로 제공된 간단한 Cordova API 데모 중 다중 페이지 접근의 예문을 활용하시려면 저는 DemoGap Complex Project(demogap.complex.com)을 보라고 추천하고 싶습니다. 

데모 응용프로그램

The rest of this article describes “Cordova Twitter Search,” a simple Windows Phone application that allows the user to search Twitter based on one or more keywords, as shown in Figure 5.
다음 기술된 "Cordova Twitter Search:Cordova 트위터 검색" 글은 Figure 5에서 보시듯 아주 간단하게 한 개 이상의 키워드로 트위터를 검색하는 윈도우 폰 응용프로그램을 보여주고 있습니다. 


As well as Cordova, this application makes use of the following frameworks:
다음은 코르도바 응용프로그램의 프레임웍입니다.
  • jQuery and jQuery Templates: jQuery has become the de facto standard framework for manipulation of the browser Document Object Model (DOM). jQuery templates are plug-ins that Microsoft developed (bit.ly/8ZO2V1), making it easy to create reusable HTML templates that can be rendered to the DOM. Twitter Search uses jQuery templates to define the UI for the various pages within the application.
  • jQuery 와 jQuery 템플릿: jQuery는 브라우저의 DOM을 가공한 de facto 표준 프레임웍이 되었습니다. jQuery 템플릿은 DOM으로 그려낼 수 있는 HTML 템플릿이고, 창조적인 재사용이 가능하게 Microsoft developed( bit.ly/8ZO2V1)에서 프러그인으로 제공됩니다. 트위터 검색은 응용프로그램에 jQuery 템플릿 UI로 정의된 여러가지 페이지로 구성되어있습니다.


  • Knockout JS: Knockout is a Model-View-ViewModel (MVVM) framework that makes it easy to construct ViewModels and keep them synchronized with Views in a manner familiar to Silverlight developers. It’s this familiarity that led me to choose Knockout over the numerous other suitable JavaScript UI frameworks.
  • Knockout JS: Knockout은 아주 쉽게 뷰모델을 구성하고 지속적으로 동기화 해주는 Silverlight 개발자를 위한 매우 친숙한 Model-View-ViewModel(MVVM)프레임 웍입니다. 이런 친숙함이 다른 괜찮은 JavaScript UI 프레임웍보다 더욱 더 Knockout을 선택하게 이끌었습니다.

I won’t be covering Knockout in detail in this article. If you’re interested in learning more about this framework, I recommend reading John Papa’s recent article, “Getting Started with Knockout” (msdn.microsoft.com/magazine/hh781029). And if you aren’t familiar with the MVVM pattern (where have you been hiding?), I recommend this excellent article by Josh Smith: “WPF Apps with the Model-View-ViewModel Design Pattern” (msdn.microsoft.com/magazine/dd419663).
저는 Knockout을 자세하게 이 글에서 다루고 싶지 않습니다. 그러나 만약 프레임웍(Knockout)에 대하여 더 배우길 원하신다면, 저는 Jhon Papa의 최근 글인 "Getting Started With Knockout"(msdn.microsoft.com/magazine/hh781029)을 권하고 싶습니다. 그리고 만약 MVVM패턴이 익숙하지 않으시다면(뭘 숨기시려하십니까?-역자주: 부끄러워 말라는 거겠죠? 모를수도 있으니...), Josh Smith의 글 "WPF Apps with the Model-View-ViewModel Design Pattern"(msdn.microsoft.com/magazine/dd419663)을 권하고 싶습니다.


마치며...
너무나 오랜 만에 번역 작업을 한 것 같습니다. 역시나 허접하지만, "개떡같이 말해도 찰떡같이 알아들어라" 현명한(?) 우리의 선조들의 말을 빌어 그지같은 저에 오역글에 자비와 인애로 애쓴다하는 생각으로 글을 봐주시길 희망합니다.


아!!!! 아래 추천좀 눌러주심 감사하겠습니다...쿄쿄쿄
좋은 하루 되세요!!!!^^

Posted by gofly

댓글을 달아 주세요

최근에 객체지향프로그램인 JAVA의 초기 입문서인 Head First Java를 모두 읽었습니다. 그런데 읽으면서 아주 흥미로운 사실 하나를 읽게되었고 깨닫게 되었습니다. 바로 객체지향에 있어서 어떤 프로그램을 작성하는데 세포단위(즉 더 이상 쪼갤 수 없는 기능이 상실되지 안는 최소한의 단위)로 쪼개어 설계하고 기능을 만들어야 한다는 점 이었습니다.


물론 이런 식의 글은 누군가는 썼을 것입니다. 사실 고찰이라는 제목을 썼지만, 아주 개똥철학일 수 있습니다. 누군가에게 나의 대단함을 내보이려기 보다는 그냥 내 생각을 정리함으로 조금더 확실한 학습을 유도하려는 스스로에대한 글인 것입니다.


돌아 와서 세포단위로 쪼개어 설계하고 기능을 구현한다는 것은 다음을 예를 들어 설명하고 싶습니다.


세포단위 기능구현


예를들어 자바에서는 외부의 파일을 읽어 드리거나 외부 파일을 만들거나 파일에 내용을 기제할 때, InputStream 또는 OutputStream과 같은 객체를 다른 객체와 Chain하여 쓰고 있습니다. 왜 굳이 Stream과 특정 객체를 체인하여 사용할까요?? 그것은 Stream에서 하는일과 각 객체 File 또는 FileWriter에서 하는 일을 불리함으로서 File 또는 FileWriter가 아닌 다른 객체 또는 다른 일(예를 들어서 Stream형태로 외부의 컴퓨터와 통신을 하게 될 때)을 하게 될 때 쉽게 변경 또는 확장하는 것이 쉽기 때문입니다.


이와 같이 객체지향적으로 프로그램을 하려면 최소단위로 그 기능을 쪼개는 시도와 고민을 많이 해야 할듯 하다는 것이 결론입니다. 물론 이 과정에서 List와 ArrayList와 같은 관계가 생길 수도 있습니다. 즉, 인터페이스와 추상클래스와 같은 다형성의 활용이 필요하게 될 수도 있다는 것입니다. 그렇기 때문에 다형성(Polymorphism)을 알아야 하며, 중요하고 중점적으로 파고들어야 하는 핵심중의 핵심이라고 말하고 싶습니다(핵심이다보니 아주 어렵습니다. 하지만 꼭 잘이해를 해야만 하는 부분임은 확실합니다).


세포단위 기능구현에서 주의 할 점


프로그램을 작성하는데 있어서 세포단위로 생각한다는 것은 아주 중요하지만, 주의 할 점이 많다고 생각합니다.


1.세포로서의 생명력(?)이 있어야 합니다.

2.증식 또는 배양을 통하여 또 다른 종으로서 사용할 수 있게해야합니다.


위의 두 가지 규칙은 반드시 존재해야만 하는 기능이라고 필자 스스로는 생각합니다. 이유는 간단합니다. 하나하나 풀어보자면 필자가 "세포단위"라고 말할 때 "세포"라는 단어를 굳이 선택한 이유는 세포라는 것은 최소한이긴 하지만 생명력이 있다는 것을 말하고 싶어서 였습니다. 프로그램에서 생명력이란 하나의 움직임 즉 기능이라고 할 수 있습니다. 가장 기초가 되는 기능 그 것이 바로 "세포단위" 기능 구현인 것입니다.


예를들자면 자바에서 String은 하나의 클래스입니다. String클래스는 그 하위에 많은 메소드들을 가지고 있는데, 이 것이 String클래스를 정의하는 최소한의 기능들입니다. 이 기능들을 활용하거나 확장하여 다른 많은 작업들을 할 수 있습니다. 이 String 클래스에서 구현되어있는 최소한의 기능들은 분리되거나 한다면 그 생명력은 String클래스 하나만으로는 존재할 수 없는 즉 생명력이 없는(다른 클래스가 있어야 기능이 되거나 하는) 클래스가 될 것입니다. 물론 인터페이스나 추상클래스와 같은 것 들은 생명력이 없는 것 아니냐는 질문을 할 수 있지만 그러한 인터페이스나 추상클래스 조차도 어떤 객체에 사용되면 오버라이드가 되지 않는 한 확장 또는 구현(Implements)선언 만으로 구현 되는 기능들이 존재합니다. 차라리 생명력이 있는 하나의 클래스를 만들기 전에 인터페이스나 추상클래스같은 것들을 만들어서 파생적으로 세포로서 생명력이 있는 클래스를 만든다면 다형성의 좋은 예로서 활용될 것입니다.


마지막으로 "증식 또는 배양을 통하여 또 다른 종으로서 사용할 수 있게해야합니다."는 주의 사항은 내가 만든 클래스를 누군가 확장하거나 재사용이 가능 하도록 만들어야 한다는 것입니다. 바로 위에서 설명했듯이 인터페이스나 추상클래스와 같은 녀석들은 자체적으로 존재할 수 없습니다. Head First Java에서는 추상클래스를 다음과 같이 예를 들었습니다.


동물에는 개과 고양이과와 같은 식의 종의 분류들이 있습니다. 이 종의 분류는 실제하기는 하지만 종의 분류자체가 하나의 동물은 아닙니다. 이와 같이 추상 클래스는 다형성에서 상속과 관련하여 하나의 종의 분류와 같이 사용할 수는 있지만, 그것 자체로서는 하나의 객체가 될 수 없는 것이어야 한다고 말합니다.


인터페이스도 이와 비슷합니다. 다중상속을 허용하고 있지 않은 자바에서 다중상속과 비슷한 역활을 하는 것이 바로 이 인터페이스입니다. 인터페이스는 다음과같이 설명합니다. 상속관계와 무관하게 어떤 객체가 확장성을 위하여 가지고 있어야 하는 특성(또는 하는 일)이 필요할 때 인터페이스를 만들고 이를 구현합니다.


위에 밑줄 친 두 개의 예문은 좋은 예시가 되어 주리라 생각합니다. 어떤 객체를 만들기 앞서 그 객체들의 고통관심사나 공통분모를 찾아 내어서 하나의 추상클래스나 인터페이스화 하는 것 이것은 후에 내 클래스가 누군가에 의해서 확장되는 데에 많은 영향을 줄 것이라고 생각합니다.


마치며...


필자는 최근에 2개의 프로그램을 만들어 보았습니다. 하나는 TelegramSpliter(SVN 주소입니다. 받아서 확장하실 분은 메일 주시거나 댓글로 의사표현을 해주시면 함께 발전해 나갈 수 있었으면 하는 바램입니다)로 전문을 받아서 사용자가 입력해준 전문 길이로 전문을 나누고 사용자가 입력해준 클래스로 자동으로 Wrapping해주는 프로그램을 만들어 보았고, 또 하나는 전문을 가지고 오는 프로그램(각가지 방식-FTP, HTTP, SSH등-으로 통신하는)을 만들어 보았습니다. 이 때 Head First Java에서 배운 내용으 가지고 여러가지 활용을 해보면서 사용해 보았습니다. 앞으로 내공을 더 쌓아서 객체지향 프로그램에서 스프링이나 스트러츠를 만들었던 분들과 같이 되고 싶은 것이 내 바램입니다.

Posted by gofly

댓글을 달아 주세요

요즘 ORM으로는 하이버네이트, JPA등 많이 사용하고 있으나, 역시 SI 쪽은 mybatis(ibatis)를 많이 사용된다.

문제는 mybatis는 xml로 sql을 관리하고 있는데 보통 조금 바꿀때 마다 서버를 재구동 시켜야 되는 문제가 된다.

시스템이 클 경우 재시작시 오랜 시간 걸리고 session 사용시 또 로그인을 해야 하는듯 개발의 흐름이 끊어지는 문제가 많이 발생한다.

예전에 ibatis를 사용 했을시에도 그런 부분이 많이 불편했었는데, 예전 대우정보시스템의 JCF 프레임워크에서 사용된다고 Refresh 되는 클래스 소스가 한번 공개 된적이 있었다. ( 몇년전인지 기억은 안나지만, 당시 인터넷 검색으로 찾았었다. )

그것이 버전이 문제인지 바로 사용이 안되어서 커스터마이징하고 사용을 잘사용 했었다.

그런데 지금 프로젝트가 mybatis로 진행하기 때문에 예전과 같은 불편함이 또 생기게 되었는데, 이 번에는 그 소스를 mybatis에 맞도로 커스터마이징 하기로 했다.  

일단 사전 조건은 

JDK 1.5 이상, Spring, mybatis, spring-mybatis 라이브러리가 설치되어 있는 환경에서만 된다.


일단 기존 Spring 에서 mybatis 설정을 보겠다.

보통 sqlSessionFactory를 이렇게 설정 한다. 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:mapperLocations="classpath*:패키지경로/**/mapper.xml" p:configLocation="classpath:/MapperConfig.xml" p:dataSource-ref="dataSource"/>

classpath*:패키지경로/**/mapper.xml  <- 이부분이 재로딩될 xml 파일 경로

이부분에서 굵게 표시한 class 부분만 새로 만든 클래스로 바꾸면 모든게 해결된다.

<bean id="sqlSessionFactory" class="패키지경로.RefreshableSqlSessionFactoryBean" p:mapperLocations="classpath*:패키지경로/**/mapper.xml" p:configLocation="classpath:/MapperConfig.xml" p:dataSource-ref="dataSource" />

RefreshableSqlSessionFactoryBean.java

import java.io.IOException;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Timer;

import java.util.TimerTask;


import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.spring.SqlSessionFactoryBean;

import org.springframework.beans.factory.DisposableBean;

import org.springframework.core.io.Resource;


import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantReadWriteLock;


/**

 * mybatis mapper 자동 감지 후 자동으로 서버 재시작이 필요 없이 반영

 *

 * @author

 *

 */

public class RefreshableSqlSessionFactoryBean extends SqlSessionFactoryBean implements DisposableBean {


private static final Log log = LogFactory .getLog(RefreshableSqlSessionFactoryBean.class);


private SqlSessionFactory proxy;

private int interval = 500;


private Timer timer;

private TimerTask task;


private Resource[] mapperLocations;


/**

 * 파일 감시 쓰레드가 실행중인지 여부.

 */

private boolean running = false;


private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

private final Lock r = rwl.readLock();

private final Lock w = rwl.writeLock();


public void setMapperLocations(Resource[] mapperLocations) {

super.setMapperLocations(mapperLocations);

this.mapperLocations = mapperLocations;

}


public void setInterval(int interval) {

this.interval = interval;

}


/**

 *

 * @throws Exception

 */

public void refresh() throws Exception {

if (log.isInfoEnabled()) {

log.info("refreshing sqlMapClient.");

}

w.lock();

try {

super.afterPropertiesSet();


} finally {

w.unlock();

}

}


/**

 * 싱글톤 멤버로 SqlMapClient 원본 대신 프록시로 설정하도록 오버라이드.

 */

public void afterPropertiesSet() throws Exception {

super.afterPropertiesSet();


setRefreshable();

}


private void setRefreshable() {

proxy = (SqlSessionFactory) Proxy.newProxyInstance(

SqlSessionFactory.class.getClassLoader(),

new Class[] { SqlSessionFactory.class },

new InvocationHandler() {

public Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

// log.debug("method.getName() : " + method.getName());

return method.invoke(getParentObject(), args);

}

});


task = new TimerTask() {

private Map<Resource, Long> map = new HashMap<Resource, Long>();


public void run() {

if (isModified()) {

try {

refresh();

} catch (Exception e) {

log.error("caught exception", e);

}

}

}


private boolean isModified() {

boolean retVal = false;


if (mapperLocations != null) {

for (int i = 0; i < mapperLocations.length; i++) {

Resource mappingLocation = mapperLocations[i];

retVal |= findModifiedResource(mappingLocation);

}

}


return retVal;

}


private boolean findModifiedResource(Resource resource) {

boolean retVal = false;

List<String> modifiedResources = new ArrayList<String>();


try {

long modified = resource.lastModified();


if (map.containsKey(resource)) {

long lastModified = ((Long) map.get(resource))

.longValue();


if (lastModified != modified) {

map.put(resource, new Long(modified));

modifiedResources.add(resource.getDescription());

retVal = true;

}

} else {

map.put(resource, new Long(modified));

}

} catch (IOException e) {

log.error("caught exception", e);

}

if (retVal) {

if (log.isInfoEnabled()) {

log.info("modified files : " + modifiedResources);

}

}

return retVal;

}

};


timer = new Timer(true);

resetInterval();


}


private Object getParentObject() throws Exception {

r.lock();

try {

return super.getObject();


} finally {

r.unlock();

}

}


public SqlSessionFactory getObject() {

return this.proxy;

}


public Class<? extends SqlSessionFactory> getObjectType() {

return (this.proxy != null ? this.proxy.getClass()

: SqlSessionFactory.class);

}


public boolean isSingleton() {

return true;

}


public void setCheckInterval(int ms) {

interval = ms;


if (timer != null) {

resetInterval();

}

}


private void resetInterval() {

if (running) {

timer.cancel();

running = false;

}

if (interval > 0) {

timer.schedule(task, 0, interval);

running = true;

}

}


public void destroy() throws Exception {

timer.cancel();

}

}


만약에 재로딩 되는 시간을 바꾸고 싶으면 

<bean id="sqlSessionFactory" class="패키지경로.RefreshableSqlSessionFactoryBean" p:mapperLocations="classpath*:kr/web/**/mapper.xml" :configLocation="classpath:/MapperConfig.xml" p:dataSource-ref="dataSource" p:interval="1000" />

 p:interval="1000" 이부분을 수치를 정해주면된다. ( 디폴트는 500, 단위 ms )


이제 설정을 서버를 시작해서 위에 로케이션 해당하는 mapper.xml ( sql이 있는 xml , 설정에 따라 다름)에서

sql을 바꿔 보자 그리고 클라이언트에서 바뀐지 확인해보자

큰 문제가 없다면 반영될것이라고 생각된다. 


아 단 운영 시스템에 사용은 보장 못합니다~ 개발시에서만 사용하세요~


이 소스는 예전에 인터넷에서 나돌던 RefreshableSqlMapClientFactoryBean 소스를 커스터마이징한 소스인데 문제가 있다면 연락주시길바랍니다.



원문:http://sbcoba.tistory.com/entry/Spring-mybats-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%9E%AC%EC%8B%9C%EC%9E%91-%EC%97%86%EC%9D%B4-%EC%84%9C%EB%B2%84-%EB%B0%98%EC%98%81

Posted by gofly

댓글을 달아 주세요

하나의 IT인으로서 우리나라 IT가 고쳐졌으면하는 것이 있다면 바로 "빨리빨리"이다. 내가 본대로라면 외국의 IT는 "재대로"다 물론 프로젝트 기간이 있고, 그 기간 안에 맞추려 준비 단계를 철저희 가져 만약의 상황에 대비한 방법들이 개발단계에서 이미 준비되어 있다. 하지만 국내 IT는 상황이 다르다. 프로젝트 기간 중 잘못된걸 느끼거나, 더 좋은 대안을 가지고 의문을 품는 것은 프로젝트의 발목을 잡는 행위로 비춰져 잘못된것으로 간주된다. 그리고 내가 가진 의문과 대안은 출시 이후에 고칠 것을 생각한다(사실 고칠 순 없다. 왜냐하면 오픈 후에는 대부분 프리렌서라 계약이 종료되니 의문과 대안은 다른 사람이 하는 걸로 되어버리기 때문이다) 그러다 보니 유지보수 하는데 비용과 시간도 오래 걸린다. 후기자본이 많이 필요한 것이다.


반면 외국은 초기자본이 많이 든다(사실 우리나라도 많이 든다). 재대로 만들기 위해선 확실한 것을 내어 놓기 위해선 출시도 미룬다. 이러다 보니 유지보수 비용도 줄어들고 시간도 적게든다. 후기 자본이 덜들어간다. 이것은 제품이나 규격의 흥망에도 영향을 주는것 같다. 고칠 것 투성이인 국내 IT제품들은 빠른 주기로 새롭게 만든 제품을 내어 놓아 이전의 아우성을 잠재우나, 소비자는 실망한다. 왜냐하면 새롭게 만들다 보니 이전 기계 또는 제품 대한 호환성은 기대할 수 없기 때문이다.


허나 외국 제품들은 조금 상황이 다르다 . 출시까지 기간을 오래잡고, 초기에 분석을 철저희 한 탓에 이전 제품에대한 호환성과 새로운 기능에 대해서 소비자를 만족 시킨다.


하나의 예로 삼성 핸드폰은 갤럭시S에서 사용자를 대상으로 실험 했다는 평을 많이 들었다. 그래서 갤럭시 S2는 많은 보강을 하여 호평이 이따랐다.  이는 ICS(Ice Cream Sandwich)지원 여부에서 더욱 극명해졌으며 옴니아폰 이 후로 또 한 번의 테스트작품으로 갤럭시S는 전락했다. 그런데 갤럭시 S2 LTE버전 역시 판매를 목적으로 하는 시험작이라는 생각이 든다(당시 통신기술 3G, 4G를 지원하는 CPU는 퀄컴의 스냅드래곤 뿐인데-[현]Snap Dragon series S3-발열과 베터리 소모량이 LTE사용시 현명하게 극대화 된다. 갤럭시 S2 LTE, S2 HD LTE, Galaxy Note는 LTE버전으로 내어 놓기 위해서 만든 제품인데 CPU문제 인지 화면모드와 같은 일부 기능이 지원되지 않는다. 이 기능은 갤럭시 S2[3G버전]와 갤럭시 S3은 지원한다. 삼성의 엑시노드 CPU가 장착된 휴대폰에서만 지원된다). 그리고 ICS이전-진저브레드 이전 버전-에는 장애인에 대한 접근성을 지원하지 않는다. 또 TTS(Text To Speach)완성도도 애플의 SIRI의 음성 지윈에 비하면 8bit컴퓨터 수준이라 할 수 있다(이런 부분들을 비춰 봤을 때, 일단 만들고 보자는 식으로 만들었다는 생각외엔 들지 않는 부분이다).


반면 아이폰은 새로운 OS가 나와도 왠만한 과거 휴대폰이나 랩탑(Also Known As Notebook) 또는 PC를 지원한다. 아이폰의 경우 하드웨어로 연결잭은 아이폰 출시 이 후 변하지 않았고, 포트부분의 규격은 지금도 동일 하기 때문에 거의 모든 버전의 아이폰이다 호환이 가능하다(아이폰용 과거 또는 현제의 외부 제품들). 하나의 표준인 것이다(삼성의 경우 갤럭시S용 연결잭은 갤럭시 S2용 연결잭이 서로 호환하지 않을 수 있다. MHL 규격이 후에 정해지면서 S2에서부턴 표준 적용되었기 때문에 TV out과 같은 케이블은 갤럭시 S와 갤럭시 S2가 서로 상이 하다).


와이브로가 역사속으로 뭍혀간다. 그 것도 한참 후발 주자인 LTE에게 자리를 내어주고 말이다. 과연 빨리 만드는게 중요할까 재대로 만드는 것이 중요한가 다시 한 번 생각하게하는 기술의 흥망이다. 우리 나라 IT도 발전을 이루어 빨리보다는 재대로 만들자가 되어서 롱런(Long run)하는 기술, 제품들이 나왔으면하는 바램이다. 그 것이 IT강국으로 다시 한 번 도약하는 대한민국의 프로그래머가 되었으면 한다.

Posted by gofly

댓글을 달아 주세요

  1. Favicon of https://reviva.tistory.com BlogIcon reviva 2012.12.12 14:28 신고  댓글주소  수정/삭제  댓글쓰기

    같은 개발자로서 정말 공감이 많이되는 글입니다 .. 잘 읽고 갑니다

얼마전 아주 이상한일이 있었습다....

다름이 아닐 Dataset에 분명히 값을 집어넣고 Spring서버로 보냈는데....

처음에는 아무 이상없이 데이터가 넘어 가던 것이 왠일인지 두 번째 보내려고 할 때는 당최 값이 Dataset에 들어가지 않는 것이었습니다.

세팅할 때 문제가 있나 해서 세팅하는 값을 Alert으로 확인도 해보고, Dataset에 Row를 잘못 찾아넣어서 그러나 하고 여러가지 시도를 해봤는데 무슨수를 써도 값에는 이상이 없었습니다.


그래서 여기저기 또 찾고 찾다가....인터넷에서는 못찾고...^^;;; MiPlatform으로 개발을 오래 하신 분에게 여쭤봤습니다. 그래서 겨우 답을 찾을 수 있었습니다.


Logic


일단 MiPlatform과 Spring을 이용한 Logic은 다음 그림과 같습니다.



Miplatform과 Spring을 통한 기본 로직Miplatform과 Spring을 통한 기본 로직


그런데 문제는 저 로직을 한 번 거치고 나면 두 번째는 Dataset에 특정 컬럼에 데이터를 입력하려고 Spring서버로 보내면 Dataset에 넣었던 데이터는 Null 값으로 넘어 오는 문제였습니다....



문제점이 생기는 부분....문제점이 생기는 부분....


윗 부분이 바로 문제가 있는 부분이죠....빨간글씨...... 아무리 데이터를 넣어도 Spring서버에는 Null로 넘어 옵니다...쿼리에 조회값을 넣어서 넘긴건데 당최 쿼리는 Null이 들어가서 돌더군요;;;;;;


문제해결


알고 봤더 제가 사용하던 쿼리에 문제가 있었습니다.....;;;;

제가 보내는 Dataset과 다시 return받는 Dataset을 동일 한 것으로 해 놨는데 리턴 할 때 쿼리의 컬럼이 하나만 선언되어있다보니 Return받을 때 Dataset에 있는 Column이 사라지는 문제가 있더군요....


예시를 하나 들자면 이렇습니다.


Dataset에는 컬럼이 두개 있습니다. A, B이죠....


Dataset 예제Dataset 예제


이 중 저는 B에 데이터를 넣고 보냈습니다. 그리고 퀄리를 실행할 때에는 Dataset에 B컬럼의 데이터를 조회값으로 넣고 실행하게 됩니다.



만든 Dataset에 조회조건 넣기만든 Dataset에 조회조건 넣기


이렇게 데이터를 넣고 Spring에 보내게 되면 "조회조건"값으로 쿼리를 실행하게 됩니다.



조회조건으로 쿼리를 실행합니다.조회조건으로 쿼리를 실행합니다.


이렇게 말이죠..... 그런데 여기서 문제가 있었습니다. 조회해 오는 컬럼을 하나만 선언하고 나니 Return받게 되는 Dataset은 A라는 컬럼 하나만 남게 되는 것입니다.



Return받은 이후 변경된 Dataset의 모습(예)Return받은 이후 변경된 Dataset의 모습(예)


이렇게 말이죠.....그러다 보니 한 번 조회후에 다시 B 컬럼에 "조회조건"을 아무리 집어넣고 Spring서버에 보내도 B컬럼으로 넘어 오는 값을 Null로 와서 조회 조건이 Null....이라는 값으로 조회를 하게 되는 것이었습니다.



같은 조건으로 B컬럼에 '조회조건'을 넣어도 Spring에서는 아무값이 없는 상태로 넘어온다.같은 조건으로 B컬럼에 '조회조건'을 넣어도 Spring에서는 아무값이 없는 상태로 넘어온다.


그래서 쿼리를 바꿨습니다......




이렇게 말이죠.....Spring에서는 iBatis(MyBatis 개명 전 버전임)를 쓰고 있어서 조회조건으로 넘겨주는걸 조회절에 하나 더 넣어서 컬럼 B로 선언해 주었습니다. 그랬더니 두 번째 Dataset을 활용할 때 값이 제대로 Setting되고 조회조건도 잘 넘어 가는 것을 확인했습니다.


저는 자동으로 컬럼을 유지해 주는줄 알았는데 Miplatform으로 오래 작업하신 분의 설명은 아니더군요....

개발환경에서 Dataset 컬럼을 선언해두는 건 단지 편의를 위해서 만들어 둔다는 것이었습니다. 리턴 받으면 리턴받은 컬럼대로 Dataset의 컬럼은 변한다고 하더군요....


마무리..


아주 이것 때문에 엄청헤메였습니다. 하지만 해결을 하고 나니 어의가 없더군요....보강이 필요한 부분인 것같습니다...^^




Posted by gofly

댓글을 달아 주세요

  1. 2012.07.03 17:56  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://belong2jesus.tistory.com BlogIcon gofly 2012.07.04 10:49 신고  댓글주소  수정/삭제

      ^^ ;;;;; 이거 어쩌죠......저도 여기서 개발을 하고 있는 입장이라 여기 플랫폼은 이쪽 직원분들이 만들어 놓은거라 자료를 구하기가 힘드네요;;;;;;

      다만 자료를 POST형태로 파라미터로 보내고, 받을 때는 POST형태로 XML로 받아서 화면에 뿌려주더군요.....

      원래는 데이터셋을 주고 받는게 더 간편한게 있다고하던데 Dataset와 DB Column을 맞춰주면 자동으로 Generate해서 셀렉트 인서트같은 것들이 생성되는....그런데 아쉽게도 이번 프로젝트에서는 그렇게 구현은 안되어있네요....


      저도 Miplatform으로 개발하는건 이번이 처음이구요....;;;;;;

      그래도 Tip을 들이자면 Tobesoft에서 제공하는 Java용 API를 잘 살펴보시고 Miplatform과 통신하는 부분만 잘 만드시면 뒷단 Spring단은 기존에 Controller와 Service구현으로 generalDao(iBatis)구현해서 사용하는건 똑같습니다.

      Miplatform과 통신은 확실히 논리적 URL인 http://host/path/aaa.do 뭐 이런식으로 POST형태로 데이터를 주고 받더라구요 제가 하고 있는 framework에서는요.....

      큰도움을 못들여서 죄송합니다.....;;;; 정보누설을 두려워하기보다....핵심부분들을 Jar로해서 바이너리 파일을 배포해 놓은거라(iBatis도 막 바꿔놨더군요...)........보셔도 큰 도움은 못될 것 같아서 알려드리지 못하는 것이지 이해해 주세요;;;;

  2. 2012.07.04 11:05  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://belong2jesus.tistory.com BlogIcon gofly 2012.07.04 13:54 신고  댓글주소  수정/삭제

      큰도움 못드려 죄송하네요....^^;;;;
      기술자로서 개발자로서 그럴 때 얼마나 절실한지 아니까요.... 자주 오세요 또 제게 알려주실거 있음 알려주세요....저도 부족한터라...허허허..^^ 그럼 좋은 하루 되세요....

얼마전 파란이 진짜 없어 진다는 인터넷뉴스를 봤는데....

파란닷컴의 개발자블로그가 있는지는 몰랐네요.....


http://dev.paran.com/


뭐 역사속에서는 잊혀지지만 기억속에는 남아있겠죠....

좋은 정보가 몇 있는 것 같아 글남겨 봅니다.....

Posted by gofly

댓글을 달아 주세요

제목특집3부_리팩토링을 이용한 자바 성능 최적화 기법
작성일자2006.12.27출처마이크로소프트 [2006년 12월호]

리팩토링을 이용한 자바 성능 최적화 기법

 

허광남 | GS홈쇼핑 EC정보팀 과장

 

리팩토링, 복잡다단해지는 현대의 소프트웨어 개발에서 이 단어는 점점 중요한 위치를 차지해 가고 있다. 이제 리팩토링은 진정한 개발자의 덕목 중에 하나라고 단언할 수 있을 정도다. 리팩토링을 한다는 것은 개선에 대한 의지가 있음을 뜻하고, 좀 더 나은 코드, 구조, 프로세스를 지향한다는 의미가 된다. 리팩토링으로 소프트웨어의 성능을 직접적으로 높이지는 못 한다. 하지만 코드의 가독성을 증대시켜, 생각하는 프로그래머들의 머릿속 성능을 높여준다. 3부에서는 리팩토링 방법들에 대해 알아본다.

 

햄버거나 커피 등을 살 때, 또는 백화점이나 편의점에서 물건을 살 때, 우리는 1회용 물건을 쓰는 것에 대한 세금을 낸다. 1회용 물건을 쓰면 환경이 그만큼 빨리 피폐해지기 때문이란다. 그게 사실인지 아닌지 모르겠지만, 내 돈이 나가는 것은 용납이 안 된다. 1회용품의 편리함. 그 반대급부로 만들어지는 쓰레기 처리에 따른 비용을 지불한다고 하는데, 영 맘에 안 든다.

혹시 프로그램을 짤 때도 1회용 프로그램을 짠다는 생각을 해본 적이 있는가? 그런데 우리는 1회용 프로그램을 짜도 세금을 내지 않는다. 다행일까? 1회용 프로그램이 환경 자원을 소모시키지는 않는다. 다만 1회용 프로그램은 쓰레기를 양산한다. 그때 그때 필요한대로 찍어낸 프로그램은 수많은 중복코드를 양산해낸다. 재활용하지 않는 습관 탓에 시스템이라는 환경이 무거워지고 손이 많이 가도록 바뀌는 것이다.

재활용성은 객체지향 프로그램의 핵심원리 중의 하나이다. 재활용성을 높인다는 것은 찍어낼 때 사용하는 템플릿을 얘기하는 것이 아니다. 오히려 업무나 기능을 제어 가능한 곳에 집약시켜서 관리할 수 있도록 시스템 전체의 청결한 상태를 유지하는 것이다. 이리저리 산재된 중복 코드를 정리하는 것이 핵심이다. 이 때 필요한 기술이 리팩토링이다. 이쯤 얘기하면 리팩토링은 정리 정돈에 비견된다. 군대에서 총기수입을 하는 것과도 같고 집에서 설거지를 하는 것과도 같다.

 

리팩토링이란



Refactoring (Re + Factor + ing) 영어 단어를 요소별로 나눠보면 요소들을 재구성한다는 뉘앙스를 받을 수 있다. 이는 마틴 파울러의 책에서 비롯된 단어인데, 책에 있는 리팩토링의 정의를 보면 다음과 같다.

“리팩토링은 외부 동작을 바꾸지 않으면서 내부 구조를 개선하는 방법으로, 소프트웨어 시스템을 변경하는 프로세스이다.” 마틴 파울러, 리팩토링, P10. 대청출판사 책에 이어서 나오는 내용은 버그가 끼어들지 않도록 주의하면서 코드를 작성한 후에 더 나은 디자인으로 개선하는 방법이라고 한다. 디자인을 먼저 한 후 코드를 만드는 것이 아니라 일단 돌아가는 코드를 작성하고, 그 후에 그 코드가 더 좋은 구성을 갖도록 바꾼다는 것이다. 우리들의 코딩 관행을 돌아보면, 일단 돌아가는 프로그램을 짠다. 그리고? 끝이다. 그 다음으로 넘어간다. 정리? 남은 사람이 알아서 할 것이다. 남은 사람이 자기 밖에 없다면? 날 잡아서 정리하거나, 회사 옮긴다.

 

 

리팩토링을 하는 이유



야심찬 초급 개발자가 자주하는 것 중에 하나가 이전 소스에 대한 비평이다. “도대체 어떻게 이렇게 소스를 짤 수 있지. 발로 짜도 이것보다는 낫겠네. 왜 이렇게 if else가 많은 거야. 이 소스 이해할 시간 있으면 차라리 다시 짜고 만다.” 그래서, 다시 짠다. 그리고 오픈하면 이것 저것 버그 리포트와 요구사항이 들어온다. 이것 저것 예외 처리를 해주다 보면 내가 짠 코드지만 보기 싫어진다. 어느 정도 서비스가 안정적으로 돌아가도록 소스를 수정해 놓으니, 이런, 전에 내가 막 뭐라고 했던 이전 개발자의 소스와 별반 차이가 없다.

“제길, 다음 후임이 누가 될지는 몰라도 내 욕 무진장 하겠군.” 문서라도 잘 주면 모르겠지만, 처음 개발할 때 보고했던 문서 그대로다. 요구사항과 수정을 통해서 변경된 내용을 문서에 업데이트하질 못했다. “할 시간이 있어야지.” SM(System Maint enance)분야에서는 거의 이렇게 사는 것이 보통이다.

이전 사람이 만든 소스에서 버릴 것은 거의 없다. 정리가 안 되서 몇 달간 목욕 못한 모습일 뿐이지, 처리할 수 있는 모든 경우의 수는 그 안에 다 가지고 있다. 이런 코드를 새로 짠다는 것은 그 모든 경우의 수를 처음부터 다시 감수하겠다는 의미가 된다.
이전 소스를 씻기고 다듬는 것이 소스 수정을 위한 필수 과정이다. 정리하지 않고 계속해서 소스를 추가해 가는 일은 운동하지 않고 계속해서 먹어대는 것과 같이 시스템을 비만상태로 만들어간다. 움직임이 점차 둔해질 것이다. 정리 안 된 방처럼 발 디딜 팀이 없는 소스가 될 것이다.

무엇인가 소스의 변경이 필요할 때, 기능 추가나 삭제, 수정 작업이 일어날 때 소스의 리팩토링은 포장이사처럼 편하게 작업하도록 도와준다. 리팩토링은 소스의 중복된 부분을 모듈화 시켜준다. 모듈화는 입출력이 명확하기 때문에 이식성을 높여준다. 중복을 제거한다는 것은 시스템의 칼로리를 빼는 것과 같다. 시스템의 복잡도, 즉 코드를 읽는 사람의 머리가 열받는 정도를 낮춰준다. 물론 그렇다 해도 이사 자체는 귀찮은 일이다.

 

 

 

리팩토링을 위한 도구



리팩토링은 그로 인해 영향 받는 프로그램의 수가 적을 대에만 수작업으로 작업해야 한다. 사실 리팩토링을 수작업으로 한다는 것은 추천하지 않는다. 좋은 개발 환경이 있는데 사서 고생할 필요가 없는 탓이다. 리팩토링을 위한 좋은 툴이 많이 나왔다. 일단 통합개발환경(IDE, Integrated Development Environment)을 준비한다. 요즘의 자바 개발 시 많이 사용되는 IDE는 기본적으로 리팩토링을 지원한다.

리팩토링과 함께 진행되어야 할 JUnit 테스트케이스 자동 생성도 같이 지원되고 있다. 리팩토링 작업을 할 경우 여러 줄의 코드들이 수정된다. 이때 영향을 받는 프로그램들을 모두 불러내서 수작업으로 수정할 경우 리팩토링에 대한 공수가 많이 필요한 탓에 감히 리팩토링에 대한 엄두를 낼 수 없다. 하지만 요즘 통합 개발 환경을 지원하는 개발 도구들은 변경 받는 파일들의 목록과 변경 전 후의 코드 비교, 자동 변경 기능을 지원한다. 덕분에 리팩토링에 드는 수고가 전혀 수고로 생각되지 않을 정도다.

 

 

 

리팩토링 진행 방법



리팩토링하는 이유와 리팩토링 도구까지 알아보았으니 이제 리팩토링 방법에 대해 알아볼 차례다. 주저리 주저리 방법들을 늘어놓을 수 도 있겠지만 개발자는 코드로 얘기한다. 바로 이클립스에서 리팩토링을 사용하는 방법을 설명하도록 하자.

 

<리스트 1> 리팩토링 샘플
1 public void deleteArticle(Connection conn, int seq) throws SQLException {
2 if (conn == null)
3 return;
4
5 // db에서 삭제 - 삭제 테이블로 이동
6 PreparedStatement pstmt = null;
7 pstmt = conn.prepareStatement(QUERY_MOVE);
8 pstmt.setInt(1, seq);
9 pstmt.executeUpdate();
10
11 pstmt.close();
12
13 pstmt = conn.prepareStatement(QUERY_DELETE);
14 pstmt.setInt(1, seq);
15 pstmt.executeUpdate();
16
17 pstmt.close();
18
19 // memo 삭제 생략
20
21 }


리팩토링에 대한 간단한 예를 들기 위해서 <리스트 1>을 보며 설명하겠다. 7~11번 줄의 코드가 13~17번 줄의 코드와 유사한 것을 알 수 있다. 중복이 계속되는 것은 일정한 패턴을 갖고 있는데 중복이 심해지면 패턴 변경에 따른 공수가 많이 필요하므로 소스의 유연성이 떨어지게 된다. 때문에 반복되는 패턴을 메소드화 시켜서 쉽게 코드를 읽을 수 있도록 한다. 



<화면 1> 반복되는 부분, 메소드 추출의 대상

   

<화면 2> 메소드 추출(Extract Method)

이클립스에서 패턴부분을 선택하고, 오른쪽 버튼을 눌러 콘텍스트 메뉴를 열면 중간 위치에 [Refactor…]라는 메뉴가 보인다. 확장 메뉴에서 [Extract Method…]를 선택하면 <화면 2>와 같은 다이얼로그 창이 뜬다. ‘doQuery’라고 메소드명을 입력한 뒤에 파라미터들을 확인한다.

화면 아래쪽의 버튼 중 [Preview]를 클릭하면 <화면 3>과 같이 미리보기 창으로 바뀐다. 이때 화면에 표시되는 정보들이 기가 막힌다. 리팩토링을 통해서 변경되는 소스의 비교와 상단에는 이 리팩토링에 영향을 받는 소스들과 메소드명까지 친절하게 알려준다. 게다가 이클립스가 모두 다 자동으로 바꿔준다.


 


<화면 3> 리팩토링 결과 미리보기


<화면 4>에서는 다이얼로그에서 만든 doQuery() 메소드의 내용을 볼 수 있다. 소스 비교란의 맨 오른쪽에 있는 네모는 소스 전체에서 변경이 일어난 부분을 표시한 것이다.


 


<화면 4> 리팩토링으로만들어진 메소드

비교가 끝났다면 [OK] 버튼을 클릭해서 리팩토링을 실행한다. 소스 리팩토링을 마친 뒤에 doQuery() 메소드를 보면, <화면 5>처럼 파라미터가 Connection conn, int seq 두 개임을 알 수 있는데, 여기에 하나가 더 필요하다. 바로 쿼리 부분인데, 이것을 파라미터로 받아야 비로로 doQuery()가 공용으로 쓰일 수 있게 된다.


<화면 5> 리팩토링으로 만들어진 약간 아쉬운 메소드

QUERY_MOVE라는 상수를 파라미터로 대치한다. 이 상수에 마우스 오른쪽 버튼을 클릭한 뒤에 [Refactor]-[Introduce Para meter] 메뉴를 실행시키면 <화면 6>과 같은 다이얼로그 창을 볼 수 있다. 새로운 파라미터 이름을 ‘query’로 정하고 우측의 [up] 버튼을 클릭해서 파라미터의 위치를 조정한다. 파라미터의 변경은 메소드의 모습인 시그니처(signature)를 변경하는 것이다.



마찬가지로 [Preview] 버튼을 클릭하면 <화면 7>과 같이 리팩토링 전후의 소스를 비교할 수 있다.

<그림 7>에서 [OK] 버튼을 클릭해서 만들어진 doQuery() 메소드는 반복되는 쿼리 실행 부분을 메소드 추출(Extract Met hod)과 파라미터로 빼기(Introduce Parameter) 리팩토링을 이용해서 만든 것이다. <리스트 2>는 그것을 이용해서 바뀐 소스의 모습이다. 



<그림 7> 파라미터로 만들기 적용하기 전 미리보기

 

<리스트 2> QUERY_DELETE 부분 리팩토링 과정
1 public void deleteArticle(Connection conn, int seq) throws SQLException {
2 if (conn == null)
3 return;
4
5 // db에서 삭제 - 삭제 테이블로 이동
6 PreparedStatement pstmt;
7 doQuery(conn, QUERY_MOVE, seq);
8 doQuery(conn, QUERY_DELETE, seq);
9
10 pstmt = conn.prepareStatement(QUERY_DELETE);
11 pstmt.setInt(1, seq);
12 pstmt.executeUpdate();
13
14 pstmt.close();
15
16 // memo 삭제 생략
17
18 }

19 private void doQuery(Connection conn, String query, int seq) throws SQLException {
20 PreparedStatement pstmt = null;
21 pstmt = conn.prepareStatement(query);
22 pstmt.setInt(1, seq);
23 pstmt.executeUpdate();
24
25 pstmt.close();
26 }


<리스트 2>는 아직 변경 중인 샘플코드이다. 앞서 만든 doQuery() 메소드를 이용해서 쿼리만 다른 것을 보내면 된다. 필자가 추가한 8번 줄은 10~14번 줄과 동일한 기능을 수행하게 된다. 코드를 정리하면 다음과 같이 된다.

 

<리스트 3> QUERY_DELETE 부분 리팩토링 후
1 public void deleteArticle(Connection conn, int seq) throws SQLException {
2 if (conn == null)
3 return;
4
5 // db에서 삭제 - 삭제 테이블로 이동
6 doQuery(conn, QUERY_MOVE, seq);
7 doQuery(conn, QUERY_DELETE, seq);
8 // memo 삭제 생략
9
10 }


하단의 구문이 지워지면서 이 deleteArticle() 메소드 내의 PreparedStatement pstmt 선언은 불필요하기 때문에 삭제했다. 처음 보았던 소스에서 많이 정리되었다. 정리를 하고 보니 deleteArticle() 메소드를 호출하는 곳에서 비슷한 기능을 하는 부분을 볼 수 있다.

 

<리스트 4> 리팩토링 적용 범위 확대
1 // password 확인
2 if (confirmPassword.equals(MASTER_PASSWORD)
3 || confirmPassword.equals(article.getPassword())) {
4 deleteArticle(conn, seq);
5 deleteFiles(conn, seq);
6 } else {
7 resourceName = "/jsp/error.jsp";
8 throw new Exception(CommonUtil.k2a("잘못된 비밀번호"))
9 }

10 public void deleteFiles(Connection conn, int seq) throws SQLException {
11 if (seq == 0){
12 return;
13 }
14
15 // file db에서 삭제 - sts 값 0 로 변경
16 PreparedStatement pstmt = conn.prepareStat ement(QUERY_DEL_SEQ_FILE);
17 pstmt.setInt(1, seq)
18 pstmt.executeUpdate();
19 
20 pstmt.close();
21 
22 // file 삭제 생략
23 }


<리스트 4>의 16~20번 줄을 보면 앞서 추출한 메소드 doQuery()로 변경할 수 있을 것 같다. 그럼 코드는 <리스트 5>와 같이 수정될 것이다.

 

<리스트 5> QUERY_DEL_SEQ_FILE 부분 리팩토링 과정

10 public void deleteFiles(Connection conn, int seq) throws SQLException {
11 if (seq == 0){
12 return;
13 }
14
15 // file db에서 삭제 - sts 값 0 로 변경
16 doQuery(conn, QUERY_DEL_SEQ_FILE, seq);
17 
18 // file 삭제 생략
19 }

 

이렇게 정리하고 난 후에 다시 전체적인 코드를 생각해보면 두 개의 메소드가 불필요하다 생각이 든다. 즉 <리스트 6>과 같이 deleteArticles()와 deleteFiles() 메소드를 지우고 바로 doQuery() 를 호출하도록 바꿀 수 있을 것이다. <리스트 6>은 리팩토링을 통해 최종적으로 정리된 소스이다.

 

<리스트 6> 리팩토링 적용으로 개선된 코드
1 // password 확인
2 if (confirmPassword.equals(MASTER_PASSWORD)
3 || confirmPassword.equals(article.getPassword())) {
4 // db에서 삭제 - 삭제 테이블로 이동
5 doQuery(conn, QUERY_MOVE, seq);
6 doQuery(conn, QUERY_DELETE, seq);
7 // memo 삭제 생략
8 // file db에서 삭제 - sts 값 0 로 변경
9 doQuery(conn, QUERY_DEL_SEQ_FILE, seq);
10 // file 삭제 생략
11 } else {
12 resourceName = "/jsp/error.jsp";
13 throw new Exception(CommonUtil.k2a("잘못된 비밀번호"));
14 }


앞에서 보았던 소스의 if else 구문과 비교해보면 doQuery() 라는 공통으로 사용할 수 있는 메소드와 5줄이 늘어났지만 deleteArticle(), deleteFiles() 두 개의 메소드가 사라졌다. 이전 소스와 비교해보면 메소드 구성은 <화면 8>과 같이 변경되는 것을 알 수 있다.

추가된 메소드는 +화살표, 제거된 메소드는 화살표로 표시되고 변경된 메소드는 그냥 검은 화살표로 표시된다. 화면 아래쪽에 표시되는 소스 비교하는 곳을 보면 더욱 명확하게 알 수 있다. 

지금까지 샘플 소스의 구조를 개선하면서 두 가지 리팩토링 기법에 대해 알아보았다. 이 외에도 많은 기법들이 리팩토링 책에 소개되어있고, 이클립스에도 더 많은 리팩토링 기능이 지원된다.


 

<그림 8> 리팩토링 전 후 메소드 비교

 

 

리팩토링 경험담



필자는 이 글을 쓰고 있는 지금 큰 프로젝트를 진행하고 있다. 6년간 하나도 버려지지 않고 운영되면서 그때그때 패치된 페이지를 스프링 프레임워크에 맞춰서 바꾸는 작업이다. 그런데, 작업을 하는 동안 필자가 간과한 것이 있었다. 그렇게 복잡하게 얽히고설킨 페이지를 스프링 프레임워크의 새로운 바닥부터 하나씩 쌓아 올린 것이다. 기존에 운영하고 있는 소스에서 하나씩 뜯어서 새로운 토양으로 옮겨심기를 한 것이다. 이것은 재개발에 가까운 것이었고, 굉장히 많은 시간이 필요했다. 만약 옮겨야 할 소스를 기존의 토양 위에서 조금씩 리팩토링한 후에 옮겼다면 오히려 많은 시간을 절약할 수 있었을 것이다.

실수했다고 생각하는 부분은 다음과 같다. 우선적으로 모든 기능을 다 옮겨올 때까지 신규 페이지는 아직 미완성이다. 하지만 기존의 페이지 내에서 리팩토링을 한다고 하면 이미 모든 기능과 데이터를 다 갖고 있는 상태이다. 다른 파트에서 데이터가 필요하다고 할 때에도 현재 갖고 있는 데이터에서 데이터를 뽑아내서 보다 빨리 전달할 수 있을 것이다.

두 번째로 시간의 압박이다. 기존의 페이지는 언제든지 답이 나온다. 하지만 신규페이지는 모든 테스트를 마칠 때까지 계속 기다리라고 얘기해야만 한다. 바닥부터 모든 것들에 대해서 테스트를 만들어야 하는 탓에 더 많은 테스트 코드들이 필요하다. 여기에도 만만치 않은 시간이 투입된다.

세 번째는 애플리케이션에 대한 자신감이 떨어진다는데 있다. 맥가이버도 아닌데 시간에 쫓기면서 개발할 경우 만들어진 소스는 분명히 수많은 버그를 품고 있을 가능성이 높다. 그 값이 절대 정확하다고 이야기하기 힘들다. 하지만 리팩토링을 통해서 내부로부터 개혁해 나갈 경우 빠진 것 없이 소스를 재구성할 수 있기 때문에 안정된 기반에서 작업할 수 있을 것이다.

전산의 불문율 가운데 유명한 것이 하나 있다. ‘잘 돌아가는 것은 손대지 마라.’ 칼퇴근을 위해서 절대 절명으로 필요한 말이다. 이렇게 관리되는 소프트웨어의 품질은 논하기 힘들다. 그냥 먹고 살기 위한 프로그램과 그것을 관리하는 직장인이 되어버리게 된다. 반면에 리팩토링의 기본 사상은 개선을 위한 노력이다. 막무가내 개선이 아니라 현명한 개선을 위한 방법을 제시하고 있고, 친구격인 테스트 케이스가 그 안전장치가 되어 준다. 한 순간의 품질이 아닌 지속적인 소프트웨어의 건강을 생각한다면 꾸준히 리팩토링으로 손질할 필요가 있다. 그것이 끝없이 변하는 웹 애플리케이션과 같은 소프트웨어일 경우는 더욱 그렇다.
개선을 위한 작은 몸짓에 진정한 프로그래머가 되고 싶은 독자들을 초대한다.

 

참고 자료
1. 리팩토링, 마틴파울러, 윤성준,조재박 역, 대청, 2002년3월
2. 패턴을 활용한 리팩터링, 죠슈아 케리에브스키, 윤성준,조상민 역, 인사이트, 
2006년7월

 

리팩토링 관련 사이트 

1. http://www.refactoring.com/
Refactoring Home Page 

2. http://xper.org/wiki/xp/ReFactoring
김창준 님의 Refactoring에 관한 정보 

3. http://c2.com/cgi/wiki?CodeSmell
Code Smell 

4. http://xper.org/wiki/xp/CodeSmell
Code Smell 번역 

5. http://www.okjsp.pe.kr/lecture/ide/eclipse/refactor/eclipse_refactoring.html 
Eclipse의 refactoring기능 

6. http://www.okjsp.pe.kr/lecture/ide/eclipse/eclipse_install.html 
Eclipse 시작하기

Posted by gofly

댓글을 달아 주세요

OKJSP에 흥미로운 글이 올라워서 배껴왔습니다....;;;;;

무단 복제가 아니길 바라면서 글을 읽어 보시죠....^^


다은 두꺼운 글 씨는 복사해 온 것입니다.


pushState + ajax = pjax 입니다. 


HTML5 의 window.history.pushState() 메소드와 ajax 가 만났습니다. 


뒤로가기 버튼을 이용할 수 없고, 검색인덱스를 생성할 수 없는 ajax 의 한계를 극복했고, hashbang 의 URL hack 을 쓰지 않고도, URL 전환을 처리할 수 있습니다. 


github 의 CEO 인 defunkt 가 jQuery 버전으로 만들어놓았습니다. 


jQuery pjax : 

https://github.com/defunkt/jquery-pjax 


ajax 와 hashbang 그리고 pjax : 

http://rkjun.wordpress.com/2012/05/29/ajax-%EC%99%80-hashbang-%EA%B7%B8%EB%A6%AC%EA%B3%A0-pjax/



뒤로가기 버튼을 이용할 수 없는 것과 검색 인덱스를 생성할 수 없는 aJax의 한계를 극복했다는 것이 너무나 매력적인 포인트지 않을까하는 개인적인 생각입니다.

Posted by gofly

댓글을 달아 주세요

PHP Admin에는 MySql을 관리하는 툴이 있습니다.

너무나 유용하죠.....그런데 이보다 더 유용한 웹 Database관리 툴이 있어 소개해 드립니다.


시작하며...

Tadpole 사이트 메인화면Tadpole 사이트 메인화면


Tadpole은 그림에서 보시는 것과 같이 갖가지 브라우저를 통하여서 기존의 Database뿐아니라 MongoDb와 같은 NoSql까지도 지원하는 아주 유연한 툴입니다.


Tadpole ERD 스크린샷Tadpole ERD 스크린샷


ERD화면도 재공을 해줍니다. 이부분은 참 마음에 듭니다.


뭐 데이터베이스 툴이라면 당연이 있어야 하는 쿼리분석기 이니다.

마음에드는 것은 Color Scheme과 Result Sets인데 참 잘만들어 놓은 것 같습니다.

다음은 환경 및 링크들입니다. 데모 사이트에 가셔서 한 번 체험해 보시는 것도 추천하고 싶습니다.



사이트 주소 : https://sites.google.com/site/tadpolefordb/


마치며...


이 툴을 보면 볼 수록 맘에 드는 것이 참 괜찮은 툴인 것 같다하는 생각이 듭니다.

아마도 한국에서 만든 듯 한데.....누가만들었는지 참 잘만드신듯.....^^

아무튼 개발자의 한 사람으로서 감사하지 않을 수가 없네요....^^

Posted by gofly

댓글을 달아 주세요

  1. Favicon of http://www.facebook.com/TadpoleForDbTools BlogIcon 한금이 2012.07.22 15:31  댓글주소  수정/삭제  댓글쓰기

    소개해 주셔서 감사합니다.

파일(html, css, javascript)와 같은 파일들이나 텍스트 파일들이 1/10크기로 줄어 든다고 하네요.....

server.xml파일에 다음과 같이 추가합니다.

<Server.xml>

    <Connector port="80" protocol="HTTP/1.1" 

               maxThreads="300"

               connectionTimeout="20000" 

               redirectPort="443" 

                                 compression="on"

                           compressionMinSize="2048"

                           noCompressionUserAgents="gozilla, traviata"

                           compressableMimeType="text/html,text/xml"

                           />


이렇게 추가하면 앞축되어져서 클라이언트에 전해지는 것 같습니다.


From : http://viralpatel.net/blogs/enable-gzip-compression-in-tomcat/

Posted by gofly

댓글을 달아 주세요

툴 얻어오기...

It’s assumed you already have Visual Studio, the Windows Phone SDK and (optionally) Zune set up for Windows Phone development. If not, you can obtain the tools for free by downloading Visual Studio 2010 Express for Windows Phone (bit.ly/dTsCH2).
윈도우폰 SDK와 (추가적으로)윈도우폰 개발을 위한 Zune을 설치했다는 것은 당신에게 이미 Visual Studio가 있다는 것입니다. 그러나 만약 그렇지 않다고 하더라도 윈도우폰을 위한 Visual Studio 2010 Express를 무료로 다운로드 받을 수 있습니다(bit.ly/dTsCH2).


You can obtain the latest Cordova developer tools from the PhoneGap Web site (phonegap.com), although future releases will be distributed via Apache (incubator.apache.org/cordova). The download includes the templates, libraries and scripts required to develop Cordova applications across all the supported platforms. You’ll want to use the Windows Phone version, of course.
앞으로는 Apache(incubator.apache.org/cordova)를 통하여 분포되어지겠지만, 현제 최근 Cordova 개발툴은 Phonegap 웹사이트(phonegap.com)에서 얻을 수 있습니다. 다운로드에는 템플릿, 라이브러리 그리고 모든 플랫폼을 다양하게 지원하는 Cordova 응용프로그램을 개발할 때 필요한 스크립트들이 포함되어있습니다. 윈도우폰 버전도 역시 사용할 수 있음은 말할 것도 없구말입니다.


Once you’ve downloaded the Cordova tools, follow the Windows Phone Get Started Guide (phonegap.com/start#wp) and install the Visual Studio template. Creating a “Hello World”-style application is as simple as creating a new project based on the supplied template, as shown in Figure 2.
만약에 Cordova 툴을 다운로드 받았다면 윈도우즈폰 개발 시작 가이드
(phonegap.com/start#wp)에 따라서 Visual Studio 템플릿을 설치하기 바랍니다. Figures 2에서 볼 수있듯이, "Hello World"를 만든는 것은 템플릿의 지원을 기반으로 간단하게 만들 수 있는 스타일 응용프로그램입니다.


Figure 2. Visual Studio에 포함된 윈도우폰용 CordovaFigure 2. Visual Studio에 포함된 윈도우폰용 Cordova


If you build and deploy the project created by the template to your emulator, you should be greeted with the message “Hello Cordova,” as shown in Figure 3.
에뮬레이터에서 프로젝트를 빌드하고 배포했다면, Figure 3에서 보듯이 위대한 메세지 "Hello Cordova"를 만날 수 있을 것입니다(이 말투는 굉장히 장황한 어감의 말투임-해석의 부제로 원저자의 의도가 희석될까 우려하여 코멘트를 남깁니다).


Figure 3. 에뮬레이터에서 Cordova 탬플릿 응용프로그램 구동된 모습Figure 3. 에뮬레이터에서 Cordova 탬플릿 응용프로그램 구동된 모습


윈도우포 Cordova 응용프로그램의 해부...


Although you can develop a Cordova application without much knowledge of how it works under the hood, it’s worthwhile understanding what the various files generated by the template are, as shown in Figure 4.
물론 당신은 Cordova 응용프로그램이 내부적으로 어떤지 몰라도 개발은 할 수 있지만, Figure 4에서 보여주듯 탬플릿에 의해 생성된 각각의 파일들이 무엇인지 이해하는 것은 상당히 가치있는(또는 할 보람이 있는) 것입니다.


Figure 4. Cordova 탬플릿의 폴더 구조Figure 4. Cordova 탬플릿의 폴더 구조


Focusing only on the Cordova files in Figure 4 (from top to bottom), note the following:
다음에 나오는 Figures 4의 Cordova 파일에 대한 이야기에만 주의를 기울여주시기 바랍니다:


GapLib/WP7CordovaClassLib.dll is the Cordova assembly. This contains the Windows Phone native implementation of the Cordova APIs.
GapLib/WP7CordovaClassLib.dll은 Cordova의 직약체입니다. 이 것은 윈도우폰 내부수행에 대한 Cordova API들을 가지고 있습니다.


www is the folder where you place your application assets, HTML5, JavaScript, CSS and images. The template generates a basic index.html file and the master.css stylesheet.
www폴더는 당시의 응용프로그램의 자산인 HTML5, JavaScript, CSS그리고 이미지들이 위치하는 곳입니다. 탬플릿은 기본 index.html을 생성하고 master.css 스타일 시트 파일 또한 생성합니다.


www/cordova-1.5.0.js provides the Windows Phone imple­mentation of the Cordova JavaScript APIs. This interfaces with the native code contained within WP7CordovaClassLib.
www폴더 아래의 cordova-1.5.0.js는 윈도우폰이 수행할 Cordova JavaScript API들을 제공하여 줍니다. 네이티브코드인 이 인터페이스는 WP7CordovaClassLib(.dll)과 함께하고 있습니다.


BuildManifestProcessor.js is a JavaScript file that’s invoked by a post-build step. This file generates the Cordova­SourceDictionary.xml file, ensuring that anything you add to the www folder will be loaded into isolated storage.
BuildMainifastProcessor.js 는 post-build step(뭐라 번역을 해야할지 모르겠음;;;;-내용상 봤을 땐 자동으로 개발자산들을 추가하고 관리하는 듯)에 필요한 JavaScript파일입니다. 이 파일은 Cordova-SourceDictionary.xml 파일에 의해 만들어 졌는데, 뭐든 www폴더에 넣든 독립적인 저장공간에서 읽어드리게 될 것입니다.


CordovaSourceDictionary.xml is a generated XML file that lists all of your application assets. When your application first launches, this XML file indicates the files to be loaded into isolated storage.
CordovaSourceDictionary.xml은 당신의 응용프로그램의 모든 자산리스트로부터(프로젝트내의 모든 파일) XML파일로 만들어졌습니다. 당신이 응용프로그램을 실행시킬 때, 독립저장공간에서 XML파일에서 가리키는 파일들을 읽어드리게 됩니다.


The MainPage.xaml file contains an instance of the CordovaView control, a user control that contains a WebBrowser control:
웹브라우저 콘트롤이 포함하는 사용자 컨트롤를 CordovaView 컨트롤 인스탄스를 MainPage.xaml파일이 포함하고 있습니다:


<Grid x:Name="LayoutRoot">

    <my:CordovaView Name="PGView" />

  </Grid>


When the app starts, the CordovaView control takes care of loading your application assets into local storage and navigating to the www/index.html file, thus launching your application. You can, of course, place other Silverlight controls in the page by editing this XAML, although I wouldn’t recommend it. If you’re writing an HTML5 application, your intention is probably to make this work cross-platform. Any controls you add to MainPage.xaml will of course be specific to your Windows Phone build.
응용프로그램이 시작되면, ControlView는 로컬저장공간내의 응용프로그램 자산을 로딩하고, www/index.html을 가리키고 응용프로그램은 구동되게됩니다. 물론 권하지는 않지만, 다른 실버라이트 컨트롤을 XMAL을 수정하여 페이지에 위치시킬 수(place)있는 것은 당연하고. HTML5응용프로그램을 만들었다면, 당신의 의도대로 다중 플랫폼을 지원하게 될 것입니다. 어느 컨트롤들이라 할지라도 윈도우폰을 빌드하는데 있어서 필요한 것이 있다면  MainPage.xaml에 추가할 수 있습니다.


2장을 마치며...

아...조금 더 어려웠네요;;;;; 전문적인 내용들이 속속있고, 또 이 바닥 문서들이 OOP과 비슷한 애매하고 모호한 하지만 굉장히 이론적인 내용들이 담겨져 있는터라, 그것을 의역할지 직역할지 해석하는데 너무나 어려웠습니다. 뭐 그렇다고 잘 해석했다는 것은 아니구요. 제가봐도 문제가 되는 해석구문들이 있으니 영어좀 하시거나 원서읽으시는 분들은 얘뭐야? 하시겠죠...^^;;;;; 죄송합니다. 저도 제 나름의 노력이라 한계가 있네요....뭐 아무튼 다음에는 이제 구체적으로 개발하는 코드들을 보게 됩니다.


조만간 또 찾아오도록 하겠습니다....^^

Posted by gofly

댓글을 달아 주세요

HTML 5 Weekly 에서 Webzine으로 메일이 주기적으로 오는데 아주 흥미로운 기사를 보게 되어 이렇게 글을 쓰게 됩니다.

다음 부터 쓰는 글들은 MSDN Magazine에서 올라온 글인 "Develop HTML5 Windows Phone Apps with Apache Cordova-Colin Eberhardt" 을 참고로 하여  못하는 영어 해석해가며 인용하여 쓴 글입니다(그러니 조금 오역이나 잘못된 글이 있다 하더라도 이해해 주세요^^ ;;;;;). 자 그럼 시작해 보겠습니다!!!!!


Apache Cordova글 시작

This article introduces Apache Cordova, a framework for creating cross-platform mobile applications using HTML5 and JavaScript, and shows how it can be used to develop applications for Windows Phone.
이 글은 HTML5와 JavaScript를 이용하여 Cross-platform(다중 플랫폼) 모바일 응용프로그램을 만들 수 있는  Framework을 소개하고 어떻게 Window Phone용 응용프로그램을 Apache Cordova로 개발할 수 있는지를 소개하는 것입니다.


Windows Phone and its native development platform allow you to create beautiful Metro-style applications with ease. With the recent Nokia partnership, Windows Phone is starting to find its way into more and more pockets.
윈도우 폰과 윈도우 폰 네이티브 개발 플랫폼은 아름다운 메트로 스타일의 응용프로그램을 쉽게 만들 수 있도록 해줍니다. 윈도우 폰은 현제 더욱 더 휴대할 수 있는 방법을 노키아 파트너쉽을 통하여 시작하고 있습니다.


Recent data published by research firm Gartner Inc. predicts a promising future for the Microsoft OS (bit.ly/h5Ic32), with significant market share in a fragmented market. If you’re developing a smartphone application, this market fragmentation means you either have to choose which OS to target or write the same application multiple times using the diverse range of languages these phones require (C#, Java and Objective-C).
최근 연구 조사기관인 Gartner Inc에서 발표한 데이터에 의하면 분산되어 있는 어플리케이션 시장(이하 마켓)의 공유를 얼마나  중요하게 다루느냐가 마이크로소프트 운영체제(이하 OS)의 미래를 약속한다고 내다봤습니다. 분산되어 있는 마켓이라 하면,  스마트폰 응용프로그램을 개발한다고 가정하고, 어떤 OS를 선택할 것인지 다양한 언어중 폰에서 요구하는 언어는 어떤 것으로 해야 하는지를 결정 짓는 것을 뜻합니다.


However, there is another way. All these smartphones have a highly capable browser, in many ways more capable than their desktop counterparts, where some people still use archaic browsers! Modern smartphones allow you to create applications that run within the browser using a combination of HTML5, JavaScript and CSS. With these technologies you can potentially write a single browser-based application that runs across a diverse range of smartphone devices.
그러나, 여기 대안이 있습니다. 모든 스마트폰에는 고기능의 브라우저를 가지고 있는데, 이 브라우저들은 어떤 분들이 쓰는 구식 데스크탑 브라우저에 비해서 다양한 방면에서 뛰납니다! 현대의 스마트폰은 브라우저에서 HTML5, JavaScript 그리고 CSS의 조화를 이뤄 실행할 수 있는 응용프로그램을 만드는 것을 허용하고 있습니다. 이런 기술은 하나의(또는 어떤) 브라우저를 기본으로 하는 응용프로그램을 기술함으로서 다양한 스마트폰 기계에서 사용할 수 있는 잠재력을 말합니다.


Apache Cordova의 소개

You can create an HTML5-based mobile application by creating a public Web page with JavaScript and HTML5 content and directing people to the hosting URL. However, there are a couple of problems with this approach. The first is the distribution model through online marketplaces and stores. You can’t submit the URL that hosts your Web app to a marketplace, so how can you monetize it? The second problem is how to access the phone’s hardware. There are no widely supported browser APIs for accessing phone contacts, notifications, cameras, sensors and so on. Apache Cordova (just Cordova hereafter for brevity) is a free and open source framework that solves both of these problems.
당신은 JavaScript와 HTML5로 이뤄져있고 사용자가 호스팅 URL로 접근할 수 있는 HTML5 모바일 웹페이지 응용프로그램을 만들 수 있습니다. 그러나 이런 접근은 몇가지 문제점을 가지고 있습니다. 첫 번째로 온라인 마켓의 장소와 상점을 통한 배포모델입니다. 웹 응용프로그램을 마켓 호스트 URL로 등록할 수 없는데 어떻게 통용시킬 수 있겠습니까? 두 번째 문제는 어떻게 스마트폰의 하드웨어에 접근하느냐 하는 것입니다. 스마트폰의 주소, 알림, 카메라, 센서 외에도 여러부분이 브라우저 API에서 지원하지 않고 있습니다. 하지만 Apache Cordova(이하 Cordova)는 이 두가지 문제점을 해결해 주는 무료 오픈소스 프레임웍입니다.


Cordova started life as PhoneGap, which was developed by Nitobi. In October 2011 Nitobi was acquired by Adobe Systems Inc., with the PhoneGap framework being open-sourced under the Apache Software Foundation and rebranded as Cordova. This transition is still underway.
Cordova는 Nitobi에 의해 PhoneGap으로 시작하였습니다. 2011년 10월 Nitobi는 Adobe System Inc에서 이 프로그램을 습득하였는데 후에 PhoneGap 프레임웍은 오픈소스로서 아파치 재단아래에서 Cordova로 명명하기 시작하였습니다. 그리고 아직도 과도기에 있습니다.


Cordova provides an environment for hosting your HTML5/JavaScript content within a thin native wrapper. For each smartphone OS, it uses a native browser control to render your application content, with the application assets being bundled into the distributable. With Windows Phone, your HTML5 assets are packaged within the XAP file and loaded into isolated storage when your Cordova application starts up. At run time, a WebBrowser control renders your content and executes your JavaScript code.
Cordova는 가벼운 네이티브 래퍼와 함께 HTML5와 JavaScript컨텐츠를 호스팅 할 수 있는 환경을 제공합니다. 이는 각각의 스마트폰 OS의 기본 브라우저 컨트롤을 사용하여 분포된 응용프로그램 자산을 묶고 그 내용(Content)를 표현해 줍니다. 당신의 HTML5 자산들은 윈도우즈 폰에서 XAP 파일에 담겨지고, Cordova의 독립된 저장공간(Storaage)안에서 로드되어 응용프로그램이 시작됩니다. 이 때, 웹브라우저 컨트롤러는 내용을 표현하고, JavaScritp코드를 실행하게 됩니다.


Cordova also provides a set of standard APIs for accessing the functionality that’s common across different smartphones. Some of these functionalities include:
Cordova는 서로다른 기종의 기본 기능을 접근할 수 있게 해주는 표준 API들을 제공하고 있습니다. 다음과 같은 것들을 포함하고 있습니다:


  • Application lifecycle events
  • 응용프로그램 생애주기 이벤트들
  • Storage (HTML5 local storage and databases)
  • 저장공간(HTML5 자체 저장공간 및 데이터 베이스)
  • Contacts
  • 연락처
  • Camera
  • 카메라
  • Geolocation
  • 위치정보
  • Accelerometer
  • 가속측정(이건 뭐라해야 올은건지 모르겠네요....)

Each one of the preceding functionalities is exposed as a Java­Script API, which you use from your JavaScript code. Cordova does all the hard work involved in providing the required native implementation, ensuring that you work against the same JavaScript APIs, regardless of the phone OS your code is running on, as illustrated in Figure 1.
당신이 JavaScript코드를 사용하게 되면 각각의 선행기능들이 JavaScript API에 감지되게 됩니다. Cordova는 동일한 JavaScript API들을 사용하여 기본실행에 필요한 복잡한 작업들(이 기종간 호환성을 찾고 그 것에 맞게 랲핑하는 것)에 관하여 제공하는데, Figure 1의 그림에서 처럼 스마트 폰의 OS와 상관없이 당신의 코드는 실행 되어집니다.


Cordova개념도Cordova는 하나의 HTML5 응용프로그램으로 다중기종 모바일 OS들간의 실행을 지원합니다.


The bulk of this article discusses Cordova from the perspective of a Windows Phone developer, where development takes place within Visual Studio and you test your application on the emulator or a physical device. While Cordova is a cross-platform technology, you typically develop using your editor or IDE of choice, so an iOS developer would develop a Cordova application in Xcode and an Android developer would most likely use Eclipse.
이글은 대부분 
Cordova의 Visual Studio나 에뮬레이터 또는 물리적인 기계에서의 개발하는 윈도우 폰 개발자의 시점에서 이야기하게 됩니다. 하지만, Cordova로 다중 플랫폼 기술을 사용하는 동안 에디터나 IDE를 선택해야 하는데, iOS개발자는 Xcode내에 Cordova응용프로그램을 개발할 수 있으며, Android개발자는 Eclipse를 사용할 수 있습니다.


Cordova also has a cloud-based build service called Build (build.phonegap.com), where you can submit your HTML5/JavaScript content. After a short time it returns distributions for most of the Cordova-supported platforms. This means you don’t need to have copies of the various platform-specific IDEs (or a Mac computer) in order to build your application for a range of platforms. The Build service is the property of Adobe and is currently in beta and free to use. It will remain free for open source projects.
Cordova는 HTML5/JavaScript을 언제 어디서든 제공할 수 있도록 클라우드 기반의 빌드 서비스 즉 빌드(build.phonegap.com)에 대한 것도 포함하고 있습니다. 후에 분산된 Cordova를 지원하는 플랫폼의 대부분이 될 것입니다. 이는 사용 플랫폼의 IDE 또는 맥컴퓨터에 복사할 필요가 없이 다양한 플랫폼의 범위에 대해서 응용프로그램을 빌드할 수 있다는 뜻입니다. 이 빌드 서비스는 Adobe의 자산이며 현제는 베타로 무료제공되고 있습니다. 이것은 무료 오픈소스 프로젝트로 남게될 것입니다. 


1장마무리....

오늘은 여기까지 하겠습니다. 3일을 번역했는데.....;;;;;;힘드네요^^;;;;;;; 2장에서는 Cordova를 얻어서 설치하고, 샘플로 어떻게 개발하는지를 번역하여 보겠습니다. 그럼 좋은 하루되세요....^^

Posted by gofly

댓글을 달아 주세요

CJ Hellovision MVNO 빌링 개발을 하러 왔는데 MiPlatform으로 개발을 하고 있더군요.

해서 또 이리 저리 뒤져 보니 데브멘토에서 잘 정리해 놓은 MiPlatform개발 교육 동영상이 있어 이렇게 올려 봅니다.

주소는 아래의 링크를 클릭해 주시면 되겠습니다.


MiPlatform교육 영상 보러가기

Posted by gofly

댓글을 달아 주세요

  1. Favicon of http://bigduck.tistory.com BlogIcon 오리대장 2012.07.16 22:03  댓글주소  수정/삭제  댓글쓰기

    처음 접하는거라 자료가 좀 필요했는데 이렇게 좋은 정보를 찾았네요.
    감사합니다.

이전에 건설기술연구원 프로젝트를 끝내고, 좀 놀다가

오늘은 누리꿈 스퀘어에 CJ HelloVision에 파견나왔네요....^^





아침 일찍 일어나서 출근했더니 죽겠네요....^^ ㅋㅋㅋㅋㅋ;;;;;;

앞으로 몇달동안 열심히 해이지....!!! ^^ ㅋㅋㅋㅋㅋ

Posted by gofly

댓글을 달아 주세요

Web Application개발을 하다 보면 가장 귀찮은 점이 바로 테스트를 하면서 개발을 할 때, Java를 고치고 난 후에 Class를 컨테이너에 적용 시키기 위해서 웹서버를 내렸다가(서버를 정시시키는 것) 다시 올리는 것(서버를 가동시키는 것)이라고 할 수 있습니다.

조그마한 실수 하나에도, 또는 이게 맞는지 저게 맞는지 확신이 서지 않아서 테스트 할 때 이와 같은 서버를 재부팅하는 것은 많은 시간적 소모를 가지고 올 수 있는데, 이런 귀찮은 부분을 수정한 것이 바로 HotSwap기능이라 할 수 있습니다.

HotSwap기능이라는 것이 사실은 컴퓨터의 하드웨어적인 기능이지만 여기서 말하는 HotSwap이란 JAVA에서 말하는 Class로드 부분인 것 같다는 생각이 듭니다. 어쨌든 HotSwap기능이 있는 JRebel을 공짜로 한 번 써봅시다!!!!


Step 1 등록하기!!!!

우선 아래 링크로 접속을 합니다.

http://social.jrebel.com

그러면 아래와 같은 웹페이지가 나타나죠

Social JRebel 첫화면Social JRebel 첫화면

참고! : Social JRebel은 말그대로 SNS 계정이 필요로 하는 JRebel입니다. 자세히는 않읽어 봤지만, 대략 읽어 보니 Social Network를 이용해서 홍보를 하는 것이며, 한달에 한 번 정도 자신의 SNS계정을 통해서 홍보성글을 올리는 걸로 봤습니다. 어쨌든 그래서 공짜인듯 해요. 아! 그리고 또 하나 주의 점은 non-commercial 용도라는 것입니다.


위에 밑줄 그은 부분(그림에서)을 클릭합니다. 그러면 다음 화면이 나타납니다.(Facebook을 하고 있다는 가정에서 하는 것입니다. Twitter 계정으로 하시는 분은 조금 다를 수 있습니다.)

1. Facebook 화면

Social JRebel 등록하기(Facebook)Social JRebel 등록하기(Facebook)

2.Twitter계정으로 할 때의 화면


Social JRebel 등록하기(Twitter)Social JRebel 등록하기(Twitter)



Facebook화면은 제 Web Browser가 이미 Facebook에 로그인이 되어있어서 바로 허가 화면이 뜬것입니다. 만약 Facebook에 로그인이 되어있지 않다면 로그인해야 할 것이고, 만약 계정이 (Twitter 계정역시) 없다면 계정을 만들어야 할 것입니다.



Social JRebel 등록화면Social JRebel 등록화면

이제 트위터에 로그인 헀다거나, Facebook에 Social JRebel이 사용자의 계정을 가지고 광고를 해도 된다고 수락하고나면, 위와 같은 화면이 나타납니다. 뭐 기본적인 Profile을 적는 것이죠. 작성을 다 하셨다면.....아래 그림을 참고 합니다.


Social JRebel 등록화면Social JRebel 등록화면

자신이 사용하는 언어와, Container(그러니까 일반적으로 웹 어플리케이션 서버)를 선택하고, 사용계정에대한 Agreement를 동의하고 JRebel을 다운받았는지 않받았는지를 선택하고 나서 "Register"(등록)을 클릭합니다.

그러면 아래와 같은 화면이 나타납니다.

등록이 완료된 화면등록이 완료된 화면


여기서 Next를 누르면 라이센스키 화면으로 넘어가게 됩니다.(아래그림)


Social JRebel KeycodeSocial JRebel Keycode


Step 2 Eclipse에 JRebel Plugin 설치하고 License Key Code입력하기


Eclipse 에서 JRebel 설치Eclipse 에서 JRebel 설치


Eclipse에 Help>Marketplace에 가면 일반적으로 가장 먼저 보이는 것이 JRebel일 것입니다. 않보이면 JRebel을 조회해서 설치를 합니다.

Plugin 설치가 끝나고 나면 위와 같이  Eclipse메뉴에서 Window>Preferences에 가면 설정화면이 보입니다. 항목중에 JRebel이라는 항목을 클릭합니다.

JRebel plugin for Eclipse 설치 후 설정JRebel plugin for Eclipse 설치 후 설정


그러면 위와 같은 설정화면이 보이는데 여기에서 "Configuration Wizard"를 클릭하시면 아래와 같은 Popup창이 하나 뜨게 됩니다.


JRebel plugin for Eclipse 설치 후 Configure화면JRebel plugin for Eclipse 설치 후 Configure화면


팝업창이 뜨면 조금 느려 질 것입니다. 제 컴퓨터 스펙이 그닥 딸리는 편은 아닙니다. i-5코어 2.5Ghz에 RAM 8G인데도 버벅거렸으니까요;;;; 아마 대부분 느려지실 겁니다. 하지만 인내를 가지고 하시다보면 금방 끝나고, 끝이나면 괜찮아지니까요.....포기하지 마세용!!! ㅋㅋ

어쨌든 위와 같이 라디오 버튼 항목중에 "I want to use JRebel Social(FREE for non-commercial user)"라는 항목을 선택하고 하단에 "Next" Botton을 클릭합니다. 그러면 아래의 화면이 보입니다.

JRebel Configure에서 Keycode입력하기JRebel Configure에서 Keycode입력하기

위에 말풍선에 표시했듯이 아까 Social Jrebel등록후에 나온 Key Code를 공간에 붙여 넣기 하고 "Next"를 누룹니다.

그리고 끝까지 가서 Finish를 누르면 일단 License Key Code등록은 끝이 났습니다.


마지막으로 Preferences창에 JRebel에서 아까는 Configuration Wizard를 선택했다면, 이번에는 그 바로 아랫줄에 있는 "Agent Settings"을 선택하고 아래와 같이 Project의 Root위치를 설정해 줍니다.(사실 이거 왜하는지 모르겠어요 안들어가 있어도 잘되던데;;;;;)

JRebel Agent Setting화면JRebel Agent Setting화면


Step 3 Project에 설정하기!!!

자 이제 프로젝트에 설정을 해야 하는데요, Configuration Wizard에 설명은 아래 그림과 같이 나와있습니다. 그런데 저는 Eclipse Indigo를 쓰고 있는데 창이 이런 식으로는 안뜨더군요.....(다른 버전에서는 아래와 같이 뜰 수도 있지만 저는 조금 다르게 뜹니다.)

Eclipse Project에 JRebel 설정하기Eclipse Project에 JRebel 설정하기


바로 아래와 같이 조금 다르게 뜨는데요. 화면은 아래와 같습니다. 


Eclipse Project에 JRebel 설정하기Eclipse Project에 JRebel 설정하기


일반적으로 Project의 Source폴더가 src로 지정 되어있다면 위에 빨간줄 친것 처럼 "Generate rebel.xml in src"를 클릭하면 되지만 만약 Source폴더가 다를 경우에는 바로 위의 메뉴인 "Generate rebel.xml"을 눌러 Source폴더가 어디인지 지정해 줍니다.

주의! Source폴더는 *.java가 모여있는 Project내의 최상위 폴더를 이야기 합니다.


자 rebel.xml을 Generate했다면 이제 마지막으로 Eclipse에서 돌아가는 Tomcat서버의 설정만 하면 됩니다. 아래의 빨간줄 그은 부분들로 체크하고 저장하면 됩니다(물론 Tomcat Server는 중지시켜 놓구요)


JRebel을 위해서 Tomcat서버 설정하기JRebel을 위해서 Tomcat서버 설정하기


이제 모든 것이 끝났습니다.

이제는 *.java파일을 아무리 고쳐도 Tomcat서버를 멈췄다가 재가동해야 하는 부분은 문명히 필요 없게 되었습니다.


*한가지 아쉬운점

JRebel은 다 좋은데 한가지 아쉬운 점은 바로 xml로드는 지원하지 않는다는 것입니다.

저의 경우 Struts에 iBatis를 쓰고 있는데, iBatis에서 정의해 놓은 SQL문들이 있는 XML을 아무리 바꿔도, HotSwap기능과는 거리가 있는 것 같더군요;;;;; 뭐 그부분을 빼면 나쁘진 않은 것 같습니다......^^잘 사용하세요!!!

















Posted by gofly

댓글을 달아 주세요

  1. 유창근 2012.09.28 09:59  댓글주소  수정/삭제  댓글쓰기

    겁나 좋은정보 감사합니다..!!!제 블로그도 놀러오셔요 개발 정보 조금이나마 기재하고 있습니다.

  2. BlogIcon gedo 2012.11.19 19:26  댓글주소  수정/삭제  댓글쓰기

    스프링에서 xml 쿼리 경로 자동등록해서 쓰시면 안되구요.

    mybatis-config.xml 같은 쿼리경로설정 파일에
    mapper resource="egovframework/job/dbio/WebMapper.xml"

    같이 하나하나 명문화 해서 등록하시면 됩니다.

    • Favicon of https://belong2jesus.tistory.com BlogIcon gofly 2013.01.31 10:28 신고  댓글주소  수정/삭제

      스트러츠에서 할 때는 분명 않되었었는데....스프링으로 하니까 XML로 오토로드(Auto Load)가 되는 것 같더라구요...^^ 물론 이야기 해주신대로 리소스는 명시적으로 추가해서 사용하고 있었습니다....^^

  3. Favicon of http://seirian.tistory.com BlogIcon 엽이군 2013.03.29 15:33 신고  댓글주소  수정/삭제  댓글쓰기

    처음 글에 등록되어 있는 웹사이트가 접속이 안되네요 ㅠ_ㅠ 이제는 막힌건가요?

먼저 이 글을 Head First Java에서 배운 내용을 잊지않기 위해서 정리차원에서 제가 적어두는 것입니다.
오해없으시길 바랍니다


이전 포스트에서는 코드를 전부 main() 메소드에 집어넣었습니다. 그 방법은 정확하게 말하자면 객체지향적인 방법은 아닙니다.사실, 객체지향적인 면이 전혀 없다고 할 수 있지요. 자동 구문 생성기를 만들기 위해 String의 배열 같은 것을 쓰긴 했지만, 직접 객체 유형을 만들지는 않았습니다.

이제 절차적인 프로그래밍 세계는 완전히 제쳐두고 main()을 벗어나서 직접 객체를 만들어보기로 합시다. 자바 객체지향(OO, Object-Oriented) 개발이 얼마나 재미있는지를 확인할 수 있을 것입니다. 우선 클래스(class)와 객체(Object)가 어떻게 다른지 알아보고 객체를 사용함으로써 삶의 질(물론, 프로그래밍과 관련된 삶의 질이겠죠. 패션 감각을 향상시킨다거나 하는데는 별 도움이 않됩니다)을 어떻게 향상시킬 수 ㅇ있는지도 알아보겠습니다. 주의! 일단 한 번 객체 마을로 옮기고 나면 다시 돌아오고 싶지 않을 것입니다.

의자전쟁
(객체가 어떻게 삶을 바꿀 수 있을까?)

옛날에 어떤 소프트웨어 회사에서 팀장이 두 프로그래머에게 똑같은 스펙을 주고는 프로그램을 만들라고 지시했습니다. 두 프로그래머를 경쟁시키기 위해 둘 중에서 프로그램을 더 빨리 완성한 사람에게 실리콘 밸리에 있는 사람이라면 누구나 가지고 있는 에어론™(Aeron™)의자를 주겠다고 했습니다. 절차적 프로그래밍을 선호하는 래리(Larry)와 객체지향적인 방법을 구사하는 브래드(Brad)는 둘다 이 프로그램을 만드는 것이 식은 죽 먹기라고 생각했습니다.

래리 사무실에 앉아서 곰곰히 생각했습니다. "이 프로그램에서 어떤 일을 해야 할까? 어떤 프로시저(Procedure)가 있어야 할까?" 그리고는 "(rotate 프로시저를 써서) 돌린 다음(playSound 프로시저를 써서) 사운드를 재생하면 된다"는 결론을 내렸습니다. 그리고는 잽싸게 프로시저를 만들었습니다. 프로그램이라는 것이 결국은 프로시저를 모아놓은 것이 아닐까요?

그 동안 브래드는 카페에 가서 궁리를 했습니다. "이 프로그램에서 어떤 일을 해야 할까? 그 중에서 어떤 것이 가장 중요한 역활을 할까?"  그래서 "도형이 가장 중요한 역활을 하지 않을까?"라는 결론을 내렸습니다. 물론, 사용자, 사운드, 클릭 이벤트와 같은객체도 생각해 봤습니다. 하지만 그런 객체와 관련된 고드는 이미 가지고 있었기 때문에 도형에 대한 코드만 신경 쓰면 됐습니다. 브래드와 래리가 각각 어떻게 프로그램을 만들었는지, 그리고 결국 누가 에어론 의자를 차지할지 계속 살펴 봅시다.


'Develop Story > Head First Java' 카테고리의 다른 글

2.객체 마을로의 여행  (0) 2011.03.26
1 껍질을 깨고  (0) 2011.03.25
Posted by gofly

댓글을 달아 주세요

먼저 이 글을 Head First Java에서 배운 내용을 잊지않기 위해서 정리차원에서 제가 적어두는 것입니다.
오해없으시길 바랍니다.


자바는 어떤식으로 돌아갈까요?


처음 고려 사항은 애플리케이션 하나를 만들어서 여러 친구들이 가지고 있는 다양한 장치에 보낼 파티 초대장을  만드는 방법입니다.

1.소스->2.컴파일러->3.결과물->4.각 기계(Device)의 가상머신

1.소스: 소스를 만들되 문법을 지켜야 함
2.컴파일러: 소스 코드를 컴파일 처리한다. 이 때 오류가 없는지 체크하고, 통과한 경우에만 최종 결과를 만들어 줍니다.
3.결과물: 소스를 컴파일 하면 바이트코드(Bytecode)라는 코딩된 문서를 만들어 줌. 이것이 기계에 실행명령을 내림.
4.가상머신: 각 기계마다 소프트웨어 자바가상머신(J.V.M)이 있어 3번 결과물을 가상머신에서 실행 시키게 됩니다.

 
 

1.소스: *.java로 된 파일
2.컴파일러: 커맨드 창에 "%javac *.java "와 같이 javac를 실행시켜 *.java파일을 컴파일 합니다.
3.결과물: *.java파일이 컴파일 되면 바이트코드가 담긴 *.class파일이 생성됩니다.
4.가상머신: 커맨드 창에서 "%java *.class"를 실행시키면 *.class파일의 바이트코드를 JVM에서 실행한다. 

뭐 대충 여기까지가 자바의 구동원리 입니다.

아래는 자바의 버전별 클래스 포함의 변천사를 간단히 도표화 한 것입니다.

간단히 정리해 본 자바의 역사

간단히 정리해 본 자바의 역사




자바는 예전 C와 같이 프로그래머가 필요한 부분을 일일이 구현할 필요가 없이, 제공되는 클래스(또는 API)를 통하여 간단하게 호출하여 사용하기만 하면 됩니다. 이 것이 프로그래머들에게 아주 매력적인 요소중에 하나죠.

*Head First Java의 참 재미있는 부분은 가끔 나오는 QnA입니다.

Q: 위에 있는 표에 보니까 자바 2랑 자바 5.0은 있는데, 자바 3하고 자바 4는 어디 있어요? 그리고 자바 5.0이라고 나와 있는데, 자바 2는 왜 자바 2.0이라고 안쓰죠?

A: 마케팅의 세계란 정말 심오하죠... 자바 버전이 1.1에서 1.2로 올라갔을 때, 바뀐 것이 정말 많았어요. 그러다 보니 마케팅 팀에서 아예 이름을 새로 정해야 되겠다는 생각에 "자바 2"라는 이름을 붙였죠. 실제 자바 버전은 1.2였는데도 말예요. 버전 1.3하고 1.4는 계속 자바2로 간주되었습니다. 자바 3나 4 같은 건 없었죠. 자바 1.5가 나올 때도 정말 많은 변화가 있었습니다. 그래서 마케팅 팀에서는 (개발자들도 대부분 동의했죠) 새로운 이름이 필요하다는 생각에 어떤 이름을 쓸까 고민을 했습니다. 사실 숫자 상으로 볼 때 "3"이 와야 했는데, 자바 1.5를 "자바 3"이라고 부르려니 오히려 더 혼란 스러울 것 같다는 생각이 들어서 그냥 버전 "1.5"의 "5"에 맞춰서 "자바 5.0"이라고 부르기로 했습니다.

그래서 오리지널 자바는 버전 1.02(처음으로 공식 릴리스된 버전)부터 1.1까지는 "자바"였습니다. 버전 1.2, 1.3, 1.4는 "자바 2"였죠. 그리고 버전 1.5부터는 "자바5.0"이라고 부릅니다. 하지만 종종 (.0을 빼고) "자바 5"라고 부르기도 하고, 또는 (코드명을 따라서) "타이거"라고 부르기도 합니다. 다음 릴리즈에 어떤 이름이 붙을지는 저희도 잘 모르겠네요.


*개인적으로 저는 이런 비하인드 스토리를 알게 되면 뭔가 재미가 느껴질 까?? ㅎㅎㅎㅎ


자바 코드의 구조


자바코드의 구조

자바코드의 구조



1.소스파일에는 무엇이 들어 있을까?

소스 코드파일(java라는 확장자자 붙은 파일)에서는 클래스(class) 각각 한 개씩을 정의합니다. 클래스는 보통 프로그램의 한 부분이라고 할 수 있지만 아주 작은 애플리케이션 중에는 클래스 단 하나만으로 이뤄진 것도 있습니다. 클래스는 한 쌍의 중괄호({ })안에 들어가야 합니다.

public class Dog {

//클래스



2.클래스 안에는 무엇이 들어있을까요?

클래스에는 메소드(method)가 한 개 이상 들어갑니다. 예를 들어, (개를 나타내는) Dog 클래스에는 (짖는 것을 의미하는) bark라는 메소드가 들어갈 수 있으며, 이 메소드에는 개가 짖는 방법을 지시하는 내용이 들어가면 될 것입니다. 메소드는 클래스 안에서(즉, 클래스 전체를 감싸는 중괄호 안에서) 선언해야 합니다.

public class Dog {

    void bark() {

    } // 메소드

//클래스 



3.메소드 안에는 무엇이 들어있을까요?

메소드를 감싸는 중괄호 안에는 메소드에서 처리할 일을 지시하는 내용이 들어갑니다. 메소드 코드는 기본적으로 일련의 선언문을 모아놓은 것이므로 지금은 메소드를 일종의 함수나 프로시저와 비슷한 것으로 생각해도 됩니다.

public class Dog {

    void bark() {

        statement1; //선언문
        statement2;

    }// 메소드

}
//클래스



클래스를 해부합시다.

JVM이 실행되면 명령행에서 지정했던 클래스를 살피게 됩니다.
그리고 나서 main() 메소드를 찾아 봅니다.

public static void main(String[] args) {
    //코드가 들어갈 자리
}

 
이런 메소드를 찾으면 JVM에서는 main 메소드의 중괄호({ }) 안에 있는 것을 모두 실행시킵니다.
모든 자바 애플리케이션에는 
최소한 클래스한개가 있어야 하며 적어도 main 메소드 하나가 있어야 합니다.(클래스마다나씩이 아니라 애플리케이션마다 하나씩 있어야 합니다. *참고로 WAS와 같은 웹서버는 main메소드를 따로 구성하실 필요가 없겠죠^^ main메소드로 WAS가 이미 구동중이니까요^^)

main이 들어있는 클래스 만들기

자바에서는 모든 것이 클래스 안에 들어갑니다.
우선 소스 코드(.java 확장자가 붙어있는) 파일을 입력한 다음 컴파일해서(.class 확장자가 붙어있는) 새로운 클래스 파일을 만들면 됩니다. 프로그램을 실행시킨다는 것은 사실 클래스를 실행시키는 것이라고 할 수 있습니다.

프로그램을 실행시킨다는 것은 자바 가상 머신(JVM Java Virtual Machine)에 "Hello 클래스를 불러 오고 그 main() 메소드를 시작하라. 그리고 main() 메소드에 있는 모든 코드가 실행될 때까지 계속 실행시켜라"라는 뜻의 명령을 내리는 것입니다.

클래스에 대한 자세한 내용은 다음 포스팅에서 알아보기로 하고, 지금은 실행 가능한 자바 코드를 만드는 방법에 대해 살펴보기로 하겠습니다. 그러면 우선 main()부터 시작해보죠.
 
프로그램 실행 절차가 시작되는 부분은 바로 main()메소드입니다.

프로그램이 아무리 커도(바꿔 말하자면 프로그램에서 얼마나 많은 개수의 클래스를 사용하든 상관없이)프로그램을 실행시키려면 반드시 main() 메소드가 필요합니다. 

1.저장 -> 2.컴파일 -> 3.실행 

main 메소드란?

일단 main 안으로 들어가면 (또는 어느 메소드든) 본격적으로 뭔가가 돌아갑니다. 즉
대부분의 프로그래밍 언어에서 컴퓨터로 하여금 어떤 일을 하게 만드는 모든 일반적인 지시사항은 메소드 안에 들어있습니다.

코드에서는 JVM에 다음과 같은 것을 지시할 수 있습니다.

1.뭔가를 하는 것

선언문: 선언, 대입, 메소드 호출 등

int x = 3;
String name = "Dirk";
x = x* 17;
System.out.print("x 는 " + x + "입니다.");
//주석은 이렇게 씁니다.


2.뭔가를 여러 번 반복하는 것

순환문: for와 while

while (x > 12) {
    x = x -1;
}

for(int x -0 ; x < 10; x = x+1) {
    System.out.print("x의 값은 "+x+ "입니다.");
}



3.조건에 따라 뭔가를 하는 것

분기문: if/else 테스트

if(x== 10) {
    System.out.print("x가 10이군요.");
} else {
    System.out.print("x가 10이 아닙니다.");
if((x< 3) & (name.equals("Dirk"))) {
    System.out.print("Gently");
}
System.out.print("이 선언문은 무조건 실행됩니다.");


돌리고 돌리고 돌리고...

자바에는 while, do-while, for의 세 가지 표준 순환 구조가 있습니다. 순환문에 대한 자세한 내용은 나중에 알아보기로 하고 일단 여기서는 while만 생각해 보겠습니다.

문법이 워낙 간단하기 때문에 설명이 지루하게 느껴질지도 모르겠네요. 어떤 조건이 만족되기만 하면 순환문 블록(block) 안에 들어있는 작업을 모두 처리합니다. 중괄호 한 쌍 안에 들어가는 내용ㅇ이 바로 순환문 블록이며 반복하고자 하는 내용은 그 블록 안에 집어넣으면 됩니다.

순환문에서 가장 중요한 것은 바로 조건 테스트 부분입니다. 자바에서 조건 테스트의 결과는 부울 값(boolean)입니다. 즉, 참(true) 또는 거짓(false) 값을 가지게 됩니다.

"iceCreamInTheTub 가 참인 동안 계속 아이스크림을 퍼라"와 같은 것이 바로 부울 테스트라고 할 수 있습니다. 통 안에 아이스크림이 있거나 없거나 둘 중 하나기 때문이지요. 하지만 이 때 참과 거짓이 분명하지 않으면 안 됩니다. 반드시 참과 거짓이 명확하게 구분되는 것만 조건 테스트로 사용할 수 있습니다.


'Develop Story > Head First Java' 카테고리의 다른 글

2.객체 마을로의 여행  (0) 2011.03.26
1 껍질을 깨고  (0) 2011.03.25
Posted by gofly

댓글을 달아 주세요

1.PHP에서 SQL function을 쓰려면

나는 솔직히 PHP모듈을 설치하면 SQL function 자동으로 쓸 수 있는줄 알았다.

그런데 mysql_connect() 함수를 사용해서 DB에 쿼링을 하려고 하
Fatal error: Call to undefined function mysql_connect() in getConnect.php on line 10

라는 메세지가 뜨기 시작했다. 해서 인터넷을 뒤져 뒤져 알게된 사실이 있다.

2.PHP에 SQL Lib 추가하기

첫 번째, PHP가 설치된 곳에 php ver 5이상에는 php.ini파일이 php.ini-development ,php.ini-production 두가지로 제공을 해 주고 있습니다.

이 파일을 php.ini로 변경하여 아래 부분을 변경합니다.

이 파일 내용을 조금 변경을 해야 하는데요. 우성 아래의 extension_dir을 찾기를 사용해서 찾아서 아래와 같이 변경합니다.

[code php];extension_dir = "ext" #위 부분을 아래와 같이 변경합니다. 주의해야 할점은 ";"을 없애줘야 합니다. extension_dir = "C:/inet/PHP/ext"[/code]

그리고 다음에 주석 처리된 것을 지워 줘야 합니다. 위에도 이야기 했지만 "php.ini"파일에서의 주석구분은 ";"으로 시작하느냐에 따라 주석인가 아닌가 하는 것으로 구분합니다.

[code php];extension=php_mysql.dll
;extension=php_mysqli.dll
#위 부분에 ";"부분을 삭제 합니다.[/code]

두 번째, 중요한 것은 환변변수를 추가해 주는 것입니다. 환경변수에 PHP가 설치 되어 있는 경로를 Path변수에 추가를 해줍니다. 이렇게 하지 않으면 C:\windows\system32 폴더 아래에 "*.dll"파일을 복사해 줘야 합니다. 하지만 이 경우 업그레이드시에 별 추천할 방법이 아니라고 합니다.

세 번째, 본래 phpinfo() 함수를 써보면 Configuration File(php.ini)을 불러 오는 곳이 "C:\windows"로 설정되어 있어서 "php.ini"파일 설정 한 것을 "C:\windows"에 복사해야 합니다. 하지만, 이렇게 하지 않고, 레지스트리에 PHP설치 경로를 추가 합니다.

HKEY_LOCAL_MACHINE\SOFTWARE\PHP에 IniFilePath를 추가하고 php.ini파일이 있는 "C:\inet\PHP"를 추가합니다. 아니면, 다음의  내용을 그대로 *.reg 파일로 만들어도 됩니다.
그리고 그것을 실행하고 Apache 서버를 구동하면 됩니다.

[code]Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\PHP]
"IniFilePath"="C:\\inet\\PHP"
[/code]

이렇게하고 나면 mysql_connect() 함수를 써도 아무런 이상없이 잘 돌아 갑니다.

문제는 SQL이 버전차이로 에러가 나더군요.....;;;; 이건 또 극복후에 기회가 되면
Posted by gofly

댓글을 달아 주세요

  1. Favicon of http://magic.wickedmiso.com BlogIcon 사악미소 2014.12.31 14:27 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 올려주신 글 잘 봤는데요.
    환경변수 설정은 php설치경로 까지인가요? 아니면 ext 파일인가요?
    그리고 system32로 옮겨야 하는 파일이 php_mysql.dll 파일인가요 아니면 libmysql.dll 파일 인가요?
    레지스트리 생성된것 까지 다 확인했지만 간단한 db 연결 확인만 하려 해도 에러도 아닌 하얀 창만 떠서 난감하네요

    • Favicon of https://belong2jesus.tistory.com BlogIcon gofly 2014.12.31 20:21 신고  댓글주소  수정/삭제

      dll파일이 있는곳 까지 환경변수에 넣어주시면됩니다(ext까지죠). 이렇게하셨다면 system32를 넣어주지 않으셔도 됩니다. OS환경어느경로에서나 dll파일을 접근할수있기 때문인것입니다. 그래도 넣으시려면 모두다 넣어주셔야 할것입니다^^ dll파일은 자바로 따지면 jar파일 같은것이니까요^^ 어떤 dll이 어떻게 호출될지 모르는것이죠

      도움이 되셨길 바랍니다^^ 새해복많이 받으세요^^