Clean Code that Works.

서울 상경 ~_~

My side2008. 11. 19. 09:13

이제 취직해서...
담주에 출근을 =ㅂ=..

아 그나저나 오늘 마소 세미나를 건대 에서 하는구나..

바로 앞인데 알았으면 사전 등록 할껄..ㅠㅠ
현장 등록 만원.. -ㅅ-..
살림 사느라 지금 거지 ;ㅁ;ㅁ;ㅁ;ㅁ;ㅁ;ㅁ;ㅁ;ㅁ;ㅁ;



http://www.dehats.com/drupal/?q=node/36

여기 블로그에 나와있는 구성도 입니다.
이거 생각보다 어렵내요...
영문이라서 좀 다가가기도 어렵고.. 패턴이..ㅎㄷㄷ

일단 기본적으로 MVC 패턴이고,,싱글톤, 프록시, 커맨드, 퍼사드 패턴 등등..
디자인 패턴공부를 약간하긴 했지만 이건 뭐...-ㅁ-;;
이거 마스터하면 위 패턴은 정말 쉬울듯....


블로그 쥔장은 전체적으로 pureMVC를 추천 하는 듯 하고..
마지막에 나와있는 글을 보면..

Debugging. Singletons can mean hell when it's time to debug. PureMVC uses less Singletons than Cairngorm.

ㅎㄷㄷㄷㄷㄷ

그냥 이래 저래 공부하면서 로그인 구현 튜토리얼을 만들어 볼까 ..
뭐 영문 사이트 찾아 보면 많이 있고 pureMVC 사이트 가면 있으면서도..

영어로 되서 어려우니 겸사겸사 공부할겸 .. =ㅁ=..

천천히 조금씩 작성해 봐야지. 으케케케

머.. 2년이나 남았지만...

이번 출시 계획은 잘 발표 한거 같다..

95~98~xp~이렇게 3년동안 운영체제를 바꿔주어나갔는데
이번엔 xp가 너무 장기 집권을 했다. 2001년에 나온거 같은데 무려 7년차..

난 작년 말 부터 비스타로 갈아 탔지만..

일단 지금까지는 윈도우 변경 주기는 3년이 가장 적절한거 같다.
윈도 7이 출시 되면서 기존 xp 유저들을 다 윈도 7으로 끌어 가야 할텐데..
과연 어떤 방식으로 끌어갈 지 기대된다.

웹 하고도 어떤 방식으로 연동되어 나올 건지도 기대되고.....

정말 2050년 근 미래에는 공각기동대 처럼 전뇌가 나올듯 싶다...

나도 사이보그로 갈아타버려!!.. ㅋㅋ

정보의 홍수 속에서 부디 자아를 잃지 않고 나를 유지 할 수 있도록 하자.
Stand Alone Complex.


대략 위와 같은 모습으로...

티스토리 블로그 페이징 처럼 해보고 싶었습니다.

 

전체 페이지를 구해와서 이를 10개씩 보여주고

나누어서 페이징을 구분 하였습니다.

이전, 이후 버튼을 추가 하여 이동 가능 하고

직접 페이지를 선택해서 이동 가능 합니다.

페이지는

5페이지가 넘을 경우

1 | ... 페이지 |...| 마지막 페이지

이런 형식으로 보여주게 되잇고 5페이지씩 보여지게 되어 있습니다.

현제 페이지는 위 스크린 샷 처럼 빨간 색으로 나타 나게 되어있습니다.

 

자 이제 소스를 보면...

디비 부분은 생략 하였습니다.

으하 복잡 합니다 ;ㅁ;

페이징은 어플리케이션 컨트롤 바에 만들었습니다.

이전, 이후 버튼은 기본 컨트롤 바(navBar)에 있고

내부에 어플리케이션 컨트롤 바(pageBar)를 한개 더 추가해서

거기다가 숫자 페이징을 적용 했습니다.

 

페이지를 이동 할 때마다 setPageBar()를 호출해서 pageBar를 다시 그리는게 핵심포인트!!!

