3월, 2021의 게시물 표시

Clean Code - 제 1장. 의미 있는 이름

이미지
Clean Code - 의미 있는 이름 모두 좋은 내용이지만, 개인적으로 핵심만 정리했다. 의미있게 구분하자 애매한 -Info, -Data, -Manager, -Processor 같은 접미사는 피하자. 정확한 정보제공을 위한 단어만 사용하자. 발음과 검색이 쉬운 단어를 사용하자.  타 프로그머와 육성으로 소통하기 쉬운 단어를 사용하자. 그리고 검색이 쉬운 단어가 프로그램 수정을 더 쉽게 할 수 있다. 만약 알파벳 1글자로 사용하는 변수를 사용하려면, 메서드에서 로컬변수 혹은 Loop 의 변수 초기화 때만 사용하자. 해법 영역/문제 영역의 이름을 활용하자.  해법 영역은 컴퓨터 공학 분야를 이야기하는 것 같다. Visitor 패턴을 사용할 때는 AccountVisitor, Queue를 사용하면 JobQueue 같은 이름을 사용하자. 해법 영역에서 답을 못찾으면 구현하려는 Domain 영역에서 작명해보자. 구현에 관련된 작명. 인터페이스와 구현클래스 인터페이스와 구현 클래스 이름 중 인코딩 방식을 넣어야 한다면 구현 클래스를 추천한다.  인터페이스 : ShapeFactory 구현 : ShapeFactoryImpl 생성자 메서드  생성자를 중복정의 할때, 정적 팩토리 메서드를 사용하자. 메서드는 인수를 설명하는 이름을 사용하자. 생성자 : Complex fulcrumPoint = new Complex(23.0) 정적 메서드 : Complex fulcrumPoint = Complex.FromRealNumber(23.0); 마치며   사람들이 이름을 바꾸지 않으려는 이유 하나는 다른 개발자가 반대할까 두려워서다. 하지만 좋은 코드를 만드는 우리의 책임감이 있다면 일단 Nudge 부터 시작해야 한다. 

Clean Code - 제 3장. 주석

이미지
주석 결론 . 코드를 잘 만들면 주석을 적지 않아도 된다.   코드를 의도대로 표현하지 못해서 주석을 만드는 것이다. 표현력이 풍부한 코드는 존재 자체를 이해하기 쉽니다. 반대로 부족한 코드는 주석으로 설명이 필요하다. 그렇다면 좋은 코드를 만드는 편이 더 쉽고 빠른 개발 방법이 아닐까?   주석은 언제나 거짓말을 한다. 시간이 흐를수록 주석의 내용과 코드의 기능은 점점 멀어져간다. 프로그램은 비즈니스 요구에 따라 언제나 변한다. 이 변화를 주석에 계속해서 적는 것도 개발자의 몫인데, 과연 얼마나 많은 사람이 일관성 있게 유지할 수 있을까? 좋은 주석과 나쁜 주석 법적인 주석  저작권 등 법적인 이유로 회사나 팀이 정한 주석이 있다면 주석을 작성해야 한다. TODO 주석  아래와 같은 상황에서 작성할 수 있다. 당장 구현하기 어려운 업무를 기술 더 이상 필요 없는 기능을 삭제하는 알림. 누군가에게 문제를 봐달라는 요청. 더 좋은 이름을 제안해달라는 부탁. 앞으로 발생할 이벤트에 맞춰 수정 부탁. 소스 형상 관리 Tool.  소스 형상 관리 Tool을 잘 사용하면 나쁜 주석을 많이 피할 수 있다. 이력, 저자 같은 주석은 지우고 형상 관리 Tool을 사용하자.

Clean Code - 제 2장 함수.

