1. 작업 리스트 관리(CRUD)

1.1. 새로운 작업 추가 – 완료

    @Test public void addNewWork(){
        WorkList workList = new WorkList();
        String workName = “새로운 작업 추가하기”;
        workList.add(new Work(workName));
        assertEquals(1, workList.size());
        assertEquals(workName, workList.get(1).name);
    }

1.2. 선택한 작업 삭제 하려다 보니 Work 마다 번호가 매겨져 있어야 할 것 같아졌습니다. 새로운 작업을 추가 했을 때 그 작업의 번호를 리턴 받도록 합니다. 작업 번호는 1번 부터 시작합니다. 새로 추가되는 작업의 번호는 리스트 요소중에 제일 큰 번호를 갖게 됩니다.

1.2 작업 번호 받기 – 완료

     @Test public void addNewWork(){
        WorkList workList = new WorkList();
        String workName = “새로운 작업 추가하기”;
        int workNumber = workList.add(new Work(workName));
        assertEquals(1, workNumber);
        assertEquals(1, workList.size());
        assertEquals(workName, workList.get(workNumber).name);
    }

1.3. 선택한 작업 삭제 – 완료

    @Test public void deleteWork(){
        WorkList workList = new WorkList();
        int workNumber1 = workList.add(new Work(“work1”));
        int workNumber2 = workList.add(new Work(“work2”));
        assertEquals(2, workList.size());
        workList.delete(workNumber1);
        assertEquals(1, workList.size());
        assertEquals(“work2”, workList.get(workNumber2 – 1).name);
    }

리스트에서 작업이 삭제 되면 작업의 번호도 그에 따라 변경 됩니다. 예를 들어 2개의 작업에서 첫번째(1번) 작업이 삭제 되면 두번째(2번) 작업의 번호가 첫번째 작업의 번호로 바뀌게 됩니다.

두 개의 메소드에 중복이 발생했습니다. workList 객체를 @Before 가 붙은 메소드로 올리겠습니다.

    WorkList workList;

    @Before public void setUp(){
        workList = new WorkList();
    }

1.4. 파일로 저장하기 – 완료

    @Test public void saveList() throws IOException{
        workList.add(new Work(“work1”));
        String fileName = “ToDoList.txt”;
        workList.save(fileName);
        StringBuffer buffer = new StringBuffer();
        String line;
        BufferedReader reader = new BufferedReader(new FileReader(fileName));
        while ((line = reader.readLine()) != null) {
            buffer.append(String.format(line + “\n”));
        }
        reader.close();
        assertEquals(“work1\n”, buffer.toString());
    }

1.5. 파일에서 읽어오기 – 완료

    @Test public void loadList(){
        int workNumber = workList.add(new Work(“work1”));
        String fileName = “ToDoList.txt”;
        workList.save(fileName);
        workList = new WorkList();
        workList.load(fileName);
        assertEquals(1, workList.size());
        assertEquals(“work1”, workList.get(workNumber).name);
    }

1.6. 전체 리스트 보여주기 – 완료

    @Test public void printList(){
        workList.add(new Work(“work1”));
        workList.add(new Work(“work2”));
        workList.add(new Work(“work3”));
        assertEquals(“work1\nwork2\nwork3\n”, workList.toString());
    }

그리고 여태까지 Work class에 name 변수가 public으로 되어 있었는데 private으로 바꿔주고 에러나는 부분은 getter와 setter로 포장해 줍니다.

TDD 연습용 프로그램

“TDD 도우미”

TDD를 사용하여 개발 또는 공부를 할 때 도움이 될 프로그램을 생각해 봤습니다. 조그만 목록 관리와 작업 당 소요 시간 측정은 작업의 난이도가 어땠는지.. 혹은 작업의 단위를 너무 크게 한 것은 아닌지 생각해볼 수 있지 않을까 해서 넣어봤습니다.

1. 작업 리스트 관리(CRUD)
1.1. 새로운 작업 추가 – 완료
1.2. 선택한 작업 삭제
1.3. 작업 리스트 파일로 저장
1.4. 작업 리스트 읽어 오기
1.5. 전체 리스트 보여주기

2. 작업 소요 시간 측정
2.1. “작업 시작” 버튼을 클릭 한 시간 부터 “작업 완료” 버튼을 클릭 했을 때 까지의 시간을 잽니다.
2.2. “일시 정지” 버튼을 클릭하면 시간 재는 걸 잠시 중단 합니다. “작업 시작”버튼을 클릭하면 다시 이어서 시간을 잽니다.
2.3. “작업 완료” 버튼을 클릭하면 해당 작업한 시간이 기록됩니다.

3. 작업 자동 분류(완료된 작업, 진행 중인 작업, 해야할 작업)
3.1. 새로 추가된 작업은 “해야할 작업” 목록에 추가 됩니다.
3.2. “작업 시작” 버튼을 클릭한 작업은 “진행 중인 작업” 목록에 추가 됩니다.
3.3. “작업 완료” 버튼을 클릭한 작업은 “완료된 작업” 목록에 추가 됩니다.
3.4. 선택한 분류의 작업만 보여주기.