소스 설명은.. 쉬어서 하지 않겠습니다 ;ㅁ;

 

리팩토링 안했습니다. ;ㅁ;

보여줄 페이지를 수정 하기 위해서는 수작업을 해야 합니다. (심볼릭 정수로 치환하세요 ;ㅁ;)

나중에 컴포넌트로 배포 가능 해지면 올려보겠습니다. ㅜ_ㅠ


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

간단한 리팩토링을 했습니다.

보여줄 페이지를 심볼릭 정수로 -ㅁ-..viewPage

그리고 페이지 만드는 과정에서 중복이 있길래 이를

makePage()라는 함수로 뽑아서 만들었습니다.

덕분에 소스가 줄어들고 약간 읽기 쉽게 되었습니다.

5페이지 이상일때만

1 | 페이지 | ... 마지막 페이지

이렇게 보이도록 수정했습니다.

스샷 보면 5페이지 이하 인데도

.... | 5 이렇게 되어있었습니다.


private var totalPage:int;
private var currentPage:int;
private var _label:Label;
private var _vRule:VRule;

private function setPageBar():void {
    totalPage = noticeList.getTotalPage() + 1;
                currentPage = noticeList.getCurrentPage();
               
                var viewPage:int = 5;
                var i:int;
               
                var dotLabel:Label = new Label();
                dotLabel.text = "...";
                var vRule:VRule = new VRule();
                vRule.height = 10;
                var firstLabel:Label = new Label();
                firstLabel.text = "1";
                firstLabel.addEventListener(MouseEvent.CLICK, labelClickEvent);
                var lastLabel:Label = new Label();
                lastLabel.text = totalPage.toString();
                lastLabel.addEventListener(MouseEvent.CLICK, labelClickEvent);
               
                if (totalPage > viewPage) {
                    if (currentPage < viewPage) {
                        for (i = 1; i < viewPage + 1; i++) {
                            makePage(i);               
                        }
                    } else if (currentPage >= viewPage) {
                        pageBar.addChild(firstLabel);
                        pageBar.addChild(vRule);
                        pageBar.addChild(dotLabel);
                        vRule = new VRule();
                        vRule.height = 10;
                        pageBar.addChild(vRule);
                        for (i = (currentPage - 1); i < (currentPage + 4); i++) {
                            makePage(i);       
                        }
                    }
                } else {
                    for (i = 1; i < totalPage; i++) {
                        makePage(i);
                    }
                }
               
                if (totalPage == currentPage + 1) {
                    lastLabel.setStyle("color", "Red");
                    pageBar.addChild(lastLabel);
                } else if (totalPage < viewPage + 1){
                    pageBar.addChild(lastLabel);
                } else {
                    dotLabel = new Label();
                    dotLabel.text = "...";
                    pageBar.addChild(dotLabel);
                    vRule = new VRule();
                    vRule.height = 10;
                    pageBar.addChild(vRule);
                    pageBar.addChild(lastLabel);
                }
   }

// 페이지 선택시 이동 하기 위해서 만들었습니다.
   private function labelClickEvent(event:MouseEvent):void {
    var page:int = parseInt(event.target.text, 0);
    noticeList.movePage(page);
    pageBar.removeAllChildren();
    setPageBar();
   }

// 페이지 만드는 함수

private function makePage(i:int):void {
                _label = new Label();
                _label.text = i.toString();
               
                if (i - 1 == currentPage) {
                    _label.setStyle("color", "Red");
                }
                if (i > totalPage - 1) return;
                   
                _label.addEventListener(MouseEvent.CLICK, labelClickEvent);
                _vRule = new VRule();
                _vRule.height = 10;
                pageBar.addChild(_label);
                pageBar.addChild(_vRule);       
            }


