Clean Code that Works.

이번에도 읽어 볼만한 글을 간단하게 번역해봤습니다.

http://javarevisited.blogspot.in/2014/05/how-string-in-switch-works-in-java-7.html


Java 7의 특징중에 하나로 Switch 구문에서 문자열을 사용할 수 있는데요.

이 원리에 대해서 설명한 내용입니다. :)


3줄 요약하면

1. Switch 에서 문자열을 사용했을 경우에 컴파일된 코드를 보면 hash code 와 equals() 를 사용해서 구분을 한것을 알 수 있다.

2. equals()를 사용해서 값을 확인을 한번 더 하기 때문에 숫자형이나 열거형을 사용했을경우 보다 연산이 +1 되고, 대소문자 문제 및 카멜표기법에 따른 문제 등이 발생한다.

3. 그러므로 문자열 보다는 숫자형이나 열거형을 사용하는 것이 좋고 열거형이 가독성과 코드 품질에 더 좋기 때문에 열거형을 사용하는 것이 좋다.


가볍게 읽어보세요 


------------------------------------------------------------------------------------------------------------------------------------------------


Java의 switch 구문에서 문자열을 사용할 수 있게 됨으로써 숫자형이나 열거형을 쓰는 것 보다 더 사용하기가 쉬어서 많은 프로그래머들이 이를 사용한다. 이 기능은 자동 리소스 관리 및 다중 오류 catch blocks 를 포함해서 JDK 7의 기능중에 가장 유명한 기능중 하나다. 


Java 프로그램에서 문자열을 사용함으로써 주는 한가지 편의점은 간단하게 사용할 수 있다는 것이다. 하지만 새로운 내용에 대한것을 실제 제품 코드에 적용하기전에 나는  이 내용에 대해 조금 더 알아보는것을 선호 한다. 내가 이 기능에 대해서 처음 알았을 때 equals() 와 hashcode()를 사용하면 switch에서 문자열 사용하기를 구현할 수 있을 거라는 생각이 들었다. 그래서 Java 7 에서 문자열이 어떻게 Switch 에서 사용할 수 있게 됬는지 관심을 가지게 됬다. 한가지 더 이슈는 Java 면접을 진행할 때 질문을 하기 위해서 였고, 이런 질문을 가지고 있는 면접이 좀 더 흥미롭게 진행 될 수 있다.(간단하지만 흥미로운 질문이긴 하네요)


테스트는 간단하다. 그냥 코드를 Switch 블럭에서 문자열로 작성하면 되고 이 코드들을 디컴파일 해서 컴파일러가 이 코드들을 어떻게 변환했는지 보면 된다. 


파일되기 전 코드

아래 코드는 main 메서드에 switch 블럭을 가지고 있고 문자열을 포함한 간단한 테스트 코드다. String 변수가 프로그램이 동작할시 제공된다. 아래 테스트 코드는 3가지 모드(Activce, Passive, Safe)를 가지고 있다. 


고정값을 사용할 경우에는 열거형을 사용하는게 더 좋지만 문자열을 사용하기로 결정했다면 소문자 및 카멜 표기법으로 변수를 표시했을때 문제가 발생할 수 있으므로 대문자로 작성 하도록 한다. 


/**

* Java Program to demonstrate how string in switch functionality is implemented in * Java SE 7 release. 

*/ 

public class StringInSwitchCase 

public static void main(String[] args) { 

String mode = args[0]; 

switch (mode) { 

case "ACTIVE": 

System.out.println("Application is running on Active mode"); 

break

case "PASSIVE": 

System.out.println("Application is running on Passive mode"); 

break

case "SAFE": 

System.out.println("Application is running on Safe mode"); 

}

}


JDK 1.7을 설치해서 컴파일하고 코드를 실행해본다. JDK 7 어느 버전에서든 동작 한다.


디컴파일 된 코드

아래 코드는 jdk 1.7.0_40 버전에서 컴파일된 소스를 디컴파일 한 것이다. 만약 당신이 자바를 처음 접하고 자바 클래스파일을 디컴파일에 리버스 엔지니어링을 어떻게 하는지 알고 싶다면 이 게시글을 참조하라. 