CallBack 사용해 보기

영회형의 최신글에서 JDBC 노가다를 CallBack을 사용해서 멋지게 처리하는 글을 보고 이런 형태로 개선하면 좋을 것 같은 부분들이 떠올랐습니다.

IO를 할 때 try-catch 블락이 계속 중복 되는데요. 아래의 코드를 보겠습니다.
[#M_ more.. | less.. |

    public void getWebSiteInfoHavingNewPosts(){
        request = “http://www.hanrss.com/api/list_subs_new_items.qst”;

        try {
            URL url = new URL(request);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestProperty(“Authorization”, “Basic ” +
                    new sun.misc.BASE64Encoder().encode(new String(id + “:” + password).getBytes()));
            br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line = “”;
            while ((line = br.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty(“line.separator”));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder.toString());
    }

 

  public void getRecentFivePostWithFSRL(){
        String fsrl=”98000″;
        request = “http://www.hanrss.com/api/get_recent_items.qst?fsrl=” + fsrl;

        try{
            URL url = new URL(request);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line = “”;
            while ((line = br.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty(“line.separator”));
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder);
    }

  

public void getOnePostWithFSRLAndSSRL(){
        String fsrl=”98000″;
        String ssrl=”388743″;
        request = “http://www.hanrss.com/myfeeds_main.qst?fsrl=” + fsrl + “&ssrl=” + ssrl;

        try {
            URL url = new URL(request);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line = “”;
            while ((line = br.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty(“line.separator”));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder);
    }

_M#]첫번째 메소드만 중간에 뭐가 한 문장이 추가 됩니다. 다른 두 개의 메소드는 빨간색 글씨 아래로는 완전히 같은 코드입니다. 빨간 글씨 아래의 큰 덩어리를 다른 메소드로 분리해 내고 싶었지만 첫번째 메소드 처럼 중간에 connection에 뭔가를 추가해야할 일이 생길 수도 때문에 그렇게 하지 못하고 조금씩 묶어서 다른 메소드로 빼냈습니다.

그랬더니 코드가 아래처럼 됐습니다.
[#M_ more.. | less.. |

    public void getWebSiteInfoHavingNewPosts(){
        request = “http://www.hanrss.com/api/list_subs_new_items.qst”;

        try {
            HttpURLConnection connection = getConnection();
            connection.setRequestProperty(“Authorization”, “Basic ” +
                    new sun.misc.BASE64Encoder().encode(new String(id + “:” + password).getBytes()));
            makeResult(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder.toString());
    }

 

  public void getRecentFivePostWithFSRL(){
        String fsrl=”98000″;
        request = “http://www.hanrss.com/api/get_recent_items.qst?fsrl=” + fsrl;

        try{
            HttpURLConnection connection = getConnection();
            makeResult(connection);
        }catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder);
    }

  

public void getOnePostWithFSRLAndSSRL(){
        String fsrl=”98000″;
        String ssrl=”388743″;
        request = “http://www.hanrss.com/myfeeds_main.qst?fsrl=” + fsrl + “&ssrl=” + ssrl;

        try {
            HttpURLConnection connection = getConnection();
            makeResult(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder);
    }

_M#]물론 메소드들이 다이어트를 해서 조금 보긴 괜찮은데 그래도 try-catch가 자꾸 중복되서 나오는게 보기 싫어졌습니다. CallBack을 만들어서 써보고 싶어졌습니다. 결국 코드는 아래처럼 변했습니다.

[#M_ more.. | less.. |    

public void getWebSiteInfoHavingNewPosts(){

        request = “http://www.hanrss.com/api/list_subs_new_items.qst”;

        sendRequest(new ConnectionCallBack(){
            public void doSomethingWithConnection(HttpURLConnection connection) {
                connection.setRequestProperty(“Authorization”, “Basic ” +
                    new sun.misc.BASE64Encoder().encode(new String(id + “:” + password).getBytes()));
            }
        });
        System.out.println(builder.toString());
    }

  

public void getRecentFivePostWithFSRL(){
        String fsrl=”98000″;
        request = “http://www.hanrss.com/api/get_recent_items.qst?fsrl=” + fsrl;

        sendRequest(new ConnectionCallBack(){});
        System.out.println(builder);
    }

 

  public void getOnePostWithFSRLAndSSRL(){
        String fsrl=”98000″;
        String ssrl=”388743″;
        request = “http://www.hanrss.com/myfeeds_main.qst?fsrl=” + fsrl + “&ssrl=” + ssrl;

        sendRequest(new ConnectionCallBack(){});
        System.out.println(builder);
    }

 _M#]흠.. interface로 해두니까 꼭 구현을 해야 되서 아래 두 개의 메소드에서는 구현할 필요가 없는데 구현을 해야만 하는 상황이 생겼네요. 그래서 interface를 class로 바꾸고 빈 메소드로 만들어 두었습니다.

으~ 어렵습니다… 마지막 코드도 별로 좋아보이지 않는데요. 흠…좀 더 공부하다 보면 좋은 방법이 생기겠죠.