리팩터링 정의 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법 여러가지 리팩터링 기법을 적용해서 소프트웨어를 재구성한다. 리팩터링하는 동안에는 코드가 항상 정상 작동하기 때문에 전체 작업이 끝나지 않아도 언제든 멈출 수 있다 누군가 "리팩터링하다가 코드가 깨져서 며칠이나 고생했다"라고 한다면, 리팩터링한 것이 아니다 두개의 모자 소프트웨어를 개발할 때 목적이 '기능 추가'냐, 아니면 '리팩터링' 이냐를 명확히 구분해 작업 기능을 추가할 때는 '기능 추가' 모자를 쓴 다음 기존 코드는 절대 건드리지 않고 새 기능을 추가하기만 한다. 리팩터링할 때는 '리팩터링' 모자를 쓴 다음 기능 추가는 절대 하지 않기로 다짐한 뒤 오로지 코드 재구성에만 전념한다...
Future의 단순 활용 비동기 계산을 모델링하는데 사용 Future는 계산이 끝났을 때 결과에 접근할 수 있는 참조를 제공 시간이 걸릴 수 있는 작업을 Future 내부로 설정하면 호출자 스레드가 결과를 기다리는 동안 다른 작업을 수행 Callable 객체 내부로 감싼 다음에 ExecutorService에 제출 ExecutorService executor = Executors.newCachedThreadPool();//스레드 풀 생성 Future future = executor.submit(new Callable() {//Callable을 스레드풀에 제출 public Double call() { return doSomeLongComputation();//시간이 오래걸리는 작업을 다른 스레드로 비동기 실..
리팩터링이란 겉으로 드러나는 코드의 기능은 바꾸지 않으면서 내부 구조를 개선하는 방식으로 소프트웨어 시스템을 수정하는 과정 버그가 생길 가능성을 최소로 줄이면서 코드를 정리하는 방법 리팩터링한다는 것은 코드를 작성하고 난 뒤에 설계를 개선하는 일 프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 위한 형태로 리팩터링 후 원하는 기능을 추가한다 리팩터링 전에 제대로 된 테스트부터 마련한다 테스트는 반드시 자가진단하도록 만든다 테스트를 작성하는데 시간이 좀 걸리지만, 신경써서 만들어두면 디버깅 시간이 줄어서 전체 작업 시간은 단축된다 리팩터링은 프로그램 수정을 작은 단계로 나눠 진행한다 그래서 중간에 실수하더라도 버그를 쉽게 찾을 수 있다 컴파일-테스트-커밋 간단한 수정이라도 ..
스레드와 높은 수준의 추상화 단일 CPU가 여러 사용자를 지원할 수 있는데 이는 운영체제가 각 사용자에 프로세스를 할당하기 때문 두 사용자가 자신만의 공간에 있다고 생각할 수 있도록 가상 주소 공간을 각 프로세스에 제공 운영체제는 주기적으로 번갈아가며 각 프로세스에 CPU를 할당함 프로세스는 운영체제에 한개 이상의 스레드로 같은 주소 공간을 공유하는 태스크를 동시에 실행 네 개의 코어를 가진 CPU에서 이론적으로는 병렬로 실행하여 실행 속도를 네배 향상시킬 수 있음 자바 스트림으로 병렬성을 달성 long sum = Arrays.stream(stats).parallel().sum(); 스트림을 이용해 스레드 사용 패턴을 추상화 Executor와 스레드 풀 Java 5는 Executor 프레임워크와 Thre..
Executor In Java, the Executor framework provides a simple and flexible interface for asynchronous task execution. It is part of the java.util.concurrent package and is commonly used to manage and control the execution of tasks concurrently. The primary interface in the Executor framework is the Executor interface, and there are several implementations available. Basic Usage of Executor import j..
EnumSet 키로 enum 상수를 사용 enum 상수를 기반으로 하므로 효율적으로 동작 키 집합이 고정되어 있으므로 메모리 사용이 효율적 키가 해당 enum의 상수와 일치하는 경우 비트 벡터로 구현되어 있어 공간 효율적 null 값을 허용하지 않는다 열거 순서(iterator order)는 해당 enum의 상수가 선언된 순서 enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } public static Day WEEKEND_DAY = EnumSet.of(SATURDAY, SUNDAY); EnumMap 키로 enum 상수를 사용 enum 상수를 기반으로 하므로, 키의 순서가 고정되어 있고 연속적 enum 상수를 사용할 때 ..
LocalDate 시간을 제외한 날짜를 표현하는 불변 객체 LocalDate date = LocalDate.of(2023,10,18);//2023-10-18 int year = date.getYear(); Month month = date.getMonth(); int day = date.getDayOfMonth(); DayOfWeek dow = date.getDayOfWeek(); //WEDNESDAY int len = date.lengthOfMonth();//31 (10월의 일수) boolean leap = date.isLeapYear();//false (윤년) TemporalField 시간 관련 객체에서 어떤 필드의 값에 접근할지 정의하는 인터페이스 ChronoField는 TemporalField 인..
익명 클래스를 람다 표현식으로 리펙토링 1. 익명 클래스에서 this는 익명클래스 자신을 가리키지만 람다에서 this는 람다를 감싸는 클래스를 가리킨다. 2. 람다에서 감싸는 클래스의 변수를 가릴 수 없다. int a = 10; Runnable r1 = () -> { int a = 2;// Conmpile Error }; Runnable r2 = new Runnable() { public void run() { int a = 2;// Success } }; 3. 익명 클래스는 인스턴화할 때 명시적으로 형식이 정해지지만 람다의 형식은 콘텍스트에 따라 달라진다. interface Task { public void execute(); } public static void doSomething(Runnable ..
What? Java 객체를 JSON으로 Serialize 할 때, API Request, Response 으로 JSON 으로 변환 할 때, DTO 객체를 Mybatis 에 전달할 때 등등 boolean 타입 필드명의 'is' 가 누락되는 현상 @Getter @Setter public class Car { private boolean isElectronic; } // {"electronic":false} Why? Lombok의 @Getter를 사용하게 되면 boolean 필드는 getter 메소드가 아니라 is 메소드를 생성 (getIsElectronic 이 아닌 isElectronic) is로 시작하는 필드명은 is가 중복되지 않고 생성 (isIsElectronic 이 아닌 isElectronic) @G..