본문 바로가기

JAVA8

헤비한 객체 Lazy하게 생성하여 사용하기

Functional Programming in JAVA8이라는 책을 공부하면서 실무에서 사용할 수 있는 패턴을 응용하여 사용해봤습니다.

 

대부분의 프로젝트에서는 아이디, 패스워드 등 입력값에 대한 Validation Check를 해야하는데요. 사용자의 요청마다 매번 Pattern 객체를 생성하여 입력값에 대한 Validation Check를 하는 것은 비효율적이라 생각하게 되었습니다.

Pattern 객체를 생성하려면 많은 리소스가 필요하기 때문이죠.

 

프로그램이 실행 될 때 단 하나의 인스턴스만을 생성한 후 사용 시 가져온다면 매번 객체를 생성하기 위한 리소스가 들지 않기 때문에 프로그램의 효율이 증가되지 않을까 하고 다음 코드를 작성해보았습니다.

 

	private Function<String, Pattern> pattern = regexp -> createAndCachePattern(regexp);
	
	PatternStore() {
		
	}
	
	public Pattern getPattern(String regexp) {
		return pattern.apply(regexp);
	}
		
	private synchronized Pattern createAndCachePattern(String regexp) {		

		class PatternFactory implements Function<String, Pattern> {

			private final Map<String, Pattern> store = new ConcurrentHashMap<String, Pattern>();
			@Override
			public Pattern apply(String regexp) {
				return store.computeIfAbsent(regexp, key->Pattern.compile(key));
			}
		}
		
		if(!PatternFactory.class.isInstance(pattern)) {
			pattern = new PatternFactory();
		}

		return pattern.apply(regexp);
	}

 

1. JAVA8에서 제공하는 Function이라는 함수형 인터페이스를 이용하여 추상메소드가 실행하고자 하는 람다식을 정의합니다.

2. getPattern이라는 함수가 호출될 때 createAndCachePattern 함수가 호출됩니다.

3. createAndCachePattern 함수는 동기화(synchronized) 처리했기 때문에 한 시점에 하나의 스레드만이 사용할 수 있습니다.

4. if 조건문을 통해 해당 참조변수의 인스턴스가 PatternFactory가 아니라면 PatternFactory 인스턴스를 생성 후 할당합니다.

5. PatternFactory의 apply 함수를 호출하여 Pattern 객체를 반환합니다.

6. 두번째 getPattern 메소드 호출 시 PatternFactory의 apply 메소드를 호출하여 동기화로 인한 레이스 컨디션이 발생하지 않으며 한번 생성하였던 객체를 다시 사용할 수 있습니다.   

 

출저 : Functional Programming in Java8