이미지
함수 작게 만들어라.  함수를 작게 만들어서 좋아진다는 근거는 없지만, 저자의 경험 상 작은 함수가 좋다고 이야기 한다. 예시로는 함수의 Line 수가 2~4개로 설명하고 있다. 한 가지만 하라. 함수는 한가지를 해야 한다. 그 한가지를 잘해야 한다. 그 한가지만을 해야 한다.  함수 이름으로 여러가지 활동을 유추할 수 있다면, 그 활동을 다른 함수들로 쪼개는 작업을 해야 한다. 위에서 아래로 코드 읽기: 내려가기 규칙  내려가기 규칙을 제안한다. 한 함수의 다음 함수는 추상화 수준이 낮아져야 한다. 그러면 위에서 아래로 코드를 이야기처럼 이해할 수 있다. 서술적인 이름을 사용해라.  이름이 길어도 좋다. 비난 받아도 상관없다. 자세한 내용을 주석으로 사용하지 않을까? 서술적인 긴 이름이 주석보다 더 개발자들에게 쉽고 직관적으로 받아드린다. 길어도 좋은 이름을 선택하자. 반복하지 마라.  중복인 함수와 같은 작업하는 함수는 줄이자. 함수 작명법.  함수와 인수가 동사/명사 쌍을 이뤄야 한다. 예를들어 write(name)은 누구나 곧바로 이해한다. '이름' 이 무엇이든 '쓴다'는 뜻이다. 좀 더 나은 이름은 wirteField(name) 이다. 그러면 '이름'이 '필드'라는 사실이 분명히 드러난다. 오류 코드보다 예외를 사용해라 Try-Catch 문장을 하나의 메서드로 만들자. 오류 처리도 한가지 작업이기 때문에 오류 처리 함수는 오류만 처리한다.  함수인자  이상적인 함수 인자의 개수는 '0'개다. '0' 개로 만들기 위해 노력해라.  변환함수에서 입력/반환 인수. Stringbuffer transformer(StringBuffer in)  void transform(StringBuffer out)   저자는 1번을 추천한다. 변환 함수에서 출력 인수를 사용하면 혼란스러울 수 있다. 일반적으로 인수를 입력으로 해석한다. 상태를 변경해야 한다면 함수가 속한...

Algorithm과 함께 - Quick sort.

