근래 배운 몇 가지 패턴 정리: Provider, Builder, Delegation

Provider

정확히 말하면 디자인 패턴은 아니라고 한다. 자세한 설명은 [1]에 있다. Factory 패턴과 유사하나 외부 설정에 따라 다른 객체를 생성하는 패턴을 칭한다. 나쁜 패턴이라며 [1]과 함께 Constructor Injection 같은 방법을 써야 한다는 주장이 있지만, 실제로 잘 작성된 오픈소스 프로젝트들에서도 이러한 구현을 꽤 많이 볼 수 있다.

Builder

생성자에 전달되어야 할 파라메터가 다양해서 골치 아픈 경우 Builder 패턴이 좋은 해결책이 된다. 방법은 Builder 객체를 만들고 setter 를 통해 필요한 파라메터를 설정 한 후에 build() 메소드 호출을 통해 실제 객체를 생성한다.


let storage = StorageBuilder.newBuilder()
.setURL("file:///tmp/test.csv")
.setType("csv")
.setFieldDelimiter(",")
.setLineDelimiter("\n")
.setEncoding("UTF-8")
.build();

view raw

builder.java

hosted with ❤ by GitHub

Delegation

처음 Delegation 패턴을 봤을 때는 Interface의 구현과 차이점을 잘 발견하지 못했었다. 위키 피디아에도 설명이 있지만 언제 써야 하는지가 설명되어 있지 않았다. [3] 에서 이유를 찾았는데. 요약을 해보면,

  • 원래 있는 객체의 동작을 그대로 유지하면서 동작의 앞뒤에 처리를 추가하고 싶을 때
  • 호환되지 않는 인터페이스를 위한 Proxy 를 구현할 때
  • 실제 구현 사용 시 복잡도가 높은 콜 루틴을 단순하게 제공하려고 할 때

경우에 따라 서브클래싱과 함께 쓸 수 있을 것 같으며 데코레이터 패턴에서 주로 나타나는 패턴인 것 같다.

See Also

[1] Provider Model Design Pattern and Specification, Part 1
[2] Provider is not a pattern
[3] http://stackoverflow.com/questions/7168714/what-is-the-purpose-of-a-delegation-pattern/7168737#7168737


Jni Native를 통한 Rust 함수 호출

회사 허락을 맡아 홀로 프로젝트를 하나 시작했다. 큰 그림은 일부 컴포넌트를 Rust로 구현하고 컴포넌트간 연결은 rpc로 하는 것인데 아직 Rust 로 rpc 구현을 하기에 시간이 더 필요하다. 임시적인 수단으로 JNI를 통해 기존 컴포넌트에 연결을 하려고 한다.

그 외 프로젝트에 자세한 이야기는 나중에 설명하고 위 목적으로 Stackoverflow 에서 참고하고 https://github.com/Monnoroch/RustJni 를 참고해서 JNI를 테스트를 해봤다.

C 바인딩이 쉬운것은 Rust의 장점 중 하나인데 JNI 바인딩 역시 순조로웠다. 방법은 우선 아래와 같이 native 함수 인터페이스를 작성하고


public class NativeInvoke {
public static native void procedure();
public static native void stringArg(String str);
public static native String returnString();
}

아래와 같이 Rust 코드를 작성하면 된다.


#![crate_type="dylib"]
#![feature(libc)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused_variables)]
extern crate libc;
extern crate jni;
use libc::c_void;
use std::ptr;
use jni::native::*;
use jni::helper::*;
#[no_mangle]
pub extern fn Java_org_github_hyunsik_NativeInvoke_procedure(jre: *mut JNIEnv,
class: *const c_void) {
println!("Invoked native method, jre: {:p}, class: {:p}", jre, class);
unsafe {
let v = ((**jre).GetVersion)(jre);
println!(">> version: {:?}", v);
}
}
#[no_mangle]
pub extern fn Java_org_github_hyunsik_NativeInvoke_stringArg(jre: *mut JNIEnv,
class: *const c_void, name: jstring) {
unsafe {
let string = ((**jre).GetStringUTFChars)(jre, name, ptr::null_mut());
println!("{}", chars_to_str(string));
((**jre).ReleaseStringUTFChars)(jre, name, string);
}
}
#[no_mangle]
pub extern fn Java_org_github_hyunsik_NativeInvoke_returnString(jre: *mut JNIEnv,
class: *const c_void) -> jstring {
unsafe {
return str_to_jstring(jre, "jni native");
}
}