// 이전, 이후 버튼 클릭시 사용 하기 위해서 만들었습니다.   
   private function buttonDownHandler(event:FlexEvent):void {
    var type:String = event.target.label;
    if (type == "Previous") {
     noticeList.previousPage();
     pageBar.removeAllChildren();
     setPageBar();
     nextBtn.enabled = true;
     if (noticeList.getCurrentPage() == 0) {
      previousBtn.enabled = false;      
     }
    } else if (type == "Next") {
     noticeList.nextPage();
     pageBar.removeAllChildren();
     setPageBar();
     previousBtn.enabled = true;
     if (noticeList.getCurrentPage() == noticeList.getTotalPage()) {
      nextBtn.enabled = false;      
     }
    }
   }

    }
   }

SELECT [가져올 컬럼] FROM [해당 테이블] LIMIT [value], [value];
value 는 시작 숫자와 와 가져올 숫자

예들 들어
SELECT * FROM bbs LIMIT 10, 10;

이렇게 하게 되면
결과중에서 10번째 부터 10개 가져온다.
다음 페이징을 할 경우 LIMIT 20, 10 이렇게 하면 20번째 부터 가지고 오게된다.

이것을 응용해서 티 스토리 페이징 처럼 구현 할것~!

Returning TOP N Records

DataBase2008. 10. 17. 13:49

http://www.petefreitag.com/item/59.cfm
위의 블로그에서 퍼온 글.
최근 게시물 뽑아올 때 유용.

Returning only the first N records in a SQL query differs quite a bit between database platforms. Here's some samples:

Microsoft SQL Server

SELECT TOP 10 column FROM table

PostgreSQL and MySQL

SELECT column FROM table
LIMIT 10

Oracle

SELECT column FROM table
WHERE ROWNUM <= 10

Sybase

SET rowcount 10
SELECT column FROM table

Firebird

SELECT FIRST 10 column 
FROM table

Due to these differences if you want to keep your code database independent you should use the maxrows attribute in the cfquery tag in ColdFusion. The tradeoffs to database independance is performance, I would expect maxrows to be slower than specifying the rows in the SQL.

<cfquery datasource="#ds#" maxrows="10">
SELECT column FROM table
</cfquery>

PostgreSQL and MySQL have a cool feature that will let you return an arbitrary range of rows (eg return rows 10-20). This is very handy for displaying pages of records:

SELECT column FROM table
LIMIT 10 OFFSET 20

The above query will return rows 20-30

그냥 이리 저리 공부하면서 연구실 홈페이지 만들며 정리도 할겸 만들어 보았다.

설계도 완벽하지 않고
그냥 공부하면서 기능 하나씩 첨부해서 진행 할 생각이다.

이클립스 3.4 가니메데 에다가 플렉스 빌더 플러그인 설치하고.
라이프사이클 설치, 톰캣 6.0, mysql 로 작업을 진행하는 중이다.

메인 화면에서 회원 가입을 눌르면 새 창이 팝업 되면서 회원 가입창을 보여주는 형식이다.

메인 화면


저기 로그인 옆에 regist member를 누르게 되면 아래와 같은 팝업창이 생성된다.
var _register:Register = Register(PopUpManager.createPopUp(this, Register, true));
PopUpManager.centerPopUp(_register);
Register라는 컴포넌트를 미리 만들어 주고 PopUpManager를 통해 팝업 창을 호출한다.
PopUpManager.removePopUp(this);
창을 닫을 때는 위 함수를 팝업창에서 호출해 주면 된다.

회원 가입 팝업창 Register





데이터 베이스와 연결하는게 좀 시간이 걸렸다.
services-config.xml 파일을 변경 했는데 변경 사항이 적용되지 않아서 -_-;;

services-config.xml 파일에 추가하여야 할 코드.
amf 부분에 추가 하여야 한다.
my-amf의 url 끝(/amf 를 /amf2로 바꾸는 것을 잊지 말아야 한다.)
<channel-definition id="dblab-amf-channel" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/DBLab.net/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
            <properties>
                <polling-enabled>false</polling-enabled>
            </properties>
</channel-definition>

remoting-config.xml에 추가하여야 할 코드
<default-channels>
        <channel ref="dblab-amf-channel"/>
        <channel ref="my-amf"/>
</default-channels>
   
<destination id="register">
        <properties>
            <source>register.RegisterImpl</source>
        </properties>
</destination>

