kth 개발자 세미나
2016년도 1회
h3
세미나 하는 이유
• SI 개발만 하는 각박한 분위기 좀 바꿔 보려고
세미나 하는 이유
• 소프트웨어 기술 발전 속도 -> 어마어마하게 빠르다
세미나 하는 이유
• 난 누군가 또 여긴 어딘가
• 빅데이터에 머신러닝을 함수형 언어로 분산처리 하면 되나요?
세미나 하는 이유
• 아무리 높은 초고층 빌딩도 기초공사부터 시작했습니다.
주제
• Java8
• OOP
진짜 주제
• 소프트웨어 설계에 만병통치약은 없다.
• 단점이 없는 아키텍처란 존재하지 않는다.
• Java-Spring 만 고집하지 말고 그때 그때 상황에 맞는 최선의 선택을 하자.
• 왜 다양한 언어를 꾸준히 배워야 하나?
• 디자인 패턴은 언어 종속적 = 언어마다 문제해결의 방식이 근본부터 다르다.
• Java 에 갇히면 생각도 갇힌다.
• OOP, 정말 제대로 이해하고 있나?
• OOP에서 가장 중요한 사상
• 상속도 아니고, 정보 은닉도 아니고, 추상화도 아니고, 캡슐화도 아니고
• 동적 바인딩 = 늦은 바인딩 = polymorphism 이게 제일로 중요하다.
진짜 진짜 주제
• 나는 Java가 싫어요!!
Java8 builder pattern
• 시작하기 전에…
• Builder pattern?
• Foo a = new FooBuilder().setA(111).setB(222).build();
• 등장인물 2명
• Foo class
• FooBuilder class
• 객체 하나 생성하려면 등장인물이 2명 필요합니다.
• 주인공 class
• 빌더 class
Java8 builder pattern
• 똑같은 builder 패턴이지만…
• GOF 의 builder 패턴 vs
• Java 언어만의 문법(inner class)를 사용한 builder 패턴 vs
• Java8 언어만의 문법(consumer / provider)를 사용한 builder 패턴
Example1.java
public class Example1 {
public static void main(String[] args) {
//Foo 객체를 생성하는 방법 1 : constructor 사용
Foo foo = new Foo("foo", "foo", "foo", "foo",
"foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo");
System.out.println(foo.toString());
//Foo 객체를 생성하는 방법 2 : setter 사용
Foo foo2 = new Foo();
foo2.setA("foo");
foo2.setB("foo");
foo2.setC("foo");
foo2.setD("foo");
// ...귀찮아서 생략
System.out.println(foo2.toString());
}
}
Example2.java
public class Example2 {
public static void main(String[] args) {
//FooBuilder classic GOF 방식
Foo foo = new FooBuilder().setA("foo").setB("foo").setC("foo").build();
//FooBuilder 를 java inner class로 정의
BuildableFoo foo2 = new BuildableFoo.fooBuilder().setA("fooA").
setB("fooB").
setC("fooC").
build();
System.out.println(foo.toString());
System.out.println(foo2.toString());
}
}
Functional interface 연습
@FunctionalInterface
public interface FunctionalFoo {
void foo();
}
@FunctionalInterface
public interface FunctionalFoo2 {
void foo(int foo);
}
@FunctionalInterface
public interface FunctionalFoo3 {
int foo();
}
public class Example0 {
public static void main(String[] args) {
//lambda 표현식을 assign 하려면 functional interface 가 필요
//lambda 표현식의 형태(파라미터, 리턴 타입 등)에 따라 functional interface 도
FunctionalFoo foo = ()->{System.out.println("foo!!");};
FunctionalFoo2 foo2 = (x)->{System.out.println(x);};
FunctionalFoo3 foo3 = ()->{return 100;};
foo.foo();
foo2.foo(777);
System.out.println(foo3.foo());
//function interface 는 예상할 수 있는 형태가 뻔합니다.
//java8 스펙에서 미리 만들어 놓은 interface를 사용해도 됩니다.
Consumer foo4 = (x)->{System.out.println(x);};
foo4.accept(666);
Supplier foo5 = ()->{return 666;};
System.out.println(foo5.get());
Predicate<String> alwaysTrue = (x)->true;
Predicate<String> alwaysFalse = (x)->false;
Predicate<String> isFoo = (x)->x=="foo";
System.out.println(alwaysTrue.and(alwaysFalse).test("foo"));
System.out.println(alwaysTrue.negate().test("foo"));
System.out.println(alwaysTrue.or(alwaysFalse).and(isFoo).test("foo"));
Function<String, Integer> foo7 = (x)->x.length();
Function<Integer, String> lengthToString = (x)->"length: "+x;
System.out.println(foo7.apply("hello foo!!!"));
System.out.println(foo7.andThen(lengthToString).apply("foo"));
}
}
@FunctionalInterface
public interface FunctionalFoo {
void foo();
}
@FunctionalInterface
public interface FunctionalFoo2 {
void foo(int foo);
}
@FunctionalInterface
public interface FunctionalFoo3 {
int foo();
}
Example3.java
public class Example3 {
public static void main(String[] args) {
Foo foo = GenericBuilder.of(Foo::new)
.with(Foo::setA, "fooA")
.with(Foo::setB, "fooB")
.with(Foo::setC, "fooC")
.build();
System.out.println(foo.toString());
}
}
동적 바인딩
• 동의어
• 동적 바인딩(Dynamic binding)
• =늦은 바인딩(late binding)
• OOP의 창시자 앨런 케이께서 말하길…
• 내게 있어 OOP란 모든 것(메세징, 지역성, 상태와 흐름에 대한 보호, 은
닉)에 대한 극단적(extreme)인 late binding 을 의미한다.
No Silver Bullet
• 만일 소프트웨어의 요구사항이 10개라면
• 그 소프트웨어의 복잡도는 아무리 줄여도 10개
• 최소한 10개의 기능은 반드시 구현을 해야 한다.
• 개발자 놈들이 싸지르는 똥 = 10개 + α
• + α 만 줄여도 성공하는 거다
동적 바인딩
class Bar {
void bark() {
System.out.println("Bar 멍멍멍");
}
}
class NewBar extends Bar {
@Override
void bark() {
System.out.println("NewBar 야옹야옹");
}
}
interface IBar {
void bark();
}
class DogBar implements IBar {
public void bark() {
System.out.println("DogBar 멍멍멍");
}
}
class CatBar implements IBar {
public void bark() {
System.out.println("CatBar 야옹");
}
}
public class Example4 {
public static void main(String[] args) throws Exception {
NewBar a = new NewBar();
//a.bark() 는 compile time에 무슨 일을 할 지 이미 결정
a.bark();
BufferedReader br = new BufferedReader(new InputStreamReader(System
String input = br.readLine();
Bar b = null;
if ("c".equals(input))
b = new NewBar();
else
b = new Bar();
//b.bark() 의 호출이 무슨 일을 할지 결정되지 않음
b.bark();
IBar c = null;
br = new BufferedReader(new InputStreamReader(System.in));
input = br.readLine();
if("c".equals(input))
c = new CatBar();
else
c = new DogBar();
//c.bark() 의 호출이 무슨 일을 할지 결정되지 않음
c.bark();
}
}
정적 바인딩 vs 동적 바인딩
if (open == 파일저장소) {
if(source == 엑셀) {
open엑셀from파일();
} else if (source == 워드) {
open워드from파일();
} else if (source == PPT) {
openPPTfrom파일();
}
} else if (open == 클라우드) {
if(source == 엑셀) {
open엑셀from클라우드();
} else if (source == 워드) {
open워드from클라우드();
} else if (source == PPT) {
openPPTfrom클라우드();
}
}
File foo;
AbstractFileFactory fooFactory;
if (open == 파일저장소)
fooFactory = new LocalFileFactory();
else if (open == 클라우드)
fooFactory = new CloudFileFactory();
if (source == 엑셀)
foo = fooFactory.create(엑셀);
else if (source == 워드)
foo = fooFileFactory.create(워드);
else if (source == PPT)
foo = fooFileFactory,create(PPT);
foo.open();
• 아직은 위력을 잘 모르겠지만…
정적 바인딩 vs 동적 바인딩
if (open == 파일저장소) {
if(source == 엑셀) {
open엑셀from파일();
} else if (source == 워드) {
open워드from파일();
} else if (source == PPT) {
openPPTfrom파일();
} else if (source == hwp) {
openHWPfrom파일();
}
} else if (open == kt클라우드) {
if(source == 엑셀) {
open엑셀from클라우드();
} else if (source == 워드) {
open워드from클라우드();
} else if (source == PPT) {
openPPTfrom클라우드();
} else if (source == hwp) {
openHWPfrom파일();
}
} else if (open == 기타 클라우드) {
if(source == 엑셀) {
open엑셀from클라우드();
} else if (source == 워드) {
open워드from클라우드();
} else if (source == PPT) {
openPPTfrom클라우드();
} else if (source == hwp) {
openHWPfrom파일();
}
}
• 요구사항 추가
• kt 클라우드 추가
• Hwp 포맷 추가
정적 바인딩 vs 동적 바인딩
File foo;
AbstractFileFactory fooFactory;
if (open == 파일저장소)
fooFactory = new LocalFileFactory();
else if (open == kt클라우드)
fooFactory = new KtCloudFileFactory();
else if (open == 클라우드)
fooFactory = new CloudFileFactory();
if (source == 엑셀)
foo = fooFactory.create(엑셀);
else if (source == 워드)
foo = fooFactory.create(워드);
else if (source == PPT)
foo = fooFactory,create(PPT);
else if (source == HWP)
foo = fooFactory,create(HWP);
foo.open();
• 요구사항 추가
• kt 클라우드 추가
• Hwp 포맷 추가
정적 바인딩 vs 동적 바인딩
File foo;
AbstractFileFactory fooFactory;
if (open == 파일저장소)
fooFactory = new LocalFileFactory();
else if (open == kt클라우드)
fooFactory = new KtCloudFileFactory();
else if (open == 클라우드)
fooFactory = new CloudFileFactory();
if (source == 엑셀)
foo = fooFactory.create(엑셀);
else if (source == 워드)
foo = fooFactory.create(워드);
else if (source == PPT)
foo = fooFactory,create(PPT);
else if (source == HWP)
foo = fooFactory,create(HWP);
foo.open();
VS
if (open == 파일저장소) {
if(source == 엑셀) {
open엑셀from파일();
} else if (source == 워드) {
open워드from파일();
} else if (source == PPT) {
openPPTfrom파일();
} else if (source == hwp) {
openHWPfrom파일();
}
} else if (open == kt클라우드) {
if(source == 엑셀) {
open엑셀fromKt클라우드();
} else if (source == 워드) {
open워드fromKt클라우드();
} else if (source == PPT) {
openPPTfromKt클라우드();
} else if (source == hwp) {
openHWPfrom파일();
}
} else if (open == 기타 클라우드) {
if(source == 엑셀) {
open엑셀from클라우드();
} else if (source == 워드) {
open워드from클라우드();
} else if (source == PPT) {
openPPTfrom클라우드();
} else if (source == hwp) {
openHWPfrom파일();
}
}
결론
• 디자인 패턴은 언어 종속적이다.
• OOP의 핵심은 동적 바인딩(=늦은 바인딩)이다.
• 나는 java가 싫어요.
질문?
감사합니다.

Kth개발자 세미나 1회

  • 1.
  • 2.
    세미나 하는 이유 •SI 개발만 하는 각박한 분위기 좀 바꿔 보려고
  • 3.
    세미나 하는 이유 •소프트웨어 기술 발전 속도 -> 어마어마하게 빠르다
  • 4.
    세미나 하는 이유 •난 누군가 또 여긴 어딘가 • 빅데이터에 머신러닝을 함수형 언어로 분산처리 하면 되나요?
  • 5.
    세미나 하는 이유 •아무리 높은 초고층 빌딩도 기초공사부터 시작했습니다.
  • 6.
  • 7.
    진짜 주제 • 소프트웨어설계에 만병통치약은 없다. • 단점이 없는 아키텍처란 존재하지 않는다. • Java-Spring 만 고집하지 말고 그때 그때 상황에 맞는 최선의 선택을 하자. • 왜 다양한 언어를 꾸준히 배워야 하나? • 디자인 패턴은 언어 종속적 = 언어마다 문제해결의 방식이 근본부터 다르다. • Java 에 갇히면 생각도 갇힌다. • OOP, 정말 제대로 이해하고 있나? • OOP에서 가장 중요한 사상 • 상속도 아니고, 정보 은닉도 아니고, 추상화도 아니고, 캡슐화도 아니고 • 동적 바인딩 = 늦은 바인딩 = polymorphism 이게 제일로 중요하다.
  • 8.
    진짜 진짜 주제 •나는 Java가 싫어요!!
  • 9.
    Java8 builder pattern •시작하기 전에… • Builder pattern? • Foo a = new FooBuilder().setA(111).setB(222).build(); • 등장인물 2명 • Foo class • FooBuilder class • 객체 하나 생성하려면 등장인물이 2명 필요합니다. • 주인공 class • 빌더 class
  • 10.
    Java8 builder pattern •똑같은 builder 패턴이지만… • GOF 의 builder 패턴 vs • Java 언어만의 문법(inner class)를 사용한 builder 패턴 vs • Java8 언어만의 문법(consumer / provider)를 사용한 builder 패턴
  • 11.
    Example1.java public class Example1{ public static void main(String[] args) { //Foo 객체를 생성하는 방법 1 : constructor 사용 Foo foo = new Foo("foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo"); System.out.println(foo.toString()); //Foo 객체를 생성하는 방법 2 : setter 사용 Foo foo2 = new Foo(); foo2.setA("foo"); foo2.setB("foo"); foo2.setC("foo"); foo2.setD("foo"); // ...귀찮아서 생략 System.out.println(foo2.toString()); } }
  • 12.
    Example2.java public class Example2{ public static void main(String[] args) { //FooBuilder classic GOF 방식 Foo foo = new FooBuilder().setA("foo").setB("foo").setC("foo").build(); //FooBuilder 를 java inner class로 정의 BuildableFoo foo2 = new BuildableFoo.fooBuilder().setA("fooA"). setB("fooB"). setC("fooC"). build(); System.out.println(foo.toString()); System.out.println(foo2.toString()); } }
  • 13.
    Functional interface 연습 @FunctionalInterface publicinterface FunctionalFoo { void foo(); } @FunctionalInterface public interface FunctionalFoo2 { void foo(int foo); } @FunctionalInterface public interface FunctionalFoo3 { int foo(); }
  • 14.
    public class Example0{ public static void main(String[] args) { //lambda 표현식을 assign 하려면 functional interface 가 필요 //lambda 표현식의 형태(파라미터, 리턴 타입 등)에 따라 functional interface 도 FunctionalFoo foo = ()->{System.out.println("foo!!");}; FunctionalFoo2 foo2 = (x)->{System.out.println(x);}; FunctionalFoo3 foo3 = ()->{return 100;}; foo.foo(); foo2.foo(777); System.out.println(foo3.foo()); //function interface 는 예상할 수 있는 형태가 뻔합니다. //java8 스펙에서 미리 만들어 놓은 interface를 사용해도 됩니다. Consumer foo4 = (x)->{System.out.println(x);}; foo4.accept(666); Supplier foo5 = ()->{return 666;}; System.out.println(foo5.get()); Predicate<String> alwaysTrue = (x)->true; Predicate<String> alwaysFalse = (x)->false; Predicate<String> isFoo = (x)->x=="foo"; System.out.println(alwaysTrue.and(alwaysFalse).test("foo")); System.out.println(alwaysTrue.negate().test("foo")); System.out.println(alwaysTrue.or(alwaysFalse).and(isFoo).test("foo")); Function<String, Integer> foo7 = (x)->x.length(); Function<Integer, String> lengthToString = (x)->"length: "+x; System.out.println(foo7.apply("hello foo!!!")); System.out.println(foo7.andThen(lengthToString).apply("foo")); } } @FunctionalInterface public interface FunctionalFoo { void foo(); } @FunctionalInterface public interface FunctionalFoo2 { void foo(int foo); } @FunctionalInterface public interface FunctionalFoo3 { int foo(); }
  • 15.
    Example3.java public class Example3{ public static void main(String[] args) { Foo foo = GenericBuilder.of(Foo::new) .with(Foo::setA, "fooA") .with(Foo::setB, "fooB") .with(Foo::setC, "fooC") .build(); System.out.println(foo.toString()); } }
  • 16.
    동적 바인딩 • 동의어 •동적 바인딩(Dynamic binding) • =늦은 바인딩(late binding) • OOP의 창시자 앨런 케이께서 말하길… • 내게 있어 OOP란 모든 것(메세징, 지역성, 상태와 흐름에 대한 보호, 은 닉)에 대한 극단적(extreme)인 late binding 을 의미한다.
  • 17.
    No Silver Bullet •만일 소프트웨어의 요구사항이 10개라면 • 그 소프트웨어의 복잡도는 아무리 줄여도 10개 • 최소한 10개의 기능은 반드시 구현을 해야 한다. • 개발자 놈들이 싸지르는 똥 = 10개 + α • + α 만 줄여도 성공하는 거다
  • 18.
    동적 바인딩 class Bar{ void bark() { System.out.println("Bar 멍멍멍"); } } class NewBar extends Bar { @Override void bark() { System.out.println("NewBar 야옹야옹"); } } interface IBar { void bark(); } class DogBar implements IBar { public void bark() { System.out.println("DogBar 멍멍멍"); } } class CatBar implements IBar { public void bark() { System.out.println("CatBar 야옹"); } } public class Example4 { public static void main(String[] args) throws Exception { NewBar a = new NewBar(); //a.bark() 는 compile time에 무슨 일을 할 지 이미 결정 a.bark(); BufferedReader br = new BufferedReader(new InputStreamReader(System String input = br.readLine(); Bar b = null; if ("c".equals(input)) b = new NewBar(); else b = new Bar(); //b.bark() 의 호출이 무슨 일을 할지 결정되지 않음 b.bark(); IBar c = null; br = new BufferedReader(new InputStreamReader(System.in)); input = br.readLine(); if("c".equals(input)) c = new CatBar(); else c = new DogBar(); //c.bark() 의 호출이 무슨 일을 할지 결정되지 않음 c.bark(); } }
  • 19.
    정적 바인딩 vs동적 바인딩 if (open == 파일저장소) { if(source == 엑셀) { open엑셀from파일(); } else if (source == 워드) { open워드from파일(); } else if (source == PPT) { openPPTfrom파일(); } } else if (open == 클라우드) { if(source == 엑셀) { open엑셀from클라우드(); } else if (source == 워드) { open워드from클라우드(); } else if (source == PPT) { openPPTfrom클라우드(); } } File foo; AbstractFileFactory fooFactory; if (open == 파일저장소) fooFactory = new LocalFileFactory(); else if (open == 클라우드) fooFactory = new CloudFileFactory(); if (source == 엑셀) foo = fooFactory.create(엑셀); else if (source == 워드) foo = fooFileFactory.create(워드); else if (source == PPT) foo = fooFileFactory,create(PPT); foo.open(); • 아직은 위력을 잘 모르겠지만…
  • 20.
    정적 바인딩 vs동적 바인딩 if (open == 파일저장소) { if(source == 엑셀) { open엑셀from파일(); } else if (source == 워드) { open워드from파일(); } else if (source == PPT) { openPPTfrom파일(); } else if (source == hwp) { openHWPfrom파일(); } } else if (open == kt클라우드) { if(source == 엑셀) { open엑셀from클라우드(); } else if (source == 워드) { open워드from클라우드(); } else if (source == PPT) { openPPTfrom클라우드(); } else if (source == hwp) { openHWPfrom파일(); } } else if (open == 기타 클라우드) { if(source == 엑셀) { open엑셀from클라우드(); } else if (source == 워드) { open워드from클라우드(); } else if (source == PPT) { openPPTfrom클라우드(); } else if (source == hwp) { openHWPfrom파일(); } } • 요구사항 추가 • kt 클라우드 추가 • Hwp 포맷 추가
  • 21.
    정적 바인딩 vs동적 바인딩 File foo; AbstractFileFactory fooFactory; if (open == 파일저장소) fooFactory = new LocalFileFactory(); else if (open == kt클라우드) fooFactory = new KtCloudFileFactory(); else if (open == 클라우드) fooFactory = new CloudFileFactory(); if (source == 엑셀) foo = fooFactory.create(엑셀); else if (source == 워드) foo = fooFactory.create(워드); else if (source == PPT) foo = fooFactory,create(PPT); else if (source == HWP) foo = fooFactory,create(HWP); foo.open(); • 요구사항 추가 • kt 클라우드 추가 • Hwp 포맷 추가
  • 22.
    정적 바인딩 vs동적 바인딩 File foo; AbstractFileFactory fooFactory; if (open == 파일저장소) fooFactory = new LocalFileFactory(); else if (open == kt클라우드) fooFactory = new KtCloudFileFactory(); else if (open == 클라우드) fooFactory = new CloudFileFactory(); if (source == 엑셀) foo = fooFactory.create(엑셀); else if (source == 워드) foo = fooFactory.create(워드); else if (source == PPT) foo = fooFactory,create(PPT); else if (source == HWP) foo = fooFactory,create(HWP); foo.open(); VS if (open == 파일저장소) { if(source == 엑셀) { open엑셀from파일(); } else if (source == 워드) { open워드from파일(); } else if (source == PPT) { openPPTfrom파일(); } else if (source == hwp) { openHWPfrom파일(); } } else if (open == kt클라우드) { if(source == 엑셀) { open엑셀fromKt클라우드(); } else if (source == 워드) { open워드fromKt클라우드(); } else if (source == PPT) { openPPTfromKt클라우드(); } else if (source == hwp) { openHWPfrom파일(); } } else if (open == 기타 클라우드) { if(source == 엑셀) { open엑셀from클라우드(); } else if (source == 워드) { open워드from클라우드(); } else if (source == PPT) { openPPTfrom클라우드(); } else if (source == hwp) { openHWPfrom파일(); } }
  • 23.
    결론 • 디자인 패턴은언어 종속적이다. • OOP의 핵심은 동적 바인딩(=늦은 바인딩)이다. • 나는 java가 싫어요.
  • 24.
  • 25.