새로운 버전이 계속 나오면서 문섭들이 점점 더 편리해지고 쉬어 지기 때문(설탕 문법, syntactic sugar)에 이를 확실하게 알려면 모든 레벨의 자바 프로그래머들에게 클래스를 디컴파일하는 방법을 아는것은 매우 중요하다. 


/** * Reverse Engineered code to show how String in Switch works in Java. */ 

import java.io.PrintStream


public class StringInSwitchCase

public StringInSwitchCase() { } 

public static void main(string args[]) { 

String mode = args[0]; 

String s; 

switch ((s = mode).hashCode()) { 

default: break

case -74056953: 

if (s.equals("PASSIVE")) { 

System.out.println("Application is running on Passive mode"); 

}

break

case 2537357: 

if (s.equals("SAFE")) { 

System.out.println("Application is running on Safe mode"); 

} 

break

case 1925346054: 

if (s.equals("ACTIVE")) { 

System.out.println("Application is running on Active mode"); 

break

}

}


이 코드에서 문자열이 hashCode()와 equals() 메서드를 사용하는걸 볼 수 있다. 

JAVA 7 이전에 swich 구문에서는 byte, short, car 및 int 만 사용가능했던걸 되세겨보자. 


코드를 자세히 들여다 보면 swich는 해쉬 코드 와 eqauls()메서드를 통한 비교를 하고 있다. 이 검사는 꼭 필요한데 두개의 유니크한 오브젝트도 같은 hashcode 값을 가질 수 있다. 성능으로 따지면 열거형을 사용하는 것이나 숫자형을 사용하는 것 만큼 빠르지 않지만 모든 부분에서 아주 좋지 않은것은 아니다. 

자바 컴파일러는 문자열을 비교할때 매우 빠르게 할 수 있는 equals()를 사용한다.("abc" == "abc"). hashcode()메서드를 사용하는 경우에는 코드가 이미 생성되어 있기 때문에 1번더 추가적인 시간이 소모된다. 문자열은 그들의 hash code를 캐시한다. 그래서 이 코드가 hash code를 호출하는 비용은 크지 않을 것이다. 

그럼에도 불구하고 나는 여전히 Switch 에서 문자열을 사용하거나 고정된 숫자값을 사용하는것은 좋은 방법이 아니라고 본다. 자바는 이러한 이유때문에 열거형이라는 타입을 제공하고 모든 자바 프로그래머는 되도록 열거형을 사용하는 것이 좋다.


이게 Java 7의 Switch 구문에 문자열이 어떻게 동작하는지에 대한 것이다. 

예상했던 대로 전환을 하기 위해 hashCode()를 사용하고 검증을 하기 위해서 equals()를 사용한다. 이것은 문법적으로는 심플 하지만 오히려 기본 성능보단 느리다. 


결국 선택은 사용자의 몫이다. 나는 개인적으로 Switch 구문에서 문자열을 사용하는것(다루기 힘든 코드, 대소문자 문제, 값 검증을 위한 컴파일 시간 문제)에 대해 좋아하는 사람은 아니다.


사실 숫자 정수와 열거형 타입은 성능이 중요한 코드에서 내가 좋아 하는 방법이다. 가독성과 코드 품질이 더 중요하다.

실제로는 99.99%로 열거형을 쓰는게 문자열이나 숫자형을 사용하는 것보다 좋다. 

이전에 인덱스를 가지고 값을 찾을 때

findByPropertyValue()를 썼는데 이게 deprecated 됬다.


SDN 3 부터는 Scheme base 인덱스를 사용하는데.... 
findBySchemaPropertyValue() 이걸 사용하면 된다.


("파라미터로는 해당 모델(스키마)의 변수명", "찾을 값") 두개를 주면 되고 해당 변수에 @Indexed 가 붙어 있어야 된다.
@Indexed(unique=true)로 지정하게 되면 유니크 인덱스가 된다.

eBay and Wallmart Adopt Neo4j : The Graph is Transforming Retail

오늘(3월 18일) 이베이와 월마트같은 소매 유통 업체에서 Neo4j를 활용한 미션 크리티컬한 비즈니스 애플리케이션을 개발하여 큰 성공을 거두었다고 Neo4의 개발사인 Neo Technology에서 발표 했다. 이베이는 전 세계에 위치한 고객들에게 자사의 인기있는 서비스인 당일 배송 서비스를 개선하기 위해 Neo4j를 사용한다. 월마트는 온라인 쇼핑객 구매 행동을 분석하여 최적화된 연관 상품들을 제공하기 위해 Neo4j를 사용한다.

이베이는 대략 75% 소비가 고객의 집에서 15마일이내에서 발생한다는 것을 알고 지역 상권을 재정의 하는 대담한 목표를 가지고 있었다.  전자 상거래는 빠르고 편리하지만 배송은 불편했다. 당일 배송 시스템의 출현으로 지역 상업의 모든 행위가 마비될 것으로 보인다. 온라인 쇼핑과 오프라인 매장의 소비자 경험간의 융합은 소매 업체와 고객사이의 원할한 관계를 만들어 상거래 혁명을 일으키고 있다. 유연하고 빠르고 사용하기 쉽도록 하기 위해 Neo4j는 소매상과 온라인 고객사이의 가장 큰 방해물을 제거할 수 있도록 했다. 

이베이의 폭발적인 성장과 새로운 기능들로 인해 가능한 가장 빠르고 확실한 배송을 위해 이베이의 서비스 플랫폼을 새롭게 구성할 필요가 있었다. 이전 시스템인 MySQL은 너무 느리고 계속 유지하기엔 복잡하고 배송을 위한 최적의 경로를 찾는 쿼리의 수행시간이 너무 길었다. 이베이의 개발팀은 그래프데이터베이스가 성능과 확장에 대한 문제점을 해결하기 위해 기존의SOA 및 서비스 구조에 추가될 수 있다는 것을 알았다.  이 팀은 그래프데이터베이스 시장의 최적의 해결책인 Neo4j를 사용했다.

우린 말그대로 이전 MySQL보다 천배이상 빠르고 10~100번정도 적은 코드로 수행되는 Neo4j를 사용했다. 오늘날 Neo4j는 이전의 이베이에서는 불가능했던 기능들을 지원한다.

- Volker Pacher, Seniro Developer at eBay.


월마트 같은 대형 유통업체도 Neo4j를 사용한다. 과거에 소비자들은 마케팅 형태로 제조업체에서 제공하는 정보에 크게 의존했었다. 요즘은 소비자들이 생성한 제품에 관한 리뷰와 구매에 대해서 소셜 미디어에 상담하는 등 다른 정보를 가지고 있다. 소비자간의 정보의 풍요로움과  전문가의 의견에 따른 전에 없던 가용성은 소비자들을 좀 더 다양한 제품에 대한 경험을 가질수 있게 하고 그들이 사용하거나 소유하려고 고유하는 경향에 대하여 결정할 수 있게 해준다. 이렇게 서로 연결된 모든 데이터들을 이해하기 위하여 월마트는 Neo4j 그래프 데이터베이스를 사용한다.

"Neo4j는  우리가 이해하려고 했던 온라인 고객들의 성향과 고객 및 상품간의 관계에 대하여 실시간 상품 추천을 위한 완벽한 기능을 제공한다. 그래프 데이터베이스 시장의 선두주자이고 확장성과 가용성에 대한 고급 기능들을 제공하는 Neo4j는 우리들의 요구사항을 충족시키는 완벽한 제품이다."

- Marcos Wada, Software Developer at Walmart

그래프는 어디든지..그것은 바로 Neo4j

그래프는 산업 전반에 걸친 다루기 힘든 기술적인 문제에 대한 해결 방안으로 공공연하게 인정받고 있다. DB-Engines에 따르면 Neo4j는 가장 인기있는 그래프데이터베이스다.
firm에 따르면 "데이터베이스 관리 시스템중에 작년에 비해 자신의 인기가 가장 증가했는가 볼때 250% 증가한 그래프 데이터베이스는 명백한 승자라고 볼 수 있다."

이베이의 케이스 스터디는 http://www.neotechnology.com/ebay 을 참조.


이번에 만들어본 인터넷 차계부.

기존에 쓰던 차계부 어플이 너무 불편해서.. 그냥 모바일도 지원되는 버전으로 만들었다.

http://mycarcare.kr

PC, 태블릿 버전은 동일한 UI로 지원하고, 모바일 버전은 모바일 UI로 제공한다.