view raw

lib.rs

hosted with ❤ by GitHub

이게 전부다. 위에서 사용된 chars_to_str와 str_to_jstring 는 아래 github repository에 있다.

https://github.com/hyunsik/jni-rs/blob/master/src/helper.rs

위 repository 는 https://github.com/Monnoroch/RustJni를 fork 해서 JNI 뿐 아니라 JNI 프로그램 작성 중에 반복되는 코드들에 대한 유틸리티 함수들을 추가할 계획이다.

그리고 아래는 JNI Native + Rust 를 위한 템플릿 프로젝트이다.

https://github.com/hyunsik/rust-jni-template


‘개발자가 보는 소프트웨어 교육의 오해와 진실, 그리고 미래’ 글에 대한 이견

개발자가 보는 소프트웨어 교육의 오해와 진실, 그리고 미래

링크한 글에 부분적으로 공감이 가기는 하지만 저는 꽤 다른 생각을 가지고 있습니다.

요약을 하면 링크의 글에서는 ‘직접적인 SW 개발을 위한 지식 습득’이 SW교육의 핵심이라고 주장하고 있습니다. 제 의견은 초중등 SW 교육에서 직접적인 SW 개발을 다루는 것은 불필요하다고 생각합니다. 덧붙이면 제가 생각하는 초중 SW 교육의 참의는 논리적인 사고나 알고리즘적 사고를 잘 가르치는 수단으로 SW가 활용되는 것이지 SW 개발에 목적이 있다고 생각하지 않습니다.

그 이유를 다음과 같습니다.

SW 개발을 위한 지식은 쉬이 변합니다
SW 개발 자체는 도메인 지식, SW 개발 방법론, 협업 도구, 프로그래밍 언어와 같은 응용의 말단 지식 (원론에서 먼)을 다수 요구하고 있으며 이러한 지식들은 10년 이상 단위로 보면 쉬이 변하는 영역입니다. 또한 SW 개발은 지식의 양적인 요구가 많거나 엔지니어링적인 요소가 많습니다. 이를 실제 현업에 종사하려면 10년 이상 걸리는 초중등 학생들이 배울 필요는 없습니다. 직접적인 SW 개발에 관심이 있는 친구들은 (글의 저자 설명과 같이) 인터넷 등 다른 수단을 통해 그때 그때 유망한 프로그래밍 언어나 방법론, 개발 도구들을 배우면 됩니다.

초중등 SW 교육이 SW 개발자를 만들기 위한 것이 아닙니다.
저자 분이 ‘모두 개발자가 될 필요는 없다’고 언급한 것 처럼 당연히 초중등 SW 교육이 SW 개발자를 만들기 위한 것이 아닙니다. 따라서 직접 결과물을 내기 위해 배워야 하는 SW 개발 지식(글에서 언급된 방법론, 협업 도구, 현업에서 쓰이는 언어) 에 시간을 들이는 것은 대다수의 초중등 학생들에게 사실 시간 낭비일 것이라고 생각합니다. 어린 학생들일 수록 가능성 많고 잠재력이 크기 때문에 (다른 말로 하면 미래에 어떤 분야에 종사하게 될지 모르기 때문에) 학생들 전체에게 좋은 영향을 줄 지식인 논리력, 알고리즘적 사고력을 키우는게 본질이 되어야 합니다. SW 통해 생각의 방법을 배우게 되면 예술, 인문, 철학, 과학, 공학 분야에 다양하게 적용될 수 있습니다.