1.오전시간에 복습한 인터페이스 클래스, 추상클래스를 활용한 클래스의 설계와 구현의 분리

 

-추상클래스에서 하위 클래스들도 공통적으로 동작할 연산이면, 더이상 재정의 못하게끔

추상클래스 단에서 선언시 final을 붙여버리고 구현하는 것이 안정적이라 판단.

 

-하위클래스들이 차이를 갖는 연산의 경우 설계단(추상클래스,인터페이스 클래스)에서

인터페이스(외부에 노출시킬 연산)의 선언시 abstract을 붙여서 하위클래스에서 구현하게끔

강제 + 하위클래스에서 해당 연산을 선언시 protected로 scope를 줄여주는게 캡슐화의 관점에

서 옳다고 생각함.

 

-어제 했던 format 인터페이스클래스와 하위 구현 클래스 집합(템플릿 메서드패턴으로서 전체 시스템중 form의 역할)

 ,word 클래스(사용자로 부터 출력할 데이터, 포맷을 전달받아 출력이란 비지니스 업무를 담당)

 

  이 개념을 통해 예전 내 로또의 view 단과 control단의 꼬임을 해결할수 있을지 모르겠다고 직감이 왔었음.

  (좀더 설계와 디자인 패턴에 대한 이해가 깊어져야 함.) 그나저나 control 단이 business 단인가? 헷갈린다.

  spring 책을 빨리 봐야 do,vo,dto,layer,mvc,design pattern등 감을 잡을텐데.. 조각 조각 지식이 편재된 기분임.)

 

  내 경우엔 어제 format 인터페이스 클래스의  의미론적 개념과 ,  그것이 노출하는 인터페이스(메서드)의 이름

  ( getFormat() )에 도저히 적응을 못했음. 포맷 클래스가 String형 메세지를 전달받아 그것을 가공해 String으로

  돌려주는 것을 이해를 못했음.

 

  왜냐하면, 일반적으로 print()라는 행위를 한다고 할때, 출력할 데이터, 출력할 양식, 출력할 칼라 등은 출력이라는

  행위에서 객체가 되지, 주체적인 역할을 하지 못한다고 생각했기 때문임.

  

  결국 내 개념대로 시스템이 구현되었을 경우, 사용자는 word 객체의 print(출력할 문자열 데이터, 출력할 타입인

  열거형 포맷 스타일)   ex)  WORD.print(String data, FORMAT FORMAT::EQUAL) 이 되었을 것임.

 

  WORD 클래스의 내부 구현은 if(formatType == FORMAT::EQUAL) 서식 출력 else if(formatType == FORMAT::ETC)...

  또는 switch(formatType) case FORMAT::EQUAL  서식 출력 식이 되었을 것임.

 

  만약 고객의 요구로 출력 서식이 추가 되었을땐 WORD 비지니스 클래스의 구현이 변경되어야함. 만약 WORD 클래스가

  FORMAT외에도 COLOR , EFFECT 등등을 포함하였을 경우엔 WORD 클래스의 print()구현부가 엄청 복잡해지고 비대해

  짐.

  

  부수적으로 매개변수에 따라 사용자에게 제공할 인터페이스(메서드)가 많아 질경우 수정해야 하는 코드의 양도 더 많아

  질거라 예측됨.(실제로 안해봐서 모름) 

 

  (ETC) 객체지향적으로 사고해보아도, 포맷클래스가 데이터를 받아서 자신의 책임으로 가공한다는 역할에 알맞다고

  생각했음. 단지 인터페이스(메서드) 이름이 getFormat인게 직관적이지 않았음. makeStringByFormat() 이런 메서드 이름

  이었다면 처음에 혼란도 적었을거라 판단됨. 허나 한번 더 생각해보면 .. 포맷클래스가 자신의 개념정의대로 "자신의 정의

  (다양한 출력서식)에 따라 사용자(caller)가 전달한 데이터의 출력 양식을 처리하고 결과를 반환한다" 라고 접근해보면,

  매우 객체지향적이라 느껴짐. (추상적인 부분이라 말로 표현이 어려움)

 

 

  Format 클래스를 생성해 Word 클래스에 전달하는 것은 확실치 않지만, Strategy 패턴으로 판단됨. 어떤 포맷을 주입하냐

  에 따라 Word가 제공하는 print()메서드의 동작이 변화함으로.

 

  (ETC)기존 stratergy 패턴 설계에 따르면 Word클래스는 사용자로부터 Format 객체, Color 객체, Effect 객체를 전달받고 전달

  받은 객체들에게 순차적으로 일을 시키면  자신의 역할인 데이터의 출력을 수행할수 있다. 음.. 굉장히 멋진 설계 같음. 코드도

  깔끔할테고..

 

  그리고 Word 클래스의 print(format.getFormat(msg))하는 부분은 또다른 패턴의 효과로서 template method 패턴이라 판단됨.

  인터페이스 클래스를 통해 공통된 인터페이스(메서드)인 getFormat(String) 을 Word클래스에게 제공함으로서

  Word의 구현이 단순해짐. 즉 Word로선 Format클래스의 구체적인 타입에 따른 처리를 고민할 필요가 없어짐.(캡슐화

  ,정보은닉=>reduce dependancy? loose cupling?) 공통된 getFormat()으로 사용할수 있게 해준다는 점에 감사해야할 정도임.

 

  FormatA, FormatB, FormatC 식으로 싸지르듯 설계를 했다면, 위처럼 심플하게 처리가 불가능함. 전체 코드도 개판날테고..

 

  