일단 이렇게 하면 플렉스에서의 설정은 끝난다.

그다음에 해야할 것이 데이터베이스와 연결하는 자바 코드를 작성해야 한다.

RegisterImpl의 회원 가입 코드
public void doRegister(ArrayList<HashMap<String, String>> member) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/DBLab?characterEncoding=UTF-8";
            String id = "root";
            String password = "root";
            Connection conn = DriverManager.getConnection(url, id, password);
            Statement stmt = conn.createStatement();
            String sql = "insert into member(MEMBER_email, MEMBER_password, MEMBER_name)" +
                            " values('" + member.get(0).get("email") + "', '" + member.get(0).get("password") + "', '" +
                             member.get(0).get("name") + "')";
            stmt.close();
            conn.close();
        } catch (Exception e) {
            System.out.println(e);
        } finally {
           
        }
       
    }

아 심플해~
나중에 좀 더 이해도가 올라가면 ibatis나 hibernate를 적용해 봐야겠다.

잘 모르는건 댓글달아 주셔요.

지금은 아키텍트 보다는 구현이 더 좋기 때문에...
생각을 해보지는 않았지만 나중에는 아마 해보고 싶을꺼 같다.

책 읽으면서 느끼는게 우왕.. 역시 아키텍쳐는 어렵군화.. -ㅂ-..

대규모 프로젝트를 진행해야 할때는 챙겨야 하는 선행 조건이 장난 아니게 많다 -ㅂ-...

code2 complete
chaptor 3 준비는 철저하게 : 선행조건 에 나온 요점 정리를 보면

- 구현을 준비함에 있어서 가장 중요한 목표는 위험 감소이다. 준비 작업이 위험을 증가시키지 않고 감소시킬 수 있도록 한다.
- 만약 품질이 뛰어난 소프트웨어를 개발하고 싶다면, 처음부터 끝까지 소프트웨어 개발 ㅗ가정 내내 품질에 대한 관심을 유지해야 한다. 초기의 품질에 대한 관심은 나중에 관심을 갖는 것보다 제품의 품질에 훨씬 큰 영향을 미친다.
- 프로그래밍을 시작하기 전에, 적절한 준비의 중요성과 함께 소프트웨어 개발 과정에 대해서 상사와 동료를 교육하는 일도 프로그래머의 몫이다.
- 프로젝트의 종류가 구현의 선생 조건에 중대한 영향을 미친다. 반복적으로 진행해야 하는 프로젝트가 있는 반면, 순차적으로 진행해야 하는 프로젝트도 있다.
- 만약 요구 사항 개발이 제대로 이루어지지 않았다면, 문제의 중요한 사항들을 놓칠 수 있다. 요구 사항 변경은 구현 다음 단계부터는 처음보다 20~100배 정도로 비용이 들기 때문에, 프로그래밍을 시작하기 전에 요구 사항이 맞는지 확인 해야 한다.
- 만약 구조적인 설계가 제대로 이루어지지 않았다면, 구현 시에 올바른 문제를 잘못된 방법으로 해결할 수 잇다. 잘못된 구조로 작성된 코드가 증가할수록 구조적인 변경 비용이 증가하므로, 아키텍처가 맞는지 확인해야 한다.
- 구현 선행 조건에 어떤 접근 방법을 적용햇는지 이해해야 하며, 그에 따라서 적절한 구현 방법을 선택한다.


프로젝트를 진행하면서 구현시에 항상 구현에만 급급하지 않고 프로젝트의 전체적인 모습을 볼 수 있도록 항상 생각하는 프로그래머가 되자. !!

화면 UI를 개선하였습니다.
추가 기능:변신 알림 창과 함께 알림 사운드가 추가 되었습니다.
옵션을 켜고 끌 수 있고, 시간도 지정할 수 있게 되었습니다.


나중에 시간이 되면 문게이트 알리미를 추가할 생각입니다.

설치를 위한 기본 사항 : 요기 들어가서 http://get.adobe.com/kr/air/otherversions/ 파일 설치 하시고

첨부파일 설치하시면 됩니다.