이미지
Quick Sort  Quick Sort는 빠른 Sort 중 하나로 매일 까먹어서 정리하기 위해 작성했다. 원리 QuickSort 정렬 원리  원리는 Pivot(=기준값)을 중심으로 작은 값과 큰 값을 바꾸는 방법로 정렬한다. 1차 정렬이 끝나면 정렬의 대상을 다시 분리한다.  Pivot 을 결정한다. 정렬한다. 2개로 쪼갠다. 다시 1번으로 돌아간다. 코드  그런데 정렬 갯수가 적어지면, Quick Sort 보다 일반 정렬이 더 빠르다. 그래서 Quicksort를 진행하는 Limitation을 줬다. package org . example . algorithm . sort . quicksort ; import java.util.Arrays ; import java.util.Random ; import java.util.Stack ; public class Quicksort { private static final int QUICKSORT_SORT_LIMIT = 10 ; static void swap ( int [] a , int idx1 , int idx2 ) { int t = a [ idx1 ]; a [ idx1 ] = a [ idx2 ]; a [ idx2 ] = t ; } // 퀸 정렬 static void quickSort ( int [] a ) { Stack < Integer > leftIndexStack = new Stack <>(); Stack < Integer > rightIndexStack = new Stack <>(); leftIndexStack . push ( 0 ); rightIndexStack . push ( a . length - 1 ); int ...

Clear Code - 서문

이미지
Clean Code - 서문  IT회사 신입들이 필독서 중 하나라는 이야기를 듣고, 늦었지만 이제부터 읽기 시작했다. 개인적으로 300 page 이상의 책을 별로 좋아하지 않지만 그래도 차근차근 chapter씩 정리할 예정이다.  Clean Code는 소통에서 시작한다.  이 책은 Clean Code를 위한 절대적인 지침서가 아니라는 전제를 밝힌다. 핵심은 팀이나 공동체가 합리적인 원칙을 세우기 위해 계속 소통해야 한다는 점이다.  유지보수 업무가 중요하다.  소프트웨어 업무의 80% 이상은 "유지보수"다. 좋은 소프트웨어를 처음부터 잘 만드는 것도 중요하지만, 계속될 유지보수 업무도 생각해야 한다. AI가 프로그래머를 대체할 수 없다.  코드는 절대 사라지지 않는다. 인간의 요구사항을 섬세하고 상세히 표현할 수 있는 수단은 프로그래머의 코드밖에 없다. 다음은 없다.  코드는 다시 반영 전보다 더 좋은 상태로 만들어야 한다. 시간에 쫓겨 대충 만들고 나중에 고치겠다는 마음은 버리자. 르블랑의 법칙처럼 나중은 없다. 좋은 코드를 책임지자.  빡센 일정과 터무니 없는 요구사항을 핑계로 Dirty Code를 만들지 말자. 요청자가 개발자들을 쪼아(?)가며 밀어붙이는 이유는 그들의 책임 때문이다. 그렇지만 좋은 코드를 사수하는 일도 프로그래머의 책임이다. 좋은 코드를 책임지기 위한 행동을 먼저 생각하자.  마무리...  서문부터 아주 뼈를 박살내는(?) 내용이 많다. 모두 내 이야기 같아 부끄럽고, 한편으로 시스템 관리업무의 중요성도 알려줘서 고맙기도 했다.

BigDecimal과 함께 - 정확한 숫자 계산을 Java로 구현하기

이미지
BigDeciaml With Java  이번 Post는 Java에서 금액을 저장할 때 사용하는 방법을 기록한다. 원시형(primitive) 변수로 저장하는 방법과 Java가 지원하는 Class를 정리한다. double/float  한국은 소수점 밑으로 금액이 없다. 그래서 int타입 변수로 처리하는 로직을 생각할 것이다. 하지만, 환산과 세율로 인해 소수점 곱셈이 발생하면 int타입으로는 해결할 수 없다. 그러면, 소수점을 지원하는 double과 float을 생각한다. 그런데 double과 float의 사칙연산 결과는 우리가 생각하는 것과 다르다. @Test public void 원시형 _ 사칙연산 () { double a = 0.1 ; double b = 0.2 ; double c = 0.3 ; // double 끼리 사칙연산. System . out . println ( a + b - c ); // 예상 : 0 / 결과 : 5.551115123125783E-17 System . out . println ( a * b * c ); // 예상 : 0.006 / 결과 : 0.006000000000000001 float d = 0.1f ; float e = 0.2f ; float f = 0.3f ; // float 끼리 사칙연산 System . out . println ( d + e - f ); // 예상 : 0 / 결과 : 0.0 System . out . println ( d * e * f ); // 예상 : 0.006 / 결과 : 0.0060000005 // 섞어서 사칙연산 System . out . println ( a + e - f ); // 예상 : 0 / 결과 : -8.940696738513054E-9 Sy...

JPA 와 함께 - 느낀점

이미지
Java Persistence API(JPA)  김영한님의 JPA 기초편 을 끝까지 수강했다. 작년부터 새벽에 짬내서 들었지만, 아이들의 방해(?)로 6개월 걸렸다. 듣고 많은 내용에 대해서 생각이 들었다. JPA 란?  자바 퍼시스턴스 API 이라 불리는 객체와 관계형 DB 를 관리하는 자바 API다. 2006년 1.0을 발표했으며 현재 2.1버젼까지 발전했다. Mybatis도 좋지만...  Mybatis로 Web개발을 하면, 마음 한켠이 찝찝(?)했다. 분명 Mybatis가 직관적으로 SQL을 관리해서 편하다. 하지만 점점 SQL 중심 개발로 진행할 수록, Spring의 역활에 의구심이 들었다. Web 서버, JSON 변환 외 비즈니스 로직은 점점 Mybatis 중심으로 만들어졌다.  그러다 객체설계 책을 접하고, Spring JPA를 알게 되었고, 유료 강의수강를 수강했다. Oracle Forms와 비교   가장 오래한 직업인 Oracle Forms 개발 관점에서 봤을 때, 비슷하면서 더 발전한 API라고 생각한다. 비슷한 점은 Primary Key 기준 CRUD Transaction 자동 실행과 부모-자식 관계 자동 설정이다.   더 발전한 API로 느낀 이유는 특정 DB를 위한 API가 아닌 범용 API라는 점이다. ANSI 표준 SQL과 Dialect로 DB Vendor별 차이를 좁히기도 한다. 그래서 개발자는 SQL보다는 객체에 좀더 집중할 수 있도록 도와준다. 객체지향으로 가는 길.  이제 비즈니스 로직을 객체에 자연스럽게 녹일 수 있다. 비즈니스 로직과 SQL 문장을 만들필요 없이 객체의 로직의 결과가 저장되어야 한다면 JPA를 사용하면 된다.  마치며... 홍보글은 아니지만, 꼭 듣기를 바란다. 이제 DB 없는 프로그램은 상상하기 힘들다. 객체와 DB설계 중 고민 하나를 덜어낼 수 있는 좋은 기회다. (물론 DB를 전혀 신경쓰지 않아도 되는 건 아니다.)

Oracle SQLDeveloper 성능 향상 방법 정리.

이미지
Oracle SQLDeveloper More Faster~!! SQLDeveloper  오라클에서 무료로 제공하는 DB 관리와 SQL 쿼리 기능을 가진 Tool이다. 좋은 Tool인데 처음 실행이 너무 느리다. 몇년간 봐왔지만 개선이 잘 안되는 것 같다. 이번 Post에서 성능 향상 방법 3가지와 도움되는 설정 2가지를 이야기한다. 시작시간 단축 1. Extension 끄기  최초 SQLDeveloper는 모든 기능이 활성화 되어있다. SQL 개발만 설정하기 위해서는 '도구 > 기능' 메뉴로 들어가 기능을 비활성화 시키자  Database 이전과 버젼제어 기능을 해지한다. Database 이전은 DB Vendor별 Migration을 지원한다. 버젼제어는 Git과 Subversion을 지원한다.  그리고 데이터베이스 옵션에서는 'Oracle OLAP'만 설정하자. 그러면 SQL 개발을 위한 기능들만 자동으로 설정된다. 2. IndexPreferencesTask 기능 Off.  이 기능이 성능하향의 주범(?)이다. 경험 상, 이 기능이 없어서 문제된 적이 없으니 사용하지 말자. 기능을 사용하지 않기 위해서는 실행 Option에 추가해야 한다. 경로는 아래와 같다. sqldeveloper폴더\sqldeveloper\bin\ sqldeveloper.conf  파일 내부에 아래 Option을 추가하자. AddVMOption -DIndexedPreferencesCommand = false 3. Window 테마로 변경  이론상 SQLDeveloper의 'Oracle' 테마는 '화면실행 > OS에 맞는 화면구성 > Oracle 테마 덧씌우기'라고 한다...

Finance와 함께 - Java로 구현하는 리스부채

이미지
Lease Accounting in Java  이번 Post는 2019년부터 적용한 회계법인 리스부채에 대한 이야기를 한다. 기본적인 원리와 등록예제를 설명한다. 리스부채  'K-IFRS 1116'가 도입되었다. 기존 사용권 자산(Righ-of-use assets, 이하 리스자산)은 비용 지불 분개만 기재하면 끝났다. 앞으로는 자산과 부채를 현재가치 금액으로 분개를 기재해야 한다.  리스 부채 분개  모든 리스자산를 등록하는 것이 아니다. USD 5,000 이하 또는 리스기간이 1년 이내인 리스거래는 비용만 처리해도 된다. 효과  리스효과에 대해서 부정적인 기사들이 많다. 부채나 이자비용이 높아져 회사운영에 나쁜 영향을 준다는 기사들이다. 사실 결과적으로 리스부채는 경제적 득실이 없다. 하지만 관리적인 측면이 크다. 빌린 자산을 비용으로 운영했을 때와 부채로 운영했을 때는 제무제표의 부채비율이 다르기 때문이다.  부채비율은 재무 건전성을 확인하는 지표다. 이 지표의 정확한 정보제공이 주주들의 의사결정에 영향을 끼치기 때문에 세분화시킬 필요가 있다. 그러므로 투자자는 이 항목을 잘 볼 필요가 있다. Java Lease Class Diagram LeaseContract.class  리스계약 정보를 가지고 있다. 기간, 이자율, 계약금액, LeaseSchedule의 정보를 가지고 있다. Lease Schedule과 연관관계를 맺기 위해 addSchedule()만 Public으로 선언했다. LeaseSchedule.class  리스회사에 지급할 계획정보를 가진다....

Scott 과 함께 - Cross Join 을 Java 로 구현하기

이미지
Cross Join in Java  이번 Post는 Cross Join을 Java로 구현한다. Cross Join은 조건없이 테이블 2개를 합치는 Join이다. 조건이 없다보니 데이터는 2개 테이블의 행 개수의 곱셈이다. 만약 A 테이블(2건)과 B 테이블(3건)을 Cross Join한다면, 행 개수는 2 x 3 = 6 이다.  그런데 궁금한 점은 이런 Join은 어디에 사용하는가? 개인적으로 집계 데이터의 Driving Table로 사용한다. Scott 도메인에서 예를 만든면, '모든 부서 x 모든 Job'의 급여평균을 구할 때 사용할 수 있다. 그래서 경험상 보면, Cross Join은 단독으로 사용하지 않고 Outer Join과 같이 사용한다. SQL with job as ( select distinct emp . job as job_name from emp ) select dept . dname , job . job_name , avg ( emp . sal ) from job cross join dept left outer join emp on ( job . job_name = emp . job and dept . deptno = emp . deptno ) group by dept . dname , job . job_name order by dept . dname , job . job_name    아래 그림처럼 부서에 Job이 없더라도 같은 형식을 유지하기 위해서 Cross Join을 사용한다. 여기서 알아야 할 이슈가 있는데, Cross Join으로 만들어진 Driving Table은 Index가 없기 때문에 Join에 대한 Cost가 높다. 그래서 Driving ...