2.오후 시간에 배운 예외처리

-try catch finally 등 문법적인 부분은 논외. 그외 exception이 계층트리로 구축되어 있고 구분도 됨으로 논외(api 도큐먼

  드에서 계층트리(영문판 7.0은 hierachy tree 일듯) 확인해보면, Error,Exception,RuntimeException을 수 많은 패키

  지들이 상속받아 사용하고 있음.(이러한 예외클래스를 상속구조로 체계화 함으로서 중구 난방식의 예외처리 클래스가

  아니게 되어 통일성이 있고, 타입의 계층트리라 함은 다형성을 JAVA,C++등 언어적으로 지원해주니 catch(Exception e)

  처럼 사용이 가능함.

 

- 오늘 배운것중 핵심은 문법이 아닌, 예외 발생시 제어의 흐름이라 생각함. 내 경우 예전에 input/output stream을 통해

   파일 관련 작업을 해주던중,,  익셉션이 났을때 내가 열어놓은 스트림(시스템 리소스)를 제대로 해제를 못해주는 경우

   가 발생했었음. 즉 예외 발생 가능한 코드들을 어떻게 try catch로 감싸는 지가 정말로 중요하다고 생각함.

   그나저나.. finally{} 가 return을 이긴다니.. 쇼킹했음. call stack이 unwired 될때 .. 너무 디테일하게 접근할듯 하니.. 그만 생략

 

-개인적으로 콜러->워커1->워커2->워커3->워커4  식의 클래스간 association 관계 or 메서드간(처리흐름) 의존적(?) 관계일

  때 워커 4가 throw한 예외를 워커3이 catch해서 처리가 가능한 경우 예외가 발생했다는 사실을 콜러 1에게 까지 전달해야

  하는지에 대해

  (sol)선생님 말씀으론 유저(최상위 콜러)까지 전달해주는 것이 일반적이라 말씀해주심.(simple stratergy is best)

  일단 하나는 해결이 되었고..

  (추가)jsp책을 보다가 517page void sendEmain(...)throws AddressException, MessagingException 식으로 처리함. 즉 자신이 아둥

  바둥 끙끙할바에 콜러쪽에 책임을 전가시키는 것임.


- (추가)오늘 jsp를 보다가 javax.sevelet.http.HttpSeveletRequest , Response 라는 클래스를 접해서 도큐 문서를 검색해봤지만

  찾을수 없었음. (sol) se 버전 -> ee 버전의 차이임.

 

 -콜러->워커(매개변수) 일 경우 워커의 연산이 콜러가 전달한 매개변수에 의존적일때.. 워커가 연산전에 전달받은 매개변수

  의 유효성을 검증하고 문제를 찾았을때, 해당 문제를 자신이 풀어버리고 콜러에게 적당한 결과를 줄것인지, or 문제를 풀어

  버리고 콜러에게 문제 발생을 알릴것인지, or 문제를 풀지 않고 콜러에게 바로 throw 할것인지...

 

  즉 전달 받은 매개변수에 대한 워커의 책임과 권한을 어느정도 까지 설정해야 하는지가 혼란스러웠음. 일단 정책을 잡은 것은

  전달 받은 값을 임의로 변경  caller가 0을 매개변수로 전달 -> worker(int num) -> worker의 연산 a / num; //devide by zero

  가 될것이고, 워커측에서 매개 변수에 대해 자신의 작업을 수행전에 if(숫자 범위체크) throw new NumericException 식으로

  처리를 할것임.  잘못된 매개변수에 대해 어떠한 조작및 연산도 수행하지 않고 바로 콜러측으로 책임을 전가시킴.

  =>자신의 잘못은 자신이 책임지자!    <-- 이걸 일반화 시켜도 될지 불안함.. 너무 많은 다양한 상황이 있을텐데...

 

  매개변수를 전달받은 경우의 사례에(일반화 시키면 콜러or 메인 시스템측의 잘못) 한가지 더 고민해 볼것은 콜러측에 예외

  에 대한 정보를 전달해야 하는데, 어떻게 전달할지에 대한 방식의 결정임.

  a.워커의 설계를 boolean workerMethod()로 만들어서 처리의 성공,실패란 2가지 의미의 정보를 콜러에게 전달할지

  b. int wokerMethod()로 만들어서 오류의 종류에 따라 숫자를 전달할지(콜러측이 모든 에러와 숫자를 알아야 하기에 콜러의

     부담이 커짐.)

  c. boolean werkerMethod() throws xxxException 식으로 만들어서 일반적인 수행 결과와 익셉션에 의한 수행 중지를 구분

    할지..  (콜러측이 반드시 처리를 해줘야 하게끔 강제하는 방식인데.. 만약 자신이 처리를 할수 있는 상황이라면? 그때도

    콜처측에 강요할 것인가? (sol) 선생님 정책에 따라 강제하지 않되(메서드에 throws 선언x) , 만약 자신(워커)가 lib등 각종

    api를 사용하면서 개발자가 반드시 try/catch로 처리해야할 Exception 의 하위 Exception들의 경우 워커가 처리하고 콜러

    측에 입을 다물지, 콜러측에 바로 예외를 던질지..  콜러는 워커보다 분명 시스템에서 상위의 흐름일텐데.. 역시 콜러측에

    무조건 알려야 겠다고 글을 적다보니 결정이됨.

 

    내가 이렇게 고민을 하게된 계기는 클래스 or 메소드간에 관계가 있을때 각자의 역할 정의와 책임 영역을 확실히 해야

    객체지향에 어울린다고 느꼈기 때문임. 게다가 the c++ programing language 책에서 try catch로 코드를 도배하지 말라

    고 경고했고.. (그래서 throw 해야할 상황과 아닌 상황을 구분을 해야만 했음.)

 

  -(2013/11/27추가) 콜러 1 -> 워커1 throws AExcpetion-> 워커2 가 throws 할수 있는 Exception 타입의 제한!

   트리계층 관계에서 상위타입이(or워커1) 선언한 throws Exception에 대해 하위타입(or워커2)은 Exception의 하위

   타입 or 상위타입이(or caller) 선언한 타입의 Exception만 throws 할수 있다.

   =>왜냐하면, 콜러측에선 워커1 선언된 throws 익셉션만 보고 try{} catch(){} 를 준비할텐데.. 난데 없이

     하위타입(워커의 워커= 워커2)이 전혀 다른 계통의 익셉션을 던져버리면 전체 시스템에 오류가 생긴다. 그것은 콜러의

     잘못도, 워커1의 잘못도 아닌 워커2의 잘못과 책임이다! (컴파일 타이밍에 잡아주는지는 테스트 안해봐서 모르겠음)

     (상,하위 클래스라면 잡아줄테지만, 메서드의 경우도 잡아줄지.. 흠.. 메서드는 클래스 내부 메서드니까 잡아주겠지..)

 

 -(추가) 사용자 정의 익셉션의 필요성에 대해 고민을 잠깐 했다. 그이유는 java api도큐먼트의 계층트리를 보면 

   수많은 종류의 error,exception,runtimeException 파생 클래스가 있었기 때문에 .. 사용자들이 제멋대로 추가를

   하기 보단, 상황에 맞는 익셉션을 찾아서 재정의(extends) 하는 것이 업무적 통일성(?)에서 낫다고 판단했기 때문이다.

   (sol) 수많은 구체적 익셉션 클래스가 내 상황과 100% 매치한다는 보장이 없다. 내가 구축하려는 시스템 만의

   익셉션 처리를 해야만할 독특한 상황이 있을수 있기 때문이다. 또한 팀작업으로 진행시 팀원들간 사용할 데이터

   타입에 대해 공유를 하기 때문에.. 중구난방의 익셉션 클래스는 방지가 가능할 것이다. = 단정하지 말것! 

 

  -(추가) 역시나 콜러->워커(매개변수)에서 매개변수의 유효성을 체크해야 하는 책임이 누구에게 있는가를 여전히

    고민했었다. 일반적인 메서드간의 연쇄가 아닌 내 경운 클래스간의 association으로 보니까 해결책이 어렴풋이 느껴

    졌다. 


    사례1: View 클래스 -> 사용자 입력값 전달(window app의 경우 메세지 핸들링) -> Control 클래스(내가 정의한 리스너)

    -> 사용자의 입력에 따라 적합한 비지니스 클래스를 선택하고 ,비지니스 클래스에 입력값을 전달해 비지니스 로직 수행 

     -> Business 클래스 작업수행 전에 매개변수(사용자 입력값)의 유효성 체크


     => 사용자 입력값의 유효성 처리는 coller(컨트롤러 클래스) 에서 하고 woker(비지니스클래스)는 유효한 값을 가지고 

     자신의 비지니스에 따라(ex)회원가입의 경우 -> 웹서버or 일반 서버로 request -> 서버의 입력처리 클래스(컨트롤러)가 

     적절한 비지니스클래스에 dispatch(request.detailInfo) -> 비지니스 업무가 회원가입의 경우이기 때문에 DB에 query

     request -> DB의 작업 수행후 ->response(비지니스 클래스에게? 아니면 컨트롤러 클래스에게?) -> 하여간 클라이언트

     측으로 처리 결과 전달 ... 생략


     => 사용자의 입력값에 대한 검증은 컨트롤러 클래스 단의 책임이다. (아직 프로젝트를 해본적이 없고, spring 프레임워크

     에 대한 개념이 전무해서 확실치 않다.)  


  -(추가)아.. 그러고보니 왜 sysout("에러메세지") assert 조건:xxx에러! 식으로 하지 않고 throw new xxxExcpetion을 사용하는

    지에 대한 고민이 부족했다. java ,c++ 언어적으로 지원하는 처리의 흐름 + 콜러측으로 문제에 대해 전달 + 해결이 안되면

    계속해서 상위 콜러로 타고가는 과정은 너무나 멋진 디자인이라 생각한다. 책임자&관할자를 찾아서 그 객체or루틴에 처리

    를 맡긴다라...   chian of responsibility 패턴의 아이디어와 유사하다. 


    언어적으로 오류처리에 대한 멋진 프로세스를 지원하니 당연히 사용해야 할 것이다.! (문제는 전체 코드가 try catch로 

    도배가 되면.. 알될것이다. 자신의 책임 영역에서 확실히 처리할 것! throws를 통해 콜러측에게 무리한 부담을 주지 말것!

    java api의 wrapper클래스들이 어떻게 내부적으로 예외를 처리해서 우리 개발자들의 부담을 줄여주는 지를 상기해야한다!


    =>결국 throw xxException을 적극적으로 사용하돼, 맡아서 처리할 클래스를 명확히 정의하고 서로간 책임 영역을 확실히

    해야할 것이다. 조금 더 깊은 이해와 경험이 필요할 듯 느껴진다.


 -(추가2) 커스터마이징 익셉션 클래스의 유용성. 즉 내가 재정의할 클래스이기 때문에 필요한 정보를 담아둘수 있다. 

   정보를 저장해두고, getter를 제공하면, 콜러측이 받은 익셉션에서 필요한 정보를 얻을수 있다. so good! (난 미처.. 생각을

    못했다는..) (ex)컨트롤러가 비지니스 로직에게 "사용자의 주문량"을 매개변수로 넘길때.. 비지니스 로직은 재고량을 체크

    해서 재고&주문량 tradeoff 값을 리턴해주면.. 콜러(컨트롤러)가 받아서 뷰단(사용자)으로 발송(다이얼로그 창을 띄우던지..)

     할 수 있다. 

   

    결국 컨트롤러 클래스 -요청-> 비지니스 클래스  비지니스 클래스 -응답 -> 컨트롤러 클래스란 양방향 관계에서 throw는 associ

    ation의 방법중 하나이다. 만약 throw 해서 컨트롤러 클래스에게 필요한 정보를 전달 안해줬다면, 컨트롤러 클래스는 자신의

    역할과 정의가 아닌, 재고량에 대해 어떻게든 정보를 얻어야 했을것이다. <-- 자바의 예외처리 메카니즘은 워커측이 작업

     수행불가인 상황 + 구체적인 정보를 전달해 줄수 있게 도와준다.  

     (return -10은 처리 실패, 재고량 10개   ,return 5는 처리 성공 재고량 5개  , ... ) 이것 보단 명확하지 않은가? 그럼으로 잘 사용해

     보자! 


  -커스터 마이징 익셉션을 throw한다는 것을 예외,에러 상황이라 인식하지 말고, 일반적인 상황이라 인식할것. 


   -아참 중요한건 아닌데.. java.lang.Throwable 인터페이스 클래스에 private 멤버 필드로 String detailMessage 가 존재 

     했기에 우리가 exception인스턴스.getMessage()가 하는 메서드를 통해 String 정보를 얻을수 있는것임. (grepcode.. thanks)



3.awt중 Compoenet 클래스, Toolkit 클래스 소스 코드 보기, s.o.p 소스코드 보기

 

-오늘도 대충 훑어 봤는데.. dispatch() 메서드를 분석, toolkit의 run() 메서드를 분석했음..

 

-처음엔 우리가 println()를 예외처리 없이 사용하는 이유를 알고 싶었음. (api 개발자가 우리가 편하게 사용할 수 있도록

 고민한 흔적) .. system클래스의 멤버필드인 outputstream 클래스를 상속받은 PrintStream 클래스가 제공하는 println() 

 를 grepcode.com 를 통해 파고 들어가서 버퍼에서 실제 데이터를 읽어오는 단계까지 접근했었음.

 

 PrintStream의 println(String)의 구현시 BufferedWriter,OutputStreamWriter,OutputStream 이란 멤버 필드에게 작업을 시켰는

 데.. 그중 실제 write작업은 BufferedWriter가 담당함(io과정에서 버퍼된 클래스를 사용해야 효율 증대는 논외) write()메서드

 로 이것도 파고들면 abstract 메서드니..설계가 녹아나있음. 전체적으로 이해는 못했지만.. 몇단계의 포장이(wrapper) 되어 있었

 고 내부적으로 버퍼에 입,출력하는 과정에서 발생하는 exception들을 처리했었음. 결국 내 경우(사용자) 내부 동작이 어떻게 돌

 아가는지 몰라도 간단한 인터페이스인 println()로서 편하게 사용할 수 있는 것임.

 

 자바의 in/output stream클래스들은 생성하면서 다른 스트림을 매개변수로 받게됨. decorator 패턴이었나. 해당 클래스를

 생성자를 통해 매개변수로 받아서 자신의 동일한 인터페이스로서 매개변수로 받은 그 클래스의 연산(기능)을 사용하는것.

 

-전보다는 쉽게 읽히긴 하는데.. 전체적인 클래스간 association은 너무 복잡함. Accesible, 스레드 동기화 syscronized

  등이 아직 명확치 않음.

 

-sun 사람들이 try catch를 어떤식으로 구현을 했는지 살펴보고.. 내가 느낀바에 따르면.. if(){ if(){ if(){} } } 식으로 점점

  중첩하는 방식이었음. 즉 1번 작업 수행을 try로 감싸고 catch 처리  2번 작업은 1번작업의 try내부에서 한번더 try catch

  처리 .. 식으로

 

-역시나 명확하게 감을 잡지 못하겠음.

 

4.svn(서브버전) 프로젝트 소스코드 관리 툴

 

-서버를 내 컴퓨터에서 설치후 관리하려 함

 

5.tomcat을 이용해 로컬 서버에 페이지(jsp) 띄워보기

 

-중고 서점에서 구한 jsp책.. 버전이 오래됐지만, 좋은 책이라고 선생님이 말씀해주셔서 뿌듯했음.

 

-톰캣 설치및 서버 실행까지 문제가 없었고, 지훈형님 도움으로 이클립스에 플러그인 설치함.

 

-문제는 디폴트 jsp파일을 자동으로 생성해서 서버를 실행했는데 계속해서 해당 파일을 찾을 수 없다는 404 에러 발생

(sol)문제는 jsp파일 실행시에 디폴트로 잡혀있는 j2ee preview localhost로  jsp파일을 실행했기 때문.

       내가 설치한 tomcat 7.0 server localhost로 실행을 해서 해결됨 (아무것도 아닌 문제로 약 1:30분 소요됨.)

 

-(중요)눈으로만 jsp 책을 읽는 것보다 이제부터 시간을 할애해 실습해볼 계획임

 

6.테스트 도구인 JUnit 사용해보기

 

-계기는 the c++ programing language 에서 클래스,메서드 등의 불변속성을 보던중

  (개인적으로 메서드에서 예외처리및 콜러,워커등의 관계 속에서 워커(호출된 메서드)의 책임 범위를

  어떻게 하는것이 옳은 것인지 몇일 전부터 고민했었기 때문)

  그것의 구현을 위한 방법중 하나인 단정문 assert()를 보다가 java에서 assert를 사용하기로 마음먹음

 

 -코드 테스트를 위해 assert를 사용했으나 (jvm실행 매개변수에 -ea) 

 선생님 말씀으론 테스트엔 JUnit을 사용한다는 조언을 듣고 바로 테스트해봄

 

 -프로젝트별,패키지별,클래스별,메소드별 단위테스트가 무척 간단해졌음. (메서드 선행조건,후행조건,불변속성

,클래스 선행조건,후행조건,불변속성, 각메서드별 수행 시간도 나오고.. 잘은 모르지만 자바의 annotation 도큐먼트

 태그를 이용해 스크립트처럼 테스트 처리가 가능한듯. 매우 만족. 언제 쫌더 파지..?)

 

7.현재 읽고 있는 책들,.. code complet2 , the c++ programing, web developer with javaserver pages, 자바의 정석은

 레퍼런스 북처럼 보고 있음. uml 책도 있긴 한데.. 도무지 시간도 없고.. 예전에 공부햇던 기억 + 우리 선생님이 수업

 시간에 짚어주시는 걸로 reminding.. 개발 관련 보고 싶고 알고 싶은것이 너무 많다..(목표 없는 지적 호기심 주의할것) 

 

8.집에 가서 계획: 가급적이면 code complet 1회 속독, c++ programing 너무 어렵고 디테일함.. 일단 봉인. + 각종 블로그

에서 디자인 패턴 공부

 

9.내일 할일:jsp 진행 , svn 진행, JUnit은 한동안 봉인, 예외처리에 머리싸매는 것도 일단 봉인, java awt 소스 코드중

  볼만한 메서드 2개 정도 분석, jsp 때문에 html,xml을 따로 학습할 필요는 없을듯함.(시간 부족) 글고.. 수업도 들어야지..

 

  아.. 여유 된다면, 오라클 12c는 포기하고 11버전으로 설치 + 연동 (콘솔창에서 오라클과 대화하는 명령문.. 몇일만에 머리

  속에서 증발했음.. 대책이 필요)   오라클 12c 설치된거 지우는 시간이 아까울지도;;;

 

10.윤팀장님과 게임developer 양성 과정 관해 아주 짧게 대화함. 팀장님도 바쁜일이 있으신듯.(연말 결산및 정리 땜에 내년 초에나 진행하실듯?) 내경우도 현재 여유는 없고..  흠.. 나중에 게임 개발 교육 기관및 커리큘럼등 경쟁자 조사및  게임 개발사 need 분석등의 간략 기획안 만들어서 보고하면..?

 

11.지훈이 형이 재미있는 아이디어를 두유 한잔에 내게 전해주셧음. 지훈이형 항상 고맙고.. 음..작별인사는 나중에 개별적으로

하지요~  best regard!

 

post script

시간 참 빨리가네..

by givingsheart 2014. 1. 1. 15:05