이번 장에서는 한 차원 높은 단계의 캡슐화를 다루는데,

바로 메소드 호출을 캡슐화하는 것이다. 


이를 활용해서 스케줄링, 로그 기록 시스템을 디자인할 수도 있고

취소(undo) 기능을 구현하기 위해 재사용할 수도 있다.


* Command Pattern :

요구 사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구 사항을 집어넣을 수도 있다.

또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있고 작업 취소 기능도 지원이 가능하다.

요청을 하는 객체그 요청을 수행하는 객체를 분리하고 싶다면 이 패턴을 사용하자!



Command 패턴을 이해하기 위해 간단하게 예를 들어보겠다.

다음의 그림은 식당에서 클라이언트의 주문이 실제 수행되는 과정이다.

(출처 : http://www.prayer-laputa.com/blog/archives/370)


웨이트리스는 클라이언트로부터 주문(Order)를 받아 - takeOrder()

주방장에게 그 주문을 전달해준다. - orderUp()

그러면 주방장은 주문서에 따라서 음식을 준비할 것이다. - make...()


여기서 주문서가 주문한 메뉴를 캡슐화 한다는 것을 숙지하자.


그리고 위 그림을 읽는 방법을 설명하자면

1) Client 는 Order 의 createOrder() 를 호출.

2) Order 는 웨이트리스의 takeOrder() 를 호출.

3) 웨이트리스는 Order 의 orderUp() 을 호출.

4) Order 는 주방장의 make...() 을 호출.

- 3) 이 이해가 잘 안 갈 수도 있지만 너무 신경안써도 된다. 흐름만 이해하자.



위 그림을 어느 정도 이해한 다음에

Command 패턴 다이어그램으로 넘어가보자.


위에서 보았던 다이어그램과 매우 유사하다는 것을 느낄 수 있다.


이해를 위해 설명을 하자면,

① Client 는 Command 객체를 생성한다.

② Invoker 에 ① 에서 생성한 Command 객체를 저장하기 위해 Client 는 setCommand() 를 호출한다.

③ 차후 Client 는 Invoker 에게 그 Command 객체를 실행시켜달라고 요청한다.




- Command 패턴의 흐름을 이해했다면 예제 코드로 넘어간다.

책에서는 가정 내에서 사용하는 전자제품들을 컨트롤할 수 있는 리모컨 API 를 디자인하는 예를 들었다.

아래 Class Diagram 안 보이면 Click.

(참고로 나는 리모컨에 Undo 기능이 있는 건 처음본다)


Client :

Concrete Command 를 생성하고 Receiver를 설정한다.


- Invoker :

Command 들을 관리하고 있고 Command 의 execute() 를 호출해서 Command 객체에게

특정 작업을 수행해 달라고 요청을 한다.


- Command :

모든 Command 객체에서 구현되어야 하는 인터페이스.


- Concrete Command :

execute() 에서 Receiver 에 있는 Action 들을 호출해 요청받은 작업을 수행하도록 한다.

undo() 의 예를 들면, LightOnCommand 의 경우 undo() 의 내용은 light.off() 정도 될 것이다.


- Receiver :

요구 사항을 처리하기 위해 어떤 일을 수행해야 하는지 알고 있다.


- Macro Command :

여러 Command 들을 한번에 실행시킬 수 있는 새로운 종류의 Command. 

아래의 예제 코드를 보자.

public class MacroCommand implements Command {
    Command[] commands;
    public MacroCommand(Command[] commands){
        this.commands = commands;
    }
    public void execute() {
        for ( int i=0; i < commands.length; i++ ){
            commands[i].execute();
        }
    }
}

- Null 객체 :

Client 에서 따로 null 처리를 하지 않아도 되도록 만들어 놓은 객체.

execute(), undo() 모두 아무 일도 하지 않는다. 여러 디자인 패턴에서 유용하게 쓰인다고 한다.

public void onButtonWasPushed(int slot) {
    if ( onCommands[slot] != null ) {
         onCommands[slot].execute(); 
    }
}

Null 객체를 활용하면 클라이언트는 위의 코드처럼 작성할 필요가 없게된다.



Invoker 인 RemoteControl 클래스의 코드를 자세히 알고 싶다면 

이 포스팅 글 상단에 걸어놓은 링크를 따라가면 된다. 중국어의 압박이 있긴하지만 코드는 읽을 수 있으니까.



* Command 패턴 활용 :

(1) 요청을 Command 객체에 캡슐화해서 작업 큐(Queue) 에 저장하기

큐의 한쪽은 커맨드를 추가, 다른 한쪽은 커맨드를 처리하기 위한 스레드(Thread)들이 대기하고 있다고 하자.

각 스레드에서는 우선 커맨드의 execute() 메소드를 호출하고, 이 작업을 완료하면 커맨드 객체를

보내버리고 새로운 커맨드 객체를 가져오는 작업을 하게 된다.


위와 같은 방법으로 스케줄러, 스레드 풀, 웹 서버 등에 활용할 수 있다.


(2) 요청을 로그(Log)에 기록하기

어떤 애플리케이션에서는 모든 행동을 기록해놨다가 그 애플리케이션이 다운되었을 경우,

나중에 그 행동들을 다시 호출해서 복구를 할 수 있도록 해야 한다.

이를 위해 Command 인터페이스에 execute(), undo() 이외에 store(), load() 를 추가하자.


어떤 명령을 실행하면서 디스크에 실행 히스토리를 기록해 애플리케이션이 다운되면

커맨드 객체를 다시 로딩하고 execute() 메소드들을 자동으로 순서대로 실행하면 된다.


매번 저장하기 힘든 경우에는 마지막 체크 포인트 이후로 한 모든 작업을 저장한 다음에

다운되었을 때 기존 체크 포인트에 최근 수행된 작업을 다시 적용하는 방법을 사용하면 된다.


위와 같은 테크닉을 확장해서 DB의 트랜잭션을 활용해 commit, rollback 연산을 구현할 수 있을 것이다.



* 객체지향의 원칙 :

1) 바뀌는 부분은 캡슐화 한다.

2) 상속보다는 구성을 활용한다.

3) 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

4) 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

5) 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다(OCP).

6) 추상화된 것에 의존해라. 구상 클래스에 의존해서는 안 된다(의존성 뒤집기 법칙).



* 이 장에서의 정리 :

- Command 패턴을 이용하면 요청을 하는 객체와 그 요청을 수행하는 객체를 분리할 수 있다.

- 또한 작업 취소(Undo) 기능을 지원할 수 있고, 로그나 트랜잭션 시스템 구현에도 활용된다.

- Command 객체는 Action 을 수행하는 Receiver 를 캡슐화 한다.

- Command 객체의 execute() 는 Receiver 의 Action 을 호출한다.

- Macro Command 는 여러 개의 Command 를 한꺼번에 호출할 수 있게 해주는 간단한 방법이다.

Macro Command 에서도 어렵지 않게 Undo() 기능을 지원할 수 있다.


by kelicia 2014. 5. 21. 20:46

* JAVA 의 접근 제어자 (Access Modifier)

- public : 

모든 클래스들이 접근 가능.

- protected : 

같은 패키지 내에 있거나 또는 상속받은 경우에만 접근 가능.

- package-private : 

아무런 접근 제어자를 명시해주지 않는 경우에 해당. 

같은 패키지 내에 있을 때만 접근 가능. (참고로 나는 default 제어자로 알고 있었다)

- private :

해당 클래스 내에서만 접근 가능.



* 클래스 접근 제어자 선언할 때 유의할 점

- 자바에서는 1개의 .java 파일 안에 여러 개의 클래스를 선언할 수 있다.

PublicClass.java

package test;
class PublicClass {
    public static void main(String[] args){
    }
}
class PublicSecondClass {
}

위의 코드 처럼 작성이 가능하고 컴파일도 정상적으로 된다.


package test;
public class PublicClass {
    public static void main(String[] args){
    }
}
class PublicSecondClass {
}

위 코드도 마찬가지이다.


하지만 아래의 경우 에러가 발생한다.

package test;
class PublicClass {
    public static void main(String[] args){
    }
}
public class PublicSecondClass {    // error
}


결국 3가지 코드를 통해 말하고자 하는 바는,

public 으로 선언된 클래스가 파일 내에 있다면

그 소스코드 파일의 이름은 public 인 클래스의 이름과 동일해야만 한다는 점이다.




* 오버라이딩 (Overriding) : 상속과 관련.

- 부모 클래스의 메소드를 자식인 자신의 클래스 내에서 재정의한다.

- 접근 제어자, 리턴 타입, 메소드 이름, 매개 변수 타입 및 갯수가 모두 동일.

- 단! 접근 제어자는 부모 클래스의 메소드와 반드시 동일할 필요는 없으나 접근 권한이 확장되는 경우만 가능하다.

(접근 권한 : public > protected > package-private > private)


예를 들어 부모 클래스의 메소드 접근 제어자가 public 일 때,

자식 클래스의 메소드 접근 제어자가 private 인 경우는 접근 권한이 축소된 경우라서 컴파일 에러.



* 오버로딩 (Overloading) : 한 클래스 내에서.

- 메소드 이름은 동일하되 매개 변수만 다르게 하는 것.

- 반환 타입은 상관 없다. 중요한 건 같은 메소드 이름, 매개 변수가 들어가는 '()' 안의 내용이다.


public int add(int x, int y) { }
public double add(double x, double y) { }
public void print(int intData, long longData, String strData) { }
public void print(int intData, String strData) { }
public void print(String strData, int intData) { }


위 코드 라인 4, 5와 같이 타입의 순서가 달라도 다른 메소드 처럼 인식된다는 점.


by kelicia 2014. 5. 21. 03:33

- 이번 장의 특성상 따로 Diagram 을 생성하지 않았다. 그리고 책 내용에 좀 더 충실하게 포스팅해봤다. -


* Singleton Pattern

해당 클래스의 인스턴스가 오직 하나 만들어지고,

어디서든지 그 인스턴스에 전역 접근할 수 있도록 하기 위한 패턴이다.


- 어떤 상황에서 사용될까?

스레드풀이라든가 캐시, 대화상자, 사용자 설정 또는 레지스트리 설정을 처리하는 객체,

로그 기록용 객체, 프린터나 크래픽 카드 같은 디바이스를 위한 디바이스 드라이버 같은 걸 예로 들 수 있다.

이런 상황에서 2개 이상의 인스턴스를 만들게 된다면, 프로그램이 이상하게 돌아간다든가

자원을 불필요하게 잡아먹는다든가 일관성 없는 결과를 초래할 수 있다.


- 전역변수(Global Variable)도 방법이 될 수 있지 않나?

전역변수에 객체를 대입하면 애플리케이션이 시작될 때 객체가 생성될 것이다.

그런데 여기서 그 객체가 자원을 많이 차지한다고 가정했을 때, 그 객체가 애플리케이션 종료 시까지

한 번도 사용되지 않는다면 괜히 자원만 잡아먹는 쓸데없는 녀석이 될 수 있다.

Singleton 패턴의 경우에는 필요할 때만 객체를 생성할 수가 있다.



< 고전적인 구현법 >

public class Singleton {
    private static Singleton uniqueInstance;
    private Singleton() { }
    public static Single getInstance() {
        if ( uniqueInstance == null ) {
            // 인스턴스가 필요한 상황이 닥치기 전에는 아예 인스턴스를 생성하지 않는다.
            // 이 기법을 '게으른 인스턴스 생성(Lazy instantiation)' 이라 한다.
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

클래스의 객체가 자원을 많이 잡아먹는 경우에는 위와 같이 '게으른 인스턴스 생성' 기법이 꽤 유용하다.

위 코드를 읽을 때는 접근한정자와 static 키워드를 주의깊게 읽자.



하지만 주의해야 할 점이 있다. 

* 고전적인 방법이 다중 스레드 환경에서도 아무 문제 없을까?


1번 스레드 

2번 스레드 

uniqueInstance 값 

 public static Single getInstance() {

 

null

  public static Single getInstance() {

 

  if ( uniqueInstance == null ) {

 

 

   if ( uniqueInstance == null ) {

 

   uniqueInstance = new Singleton();

 

object 1 

   return uniqueInstance;

 

 

    uniqueInstance = new Singleton(); 

object 2

 

   return uniqueInstance;

 


위의 경우, 객체가 2 개가 만들어져 Singleton 의 의미가 없어지는 문제가 발생한다.

어떻게 해야할까?

public static synchronized Singleton getInstance() {
    if ( uniqueInstance == null ) {
        uniqueInstance = new Singleton();
    }
    return uniqueInstance;
}

synchronized 키워드를 추가하면, 한 스레드가 사용을 끝내기 전까지 다른 스레드는 기다려야 한다. 

다시 말해서 2개 이상의 스레드가 동시에 실행시키는 일은 발생하지 않는다.

그러나 ! !

책에 의하면... 메소드를 동기화하면 성능이 100배 정도 저하된다는 것은 기억하라고 한다.



* Singleton 패턴에서의 3 가지 해법 :

(1) getInstance() 의 속도 이슈가 그렇게 중요하지 않다면 그냥 동기화를 해도 된다.

- 애플리케이션에 큰 부담을 주지 않는다면 바로 위의 코드처럼 놔둬도 된다.

(2) 인스턴스를 필요할 때 생성하지 말고 처음부터 만들어 버린다.

- 애플리케이션에서 반드시 Singleton의 인스턴스를 생성하고 항상 사용한다면 or

 인스턴스를 실행중에 수시로 만들고 관리하기 성가시다면 정적으로 초기화 해버린다.

 이 방법은 JVM 에서 유일한 인스턴스를 생성하기 전까진 그 어떤 스레드도 uniqueInstance 에 접근 불가.

public class Singleton {
    private static Singleton uniqueInstance = new Singleton();
    private Singleton() { }
    public static Singleton getInstance() { return uniqueInstance; }
}

(3) DCL(Double-Checking Locking) 을 써서 getInstance() 에서 동기화되는 부분을 줄인다.

- 인스턴스가 생성되어 있는지 확인한 다음, null 인 경우만 동기화 할 수 있기때문에

 처음에만 동기화를 하고 이후에는 동기화하지 않아도 된다. 

 이 방법으로 오버헤드를 극적으로 줄여 속도를 향상시킬 수 있다. 

- volatile 키워드를 사용하면 다중 스레딩을 쓰더라도 uniqueInstance = new Singleton(); 의 과정이

 올바르게 진행될 수 있다.

public class Singleton {
    private volatile static Singleton uniqueInstance;
    private Singleton() { }
    public static Singleton getInstance() { 
        if ( uniqueInstance == null ) {
            synchronized ( Singleton.class ) {
                if ( uniqueInstance == null ) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance; 
    }
}

단, (3) 방법은 자바 1.4 이전 버전에는 사용할 수 없다고는 하나 

현재 14.05.20 기준으로는 버전 1.8 까지 나왔으니 크게 염려할 필요는 없지않나 싶다.


3가지 방법 모두가 다중 스레딩 환경에서 발생하는 문제를 해결할 수 있다.

하지만 속도 이슈와 자원 문제, 구현 시나리오를 염려해두면서 적절한 해법을 선택하도록 하자.



* 객체지향의 원칙 :

1) 바뀌는 부분은 캡슐화 한다.

2) 상속보다는 구성을 활용한다.

3) 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

4) 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

5) 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다(OCP).

6) 추상화된 것에 의존해라. 구상 클래스에 의존해서는 안 된다(의존성 뒤집기 법칙).



이 장에서의 정리 :

- 어떤 클래스에 Singleton 패턴을 적용하면 애플리케이션에 그 클래스의 인스턴스가

 최대 1개까지만 있도록 할 수 있다. 또한 그 유일한 인스턴스에 전역 접근할 수 있다.

- 사실 모든 애플리케이션은 다중 스레딩을 쓸 수 있다고 생각해야하기 때문에 고전적인 구현은 되도록 피하자.

- 클래스 로더가 여러 개 있으면 싱글턴이 제대로 작동하지 않고 여러 개의 인스턴스가 생길 수 있다.

 (클래스 로더마다 서로 다른 네임스페이스를 정의하기 때문이다. 

 클래스 로더가 2개 이상일 때, 각 클래스 로더마다 한번씩 같은 클래스를 여러 번 로딩할 수도 있다. 

 그러니 클래스 로더를 직접 지정해서 이 문제를 피할 수 있다고 한다.)


※ 사실 클래스 로더가 뭔지 잘 모르겠다.


by kelicia 2014. 5. 20. 00:33

IT블로그를 운영하다보면 필연적으로 포스팅하다가 코드를 삽입하게 된다.
하지만 예쁘게 삽입되지 않는 안습...이 있다 ㅠ_ㅠ

그렇다고 예쁘게 코드 넣겠다고 개발툴 열어서 코딩하고 캡쳐해서
올리는 것도 은근 불편하다. 그냥 코드 몇줄만 넣으면 되는 일을 ! !

그래서 이를 해결하기 위해 조금 찾아보니
Google Code Project 에서 제작한 툴 'SyntaxHighlighter' 라는 녀석을 발견.
각 개발 랭귀지별로 .js 파일이 마구 있다보니-_-;; 약간 느리다는 단점이 있다.
(역시... 기능이 많을수록 무거울 수 밖에)

아무튼 이를 티스토리 블로그 기준으로 잘 적용시킬 수 있도록
자세한 방법을 포스팅해주신 친절한 분을 발견!
적용이 생각보다 까다롭다ㅡ_ㅡ.....

Tistory 설치방법, 사용법 : http://jb-story.tistory.com/13

기타 팁, 사용법 : http://snowple.tistory.com/267



지금 공부하다가 갑자기 생각나서_-_ 결국 이렇게 딴짓을..

이따가 설치해봐야겠다 !


왜 이건 태터툴즈 플러그인에 따로 없는 건지ㅡ_ㅡ.. 구글꺼라 그런가?


구글 코드 프로젝트 쪽 링크는 http://code.google.com/p/syntaxhighlighter/

(참조링크 추가 : https://code.google.com/p/sh4tistory/)



영문 메뉴얼 : 테마, 사용언어, 설정

http://alexgorbatchev.com/SyntaxHighlighter/manual/themes/

http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/

http://alexgorbatchev.com/SyntaxHighlighter/manual/configuration/



+ 설치 결과 테스트


<pre name="code" class="brush:원하는 언어;"> 
    에디터 모드에서 이 사이에 코드를 작성하면 된다.
</pre>

 
// this is JAVA
public class Test(){
    public static void main(String[] args){
        System.out.println("Hello World!");
    }
}


'Etc.' 카테고리의 다른 글

[유용TIP]포토샵 CS5 단축키 모음  (0) 2014.04.23
by kelicia 2014. 5. 19. 16:12

- 예제 코드 Diagram -



* Factory Method Pattern :

객체를 생성하기 위한 인터페이스를 만든다. 

어떤 클래스의 인스턴스를 만드는 것을 서브클래스에서 결정하도록 한다. 

이 패턴을 이용하면 인스턴스를 만드는 일을 서브클래스에게 맡길 수 있다.



아래 그림을 참고해서 위의 그림을 설명하자면,

(출처 : http://www.cnblogs.com/zhuqiang/archive/2012/05/05/2484930.html )

Pizza 라는 추상 클래스(or 인터페이스)는 Product, 이를 상속받은 피자들이 Concrete Product.

PizzaStore 라는 추상 클래스(or 인터페이스)Creator, 이를 상속받은 체인점들이 ConcreteCreator 에 해당된다.

그리고 createPizza() 라는 메소드는 factoryMethod() 에 해당된다.


PizzaStore 는 생산자로서 Pizza 를 생산할 뿐이지 실질적으로 어떤 피자가 만들어질 지는 전혀 모른다.

(여기서 PizzaStore 는 클라이언트 코드다)

실질적으로 어떤 피자가 만들어질 지는 Pizza 의 서브클래스에 따라 결정이 된다.



* 의존성 뒤집기 원칙 (Dependency Inversion Principle) :

- 추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하지 않도록 만들어야한다.

- 이를 지키는 데 도움이 될만한 3가지 가이드 라인

. 어떤 변수에도 구상 클래스에 대한 레퍼런스를 저장하지 않는다.

. 구상 클래스에서 유도된 클래스를 만들지 않는다.

. Base 클래스에 이미 구현되어 있는, 모든 서브클래스에서 공유하는 메소드를 오버라이드하지 않는다.

 


* Abstract Factory Pattern :

서로 연관된, 또는 의존적인 객체들로 이루어진 제품군(Product Family)을 생성하기 위한 인터페이스를 제공한다.

구상 클래스는 서브클래스에 의해 만들어진다.

예제의 NYPizzaStore 클래스의 createPizza() 코드 中

Pizza pizza = null;

PizzaIngredientFactory inredientFactory = new NYPizzaIngredientFactory();

pizza = new CheesePizza(ingredientFactory);


PizzaIngredientFactory 가 위 그림의 Abstract Factory, NYPizzaIngredientFactory 가 Concrete Factory,

NYPizzaStore 가 Client 에 해당한다.


그 외에 Abstract Product A 는 피자 도우 정도 되고

그 하위의 Product A1, A2 는 각각 얇은 도우, 두꺼운 도우 정도라고 생각하면 된다.

마찬가지로 Abstract Product B 도 치즈 정도에 해당, Product B1, B2 는 모짜렐라 치즈 등에 해당된다.


Concrete Factory 1 에서는 Product A1, B1 을 제품군으로 이루고 있고,

Concrete Factory 2 에서는 Product A2, B2 를 제품군으로 이루고 있다.


그리고 위 그림의 Factory 가 생산자(Creator)라고 생각하면 

Abstract Factory 패턴에서는 Factory Method 패턴이 쓰이는 걸 볼 수 있다.



* Factory Method Abstract Factory

- 공통점

서브클래스를 통해서 객체를 만듦으로서 클라이언트(PizzaStore) 에서는

자신이 사용할 추상 형식(Pizza)만 알면 되고, Concrete 형식은 서브클래스에서 처리해준다.

즉, 클라이언트와 Concrete 형식을 분리시켜주는 역할을 한다.

객체 생성을 캡슐화해서 애플리케이션이 결합을 느슨하게 만들고 

특정 구현에 대한 의존성을 낮힐 수 있다.

- Factory Method

상속을 통해 Product 의 객체를 만든다. ex ) PizzaStore 추상 클래스의 createPizza() 를 오버라이드

클라이언트 코드와 인스턴스를 만드는 구상 클래스를 분리시켜야 할 때 활용할 수 있다.

- Abstract Factory

객체 구성을 통해 Product 의 객체를 만든다. ex ) pizza = new CheesePizza(ingredientFactory)

팩토리를 이용하고 싶으면 일단 인스턴스를 생성하고 추상 형식을 써서 만든 코드(Pizza)에게 이를 전달.

Concrete Factory 구현할 때, 종종 Factory Method 패턴을 사용하는 경우가 있다.

일련의 연관된 제품을 하나로 묶을 수 있다는 장점이 있다.

단, 제품군에 제품을 추가시킬 경우 Abstract Factory 의 createProductC() 를 추가해야 하는데 요약하자면!

인터페이스를 바꿔야해서 모든 서브클래스에도 영향을 미치게 된다는 단점이 있다.



* 객체지향의 원칙 :

1) 바뀌는 부분은 캡슐화 한다.

2) 상속보다는 구성을 활용한다.

3) 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

4) 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

5) 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다(OCP).

6) 추상화된 것에 의존해라. 구상 클래스에 의존해서는 안 된다(의존성 뒤집기 법칙).



이 장에서의 정리 :

- Factory 를 쓰면 객체 생성을 캡슐화 할 수 있다.

- Factory Method 패턴에서는 어떤 클래스에서 인스턴스를 만드는 일을 서브클래스에게 넘긴다.

- Abstract Factory 패턴에서는 구상 클래스에 직접 의존하지 않고도 

서로 관련된 객체들로 이루어진 제품군을 만들기 위한 용도로 쓰인다.

- Factory 는 구상 클래스가 아닌 추상 클래스 / 인터페이스에 맞춰서 코딩할 수 있게 해주는 강력한 기법이다!


by kelicia 2014. 5. 19. 02:13

- 예제 코드 Diagram -



* Decorator Patterns

(상속 또는 인터페이스를 이용해 형식(Type)을 맞춤으로서객체에 추가적인 요건을 동적으로 첨가할 수 있다.

Decorator 는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.

주의할 건 Decorator 는 상속을 통해서 행동을 물려받는 것이 목적이 아니다!


위 Diagram 를 통해 설명하자면,

- Beverage 가 추상 구성요소 (Component)

- DarkRoast, HouseBlend, Decaf, Espresso 가 구상 구성요소 (Concrete Component)

- CondimentDecorator 가 추상 데코레이터 (Decorator)

- Mocha, SteamMilk, Whip, Soy 가 구상 데코레이터 (Concrete Decorator)


※ Beverage 클래스가 추상 클래스인데, 이는 기존의 코드가 추상 클래스로 되어있었고

기존 코드는 가능한 고치지 않는 것이 좋기 때문에 그대로 쓴 것이다. 인터페이스로 구현하는 것도 가능하다.



* 예제 코드

Beverage beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Whip(beverage);
System.out.println(beverage.cost());

Beverage 의 구상요소들 cost() 의 내용은

return (음료 가격);


Condiment Decorator 의 구상요소들 cost() 의 내용은

return (데코 가격) + (생성자에서 전달받은 음료).cost();




* java.io 클래스와 Decorator 패턴


(출처:http://i.stack.imgur.com/O7pqc.png)



* OCP (Open-Closed Principle) :

- 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다 !



* Decorator 패턴의 장점 & 단점

- OCP 에 충실하면서 유연한 디자인을 만들어 낼 수 있다.

- Decorator 를 바로 끼워넣어도 클라이언트 쪽에서는 Decorator 를 사용한다는 것을 전혀 알 수 없다.

- 자잘한 클래스들이 엄청나게 추가되는 경우가 종종 발생해 이해하기 힘든 디자인이 만들어 질 수 있다.

(ex. java.io 클래스)

- Decorator 를 도입하면 구성 요소를 초기화하는 데 필요한 코드가 훨씬 복잡해진다.

구성 요소 인스턴스만 만드는 것 뿐만 아니라 꽤 많은 Decorator 로 감싸는 경우가 자주 발생한다.

(but 이 문제는 차후 다루는 장 ~팩토리, 빌더~ 를 통해 해결할 수 있다고 한다)


* 객체지향의 원칙 :

1) 바뀌는 부분은 캡슐화 한다.

2) 상속보다는 구성을 활용한다.

3) 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

4) 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.

5) 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다(OCP).



이 장에서의 정리 :

- 상속 또는 인터페이스 구현을 통해서 Decorator 가 감쌀 클래스와 같은 형식을 가지게 된다.

- Decorator 에서는 자기가 감싸고 있는 구성요소의 메소드를 호출한 결과에

 새로운 기능을 더함으로써 행동을 확장한다.

- 구성요소를 감싸는 Decorator 의 갯수에는 제한이 없으나

 자잘한 객체들이 너무 많이 추가될 수 있고, 이로 인해 코드가 필요 이상으로 복잡해질 수도 있다. 

 주의해서 남용하는 일이 없도록 하자!


by kelicia 2014. 5. 18. 02:44

- 예제 코드 Diagram -


쉽게 이해하자면,

출판사(Subject:주제) + 구독자(Observer) = Observer Pattern.


* Observer Pattern

- 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고,

자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의한다.



* 느슨한 결합 (Loose Coupling) 

- 두 객체가 상호작용을 하긴 하지만 서로에 대해 잘 모른다!

- Observer Pattern 에서는 이러한 디자인을 제공한다. Why ?

(1) Subject 가 Observer 에 대해서 아는 것은 Observer 가 특정 인터페이스를 구현한다는 것 뿐이다.

(2) Observer 는 언제든지 추가, 삭제할 수 있다.

(3) 새로운 타입의 Observer 를 추가하려고 해도 Subject 를 변경할 필요가 전혀 없다.

(4) Subject 와 Observer 는 서로 독립적으로 사용이 가능하다.

(4) Subject 또는 Observer 가 바뀌더라도 서로한테 영향을 미치지 않는다.



* Push 방식 vs. Pull 방식

Push 방식 : Subject 는 데이터가 변경될 때 마다 Observer 들에게 알려준다.

- 장점

Observer 는 Subject 에게 따로 데이터를 요청할 필요가 없다.

- 단점

Observer 가 불필요한 데이터까지 받아야 되는 경우가 생긴다.


Pull 방식 : Observer 가 갱신된 데이터가 필요할 때 Getter 메소드를 이용해 Subject 로부터 데이터를 가져온다.

- 장점

Observer 는 필요한 데이터만 가져올 수 있다.

Subject 가 확장되더라도 Subject 는 notify 메소드를 수정할 필요없이 Getter 메소드만 추가하면 된다.

- 단점

Observer 는 필요한 데이터가 많을 수록 Getter 메소드를 여러 번 호출해야만 한다.

(Pull 방식이 더 옳은 것으로 간주된다고 한다)



* java.util.Observable, java.util.Observer

(이미지 출처 : http://dellabate.wordpress.com/2012/03/03/gof-patterns-observer/)


- 처음의 Diagram 에서는 인터페이스를 이용해 Observer Pattern 을 구현했지만 

바로 위의 이미지와 같이 Java 에서 API 로 지원하기도 한다.


- Observable 의 주의점*

1) Interface 가 아닌 Class 라는 점!

- 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다는 객체지향의 원칙 3)에 위배된다.

- 클래스이기 때문에 서브클래스를 만들어야 한다는 것이 문제.

  이미 다른 수퍼클래스를 확장하고 있는 클래스에 Observable 의 기능을 추가할 수 없기 때문이다.

  그래서 재사용성에 제약이 생기게 된다.

- Observable 인터페이스가 없어 Java 의 Observer API 하고 잘 맞는 클래스를 직접 구현하는 것이 불가능.

2) Observable 클래스의 핵심 메소드를 외부에서 호출할 수 없다!

- protected 로 선언된 setChanged(), clearChanged() 는 Observable 의 서브클래스에서만 호출 가능하다.

- 상속보다는 구성을 활용한다는 객체지향의 원칙 2)에 위배된다.



* 객체지향의 원칙 :

1) 바뀌는 부분은 캡슐화 한다.

2) 상속보다는 구성을 활용한다. - Subject 와 Observer 사이의 관계는 상속이 아니라 구성에 의해 이루어진다!

3) 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

4) 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.



이 장에서의 정리 :

- Subject (또는 Observable 객체) 는 동일한 인터페이스를 써서 Observer 에게 연락을 한다.

- Observer Pattern 은 Swing 및 여러 GUI 프레임워크, JavaBeans 나 RMI 같이 광범위하게 쓰인다.

ex ) Swing API 에서 JButton 의 ActionListener 등록


by kelicia 2014. 5. 16. 20:11

- 예제 코드 UML Diagram -



* Strategy Pattern :

- 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다.

이를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.




객체지향의 기초 :

1) 추상화    2) 캡슐화    3) 다형성    4) 상속



객체지향의 원칙 :

1) 바뀌는 부분은 캡슐화 한다. (무엇이 바뀌고, 안 바뀌는지 잘 구분해야한다)

2) 상속보다는 구성을 활용한다.

3) 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.



이 장에서의 정리 :

- 훌륭한 객체지향의 디자인이라면... 재사용성, 확장성, 관리의 용이성을 갖춰야 한다.



# Reference

- '캡슐화'에 대한 강좌 (네이버 검색 키워드 : 객체지향 캡슐화, 카페 이름 : GIS 프로그래밍 연구소)

http://cafe.naver.com/gisdev/543


by kelicia 2014. 5. 16. 19:10



이펙티브 프로그래밍

저자
제프 앳우드 지음
출판사
위키북스 | 2013-03-29 출간
카테고리
컴퓨터/IT
책소개
코딩 호러 블로그의 운영자이자 스택 오버플로우 공동 창업자가 알...
가격비교



ㅋㅋㅋㅋㅋ 동시다발적으로(?) 책 리뷰를 쓰게됐다.

한가한 백수이다보니ㅡ_ㅡ 책을 읽을 수 있는 시간이 많다.


지난 번에 리뷰한 '코딩 호러가 들려주는 진짜 소프트웨어 개발 이야기'에 이어

이 책을 읽었다. 원래 이게 먼저 나온 책이던가 그런데 뭐 아무렴 어때.


...하지만 조금 겹치는 내용들이 있긴 있었다. 

덕분에 후루루룩!! 하고 읽었다ㅋ 책을 너무 대충읽었나 싶은 생각도 든다.


저자님이 조엘 스폴스키님이랑 같이 stackoverflow 를 공동 창업하시다 보니

두 책 모두 조엘님 이야기가 엄청 나온다 ㅋㅋㅋㅋ 

그래서 다음엔 조엘님이 쓰신 책을 읽어보려고 한다. 


책을 읽으면 읽을수록 읽어야할(?) 책 리스트가 많아진다_-_ 

사실 책을 읽어야만 한다는 압박과 부담이 책읽기를 힘들게 하지만...

왜 나는 스스로에게 부담스러운 압박을 하는지 ㅋㅋㅋㅋㅋㅋㅋ 나 좀 이상한듯.

이래서 조급한 성격이 문제인듯.



또 잡소리가 길어지니 리뷰로 넘어가겠다.

무려 12개의 장으로 나뉘는데 늘 그랬듯이 하나씩 훑어보겠다.



1. 들어가며


- 프로그래머의 8 단계

(1) 죽은 프로그래머 : 최고 단계. 자신이 작성한 코드가 자신이 죽은 뒤에도 사용된다.

ex - 다익스트라, 도널드 커누스, 앨런 케이

(2) 성공적인 프로그래머 : 자신의 코드를 이용해 비지니스 혹은 산업을 창조한 프로그래머.

ex - 빌 게이츠, 존 카맥, DHH

(3) 유명한 프로그래머 : 프로그래머 집단에서 잘 알려진 존재.

(4) 일하는 프로그래머 : 개발자로서 성공적인 경력을 보유해 새로운 직장을 구하는 데 어려움이 없음.

(5) 평균적인 프로그래머 : 자신이 위대한 개발자가 아니라는 건 알지만 충분히 좋은 실력을 갖추고 있음.

(6) 아마추어 프로그래머 : 코딩을 좋아하는 사람들.

(7) 알려지지 않은 프로그래머 : 대부분 대기업에서 근무하며 유능하긴 하지만 별 특징이 없는 사람들.

(8) 나쁜 프로그래머 : 기술이나 능력이 없는 상태에서 프로그래머로 종사하는 사람들.


책에 더 자세히 나와있지만 이정도만 정리하겠다.

나는 지금 어디에 속하고 어떤 프로그래머가 되고 싶은지 생각해 볼 수 있었다.


개인적으로 나는...음.. 5~6 정도에 속하지 않을까 싶다. (아마도)

그리고 죽기 전에는 1~3 중에 하나는 이루고 싶다 ㅋ 

1, 2 둘 중 하나만 이뤄도 3 은 자동적으로 이뤄질 것 같다. 최소 3 만은 욕심내고 싶다ㅋㅋㅋㅋㅋ


- 쓰지 않으면서 쓰기

제프 엣우드님의 글에서 항상 하는 이야기. 글을 써야 한다 ! ! ! !

특히 개발자들의 특징 중 하나가 코드만 작성하다보면 의사 소통 능력이_-_ 음...(...)

이렇게 되는 경우가 많아서 

저자님과 조엘님이 ~ 어떻게 해서든 이 작자들이(?) 짧은 글이든 뭐든 글을 쓰게 만들고자 ~

스택 오버플로우 사이트를 제작하게 되었다고 한다ㅋ


뭐 어쨌든 저는 그 말씀에 공감하며 지금도 글을 쓰고 있습니다ㅎㅎㅎ




2. 엉터리 같은 일을 마무리하는 기술


- 톱날 갈기

어떤 능력을 향상시키는 최선의 방법은 최대한 반복해서 연습하는 것.

기술을 연마하는 것과 기술을 활용하는 방식에 대해 사색하는 것 사이에서 균형을 잡을 필요가 있다.


저자님께서 추천해주신 프로그래밍과 관련된 좋은 링크들을 모아놓은 웹 사이트

(1) 해커 뉴스 : 완전 강추라고 적혀있다. 폴 그레이엄의 정신이 낳은 자식이라고 한다.

https://news.ycombinator.com/news )

(2) 프로그래밍 레딧 : 어수선하지만 프로그래머들에게 관심을 불러일으킬 만한 사이트가 매우 많다고 한다.

http://www.reddit.com/r/programming )


둘 다 링크 걸기위해 들어가봤는데... 일단 영어 잘 하시는 분만 들어가시길 권장ㅋ

해커 뉴스는 심플하고 아기자기한 반면에 레딧은 진짜 정신없다 ㅋㅋㅋㅋㅋㅋㅋㅋ

앳우드님께서 추천해주셨지만 난 아직 둘다 볼 만한 레벨은 아닌 것 같다 흑 ㅠ_ㅠ


- 멀티태스킹이라는 미신

간단히 말하자면... 사람이 멀티태스킹 하면 점점 바보된다.

동시에 여러 일을 할 수 있다고 스스로를 과대평가하지만 냉철해져야 할 필요가 있다는 말씀.




3. 좋은 프로그래밍의 원리


- 프로그래밍의 첫 번째 원리 : 그것은 언제나 당신의 잘못이다

나를 포함해서 많은 사람들이 비판이 아닌 '비난'을 잘한다 ㅋㅋㅋㅋ

여기서 '실용주의 프로그래머'라는 책의 'select는 망가지지 않았다'에 대한 이야기를 실었는데

재밌기도 하고 소제목가 말하고 싶은 바를 잘 보여주는 에피소드라고 생각한다.


'코드에 책임을 지는 것'의 의미란

자기가 작성한 소프트웨어에 어떤 문제가 있든지 간에, 심지어 그것이 자기 코드가 야기하는 문제가

아닌 경우조차도 일단 문제가 자기 코드에 있다고 간주하고 그에 합당한 조취를 취하는 태도를 의미한다.


솔직히 (설령 제대로 확인을 했더라도막상 상황에 부딪히면 본능적으로 자기방어 심리에 

내 잘못이 아니라고 자신을 변호하면서 다른 쪽으로 책임을 전가하는 경향이 있다고 생각한다.

이 글을 보면서 그런 마인드를 잘 컨트롤할 수 있을지 조금 걱정이 되지만 

저렇게 하는 쪽이 옳다고 공감하는 만큼 노력 해야되겠다.


- 주석 없이 코딩하기

대체로 다른 사람이 내 코드를 잘 이해할 수 있도록 주석을 잘 달아놓으라는 얘기를 듣지만

왜곡되서 이해할 때도 있다. 그 결과로 의도치않게 왠지 쓸데없는 주석까지 blah blah 달고 있는 나를 보게 된다.


코드만으로도 충분히 이해할 수 있도록 작성하는 게 BEST 지만

어쩔 수 없는 경우에는 정말 똑부러지게 핵심만 찌르는 주석을 신중하게 달아야한다.

전에도 저자님께서 강조하듯이 '최선의 코드는 아무 코드도 없는 것이다'라고 하신 말씀에 귀결된다고 생각한다.


- 성능은 기능이다

빠른 웹 사이트를 만들기 위해 다음과 같은 Tool들을 이용할 수 있다고 한다.

(1)야후! YSlow    (2) 구글 페이지 스피드    (3) 핑돔 툴즈(Pingdom Tools)


그리고 지금은 잘 이해가 되지 않지만 필요한 내용이라고 생각되는 것을 소개해주셨다.

그게 바로 'CDN(Content Delivery Network) : 콘텐츠 전달 네트워크' 이다.


응답 속도 향상을 위해 욕심 부리거나 아키텍처를 새로 설계하는 노력을 기울이는 것 보다는 !

정적인 콘텐츠를 우선적으로 분산시키는 것이 현명하다고 한다. 

이를 위해 CDN를 사용하는 것이 용이하다고 하지만 이를 활용하는 것은 가급적 뒤로 미루라고 하신다.

이것보다는 아래의 방법들을 먼저 실천하자. 참고로 CDN 도 포함되어있다.


야후!가 발표한 웹 사이트를 빠르게 하는 13가지 간단한 방법

( 본문 : https://developer.yahoo.com/performance/rules.html )

( 정리 및 번역 : http://geothink.tistory.com/entry/빠른-웹-사이트를-위한-13가지-기본-룰-1 )


잡설이지만 티스토리도 네이버 블로그처럼 좀 깔끔하게 링크 주소를 갖고 올 수 있도록 해줬으면 좋겠다ㅡ_ㅡ+


그리고 익명의 사용자와 로그인한 사용자, 모두를 위해 디자인하고 최적화하자.

어쩌다 한 번씩 방문하는 익명의 사용자와 매일 방문하는 사용자들가 내려받는 데이터의 양이 다르다고 한다.

(구글 크롬의 네트워크 패널 자료를 보면 로그인한 사용자가 더 많은 데이터를 전달 받는다)

전자는 기본 기능만 탑재한 최소한의 코드로 빠른 속도를 체험할 수 있게

후자는 커뮤니티 활성을 위해 노력하시는 분들 이므로 코드를 추가해 더 많은 기능을 사용할 수 있게.




4. 프로그래머를 제대로 채용하는 법

음....... 나는 지금 채용을 당하는 입장으로서 이 장을 읽으면서 기분이 조금 오묘했다. 크흑.


- 프로그래머를 채용하는 법

저자님에 따르면 온라인에서 코딩 검증을 대행하는 서비스가 있다고 한다.

인터뷰 젠 : http://www.interviewzen.com/

코딜리티 : https://codility.com/


... 이런 거 처음본다. 소개해주신 저자님께 감사드린다.

이 외에 전화 인터뷰를 위한 문제들도 소개되어있다.

(1) 바로 코딩하는 질문 : 배열 안에 있는 정수 값 중에서 가장 큰 값을 찾아라

(2) 간단한 설계 질문 : HTML을 모델링하기 위한 표현 방식을 설계해보라.

(3) script 작성과 정규 표현식 : directory 내에서 특정 형식의 전화번호가 저장된 텍스트 파일 목록 만들기.

또는 HTML 페이지에서 전화번호 추출하기.

(4) 자료구조 : 어떤 경우에 배열 대신 해쉬 테이블을 사용할 것인가?

(5) 비트와 바이트 : 프로그래머에게 10월 31일(Oct 31)과 12월 25일(Dec 25)이 같은지 묻는 게 왜 우스운가?


그 외에 다른 질문들도 많이 소개 되어있다. (너무 많으니 여기에 다 적지는 않는다)


제프 앳우드 님이 추천하는 방법 중에 하나는 자기 분야에 대한 PPT를 20분 가량하는 것이라고 한다.

글쎄... 내가 봤을 때 저 방법은 아마 경력직을 대상으로 하는 이야기 아닐까 싶다.

솔직히 신입은 자기 분야라고 말할 수 있는 정도의 수준이 되는 애가 얼마나 될까 싶기 때문이다.




5. 팀이 함께 일하도록 만들기


- 뱀파이어 프로그래머 VS. 베어울프 시스템 관리자

비유가 재밌어서 여기에 남겨본다.


프로그래머는 종종 밤에 깨어있고, 죽음보다 창백한 얼굴을 가지고 있으며,

일반적으로 햇빛에 노출되는 것을 싫어한다. 그리고 자신의 코드가 영원히 죽지 않을 거라고 생각하는 경향이 있다.

마지막에는 동의하기 힘들지만 뭐 뱀파이어 같다는 비유가 재밌다.


반면에 시스템 관리자는 겉으로 보기에 평범하지만 믿을 수 없을 정도로 힘이 세고,

보통 사람들을 쉽게 죽일 만한 일들 앞에서는 멀쩡하다. 그리고 '사건'이 터지는 달밤에

몸에서 기묘한 변화를 겪는다고 한다.


서로 다른 종류의 괴물이지만 VS. 가 아닌 AND 가 되어야한다는 이야기.


- 회의 : 일이 죽으러 가는 장소

이것도 비유가 재밌다 ㅋㅋㅋㅋ

저자 님께서는 회의에 대해 다음과 같은 원칙을 가지고 있다고 한다.

(1) 회의가 한 시간이 넘기면 사형    (2) 모든 회의에는 명확하게 정의된 목표 설정

(3) 회의 참석 전에 회의에서 필요한 일하기    (4) 회의 참석을 선택사항으로 만들기

(5) 회의를 마무리할 때 해야 할 일 정리하기


음... 꽤 공감이 된다.




6. 당신의 박쥐 동굴 : 프로그래머를 위한 효율적인 작업 공간


- 프로그래머 권리 장전

(1) 모든 프로그래머는 2 대의 모니터를 가져야 한다

(2) 모든 프로그래머는 빠른 PC를 가져야 한다

(3) 모든 프로그래머는 마우스와 키보드를 자기가 원하는 것으로 선택할 권리가 있다

(4) 모든 프로그래머는 편안한 의자를 가져야 한다

(5) 모든 프로그래머는 인터넷에 연결할 수 있어야 한다

(6) 모든 프로그래머는 조용한 작업 환경을 가져야 한다


음....... 내가 봤을 때 2 를 제외하고는 왠만하면 보장되는 것 같다. (아니라고 외치는 사람도 있겠지만)

ㅋㅋㅋㅋ 가끔씩 생각나는 건 내가 인턴으로 일하기 시작했을 때 

도난 우려라는 이유로 진짜 후진 노트북를 받아서 일했던 적이 생각난다.


- 기타 좋은 의자 추천과 배경 조명에 관한 글이 궁금하다면 이 책을 읽어보시길.

특히 배경 조명의 중요성을 일깨워주는 글이 신선했다.

(배경 조명은 간접 조명과 조명을 완화하는 방법이 하나로 결합된 방식, 모니터 뒤에 불빛을 둬라!)




7. 사용자를 염두에 두고 설계하기


- 애플리케이션은 결국, 작은 디테일의 모음이다

저자님은 2마리의 고양이를 키우고 계신다. (꺄)

이 글은 고양이 자동 급식기의 구식과 신식을 소개하면서 비교하는 글이 쭉 적혀있다.

그리고 결론은 핵심 기능이 어느 정도 제대로 구현이 되있고, 고객의 피드백을 통해 디테일을 개선하고자 한다면

디테일 구현하려는 첫 시도에서 실패하는 것을 두려워 할 필요가 없다는 것이다.


- UI를 우선시하는 소프트웨어 개발

'종이 위의 프로토타입 : 사용자 인터페이스를 빠르고 쉽게 디자인하기'

(Paper Prototyping : The Fast and Easy way to Design and Refine User Interfaces)

위 책은 종이 위에 프로토타입을 그려보는 방법을 다룬 탁월한 입문서라고 한다.


- 버전 1은 엉망이야, 하지만 어쨌든 출시하라고

난 이 소제목을 보면서 이 무슨 멍멍이 같은 소리인가 하고 반감을 샀지만...

중요한 건 소프트웨어가 얼마나 완벽한 것인가가 아니라, 

소프트웨어를 출시한 다음에 당신이 어떻게 하느냐 라고 한다. 


나의 경우에는 일을 일단 끝맺으면 다시 되돌아보지 않는 경향이 커서 조금 심각한 문제가 아닌가 싶기도 하다.

그래서 일을 끝맺기 바로 직전까지 무척 완성도에 집착하고 매달리게 된다.

아마 내가 팀장이 된다면 팀원들에게 엄청 채찍질 하는 건 않을까 하는, 두려운 상상을 하게 된다.


그러니 귀차니즘을 떨쳐내고 반복적인 개선이 자연스러운 일이라는 것을 받아들이도록 침착해져야 겠다.




8. 보안의 기초 : 사용자의 데이터를 보호하라


- 웹 트래픽 전체를 암호화해야 하는가?

이 글을 읽으면서 HTTP 와 HTTPS 에 대해 고찰해볼 수 있었다.

그래서 간단히 검색해보니 자세한 설명이 나와있는 글을 찾았다. 한글이니 편히 읽을 수 있다.

http://opentutorials.org/course/228/4894 )


- 사전(Dictionary) 공격 기초, 빠른 해싱, 웹 비밀번호를 둘러싼 불편한 진실

이 책에서 가장 재밌는 부분들이 아닐까 한다.

보안 수업을 흥미롭게 들은 나로서는 정독할 수 있는 글이었고,

읽다보면 당연하고 쉬운 글들이라고 생각할 수 있겠지만 그래도 읽을 가치는 충분하다고 생각한다.


8장의 글 전부가 재밌다. 보안에 관심있는 초보 개발자라면 꼭 읽어보시길.

고커 네트워크 까는 글이 우...웃겼다. 비번 저장, DES 암호화에서 어처구니 빵터짐 ㅋㅋㅋㅋ




9. 코드를 테스트해서 그것이 필요 이상으로 엉망이 되지 않게 만들기


- 단위(Unit) 테스트 VS. 베타(Beta) 테스트

윌 쉬플리라는 베테랑 프로그래머는 단위 테스트를 너무나도 혐오하신다.

사람이 직접 테스트 하는 것을 극단적일 정도로 강조하시는데 음... 저자님의 의견에 따르면

기본적인 단위 테스트가 베타 테스팅을 보완할 수 있다고는 생각하지만 윌님의 의견에 동의한다고 한다.

그 말은 즉.... 단위 테스트가 불필요한 건 아니지만 베타 테스트에 더 무게를 실으신다는 말씀이라 생각한다.


- 크래쉬보다 더 나쁜 것은 무엇인가?

이 글을 보면서 나는 '원래 버그가 발생하고 한참 지난 다음에 애플리케이션이 크래쉬한다' 라는 글을

읽는 순간 숨이 멎는 줄 알았다 ㅋㅋㅋㅋㅋㅋㅋㅋ 진짜 상상도 하기 싫다 ㅋㅋㅋㅋㅋ 끔찍해 으아ㅏㅏㅏㅏ


저런 경우 뭐가 문제인지 찾기도 힘들고 그러다보면 멘붕 상태에 이르기때문에 ㅡ_ㅡ....

진짜 저것만큼 최악인 것도 없다고 생각했다. 하지만 이 글의 결론과는 달랐다.

핵심은 '사용자의 데이터를 절대, 반드시, 무슨 일이 있어도 손실해서는 안 된다. 보호해야만 한다' 였다. 

내가 너무 개발자 입장에서만 생각했다는 게 확 느껴진다 ㅋㅋㅋㅋㅋ 흐엉 반성하자 ㅠ_ㅠ




10. 커뮤니티를 만들고, 관리하고, 커뮤니티로부터 이익 얻기


- 이 장을 읽은 덕분에 'Stack Exchange, Stack Overflow 무슨 차이일까?' 라는 포스팅을 하게 되었다.


- 정지, 금지 혹은 완전금지?

커뮤니티를 보면 꼭 썩은 사과같은 존재가 있기 마련이다. 그러니 이 녀석들을 없애기 위해서는 !

~ 누군가를 몰래 정지시키는 3가지 방식 ~

(1) 완전 금지 : 커뮤니티에 참여할 수 있지만 다른 모두 사람들에게 노출되지 않으므로

아무도 그들에게 응답하지않는다. '트롤에게 먹이를 주지말라' 원칙이 적용된 방식.

(2) 느린 금지 : 웹 사이트 반응 속도를 느리게 함으로서 참여의 감소를 유도함.

(3) 에러 금지 : 방문하는 페이지의 무작위한 장소에 에러가 뜨는 것을 경험한다. 

드루팔 미저리(Drupal Misery) 모듈 같은 곳에 실제로 구현되어 있다고도 한다.


ㅋㅋㅋㅋ 읽어보기만 해도 레알 끔찍한 형벌이라고 느끼는데 나만 그런건가?




11. 마케팅 사기꾼들, 그리고 어떻게 그런 사람이 되지 않을 수 있는가


- 인터넷 광고에서 하지 말아야 할 일

이 글에서는 문명이라는 게임의 브라우저 판인 에보니(Evony) 라는 게임의 인터넷 광고 변천 과정을 볼 수 있다.

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

웃음 밖에 안 나온다. 이런 식의 광고는 실제로도 정말 많이 봤다. 써글. 욕 나올 뻔했다.


저자님이 비꼬는 말이 기억에 남는다 ㅋㅋㅋㅋ

'에보니, 인터넷 광고가 도달할 수 있는 맨 밑바닥이 어떤 것인지 보여준 것에 대해 고마움을 전한다'




12. 우선순위를 제대로 관리하기


- 행복을 구매하기

이 글의 내용은 

마치 내가 최근에 리뷰한 '59초 - 순식간에 원하는 결과를 끌어내는 결정적 행동의 비밀 -' 라는 책의

요약본과도 같은 글이었다.


- 빠르게 살고, 일찍 죽고, 지친 육신을 남기고

닷컴 거품의 과도했던 측면을 잘 포착해서 그려낸 다큐멘터리 영화가 2개 있다고 한다.

(1) Startup.com : 웹 1.0 회사들의 초기 모습을 그려낸 작품

(2) Code rush : 98~99년 사이에 넷스케이프에서 촬영된 작품


넷스케이프... 훌륭한 회사지만 MS의 IE 끼워팔기로 인해 몰락해버린... 

씁쓸하고 동정을 금치 못하는 회사라는 것은 이미 알고 있다.


책에 의하면 그들은 다음과 같이 의미있는 유산을 남겼다고 한다.

# 넷스케이프 네비케이터 를 통해 HTML과 인터넷 자체를 널리 퍼뜨렸다.

# 98.03.31 에 넷스케이프 소스코드를 공개함으로서 상상하기 어려웠던 상업용 오픈소스 운동의 씨앗을 뿌렸다.

# 04년도에 모질라 파이어폭스 1.0 이라는 브라우저를 통해 IE에게 처음으로 실제적인 위협을 가하기도 했다.


회사는 이미 사라지고 없지만 수많은 전설적인 해커들은 그곳에서 시작해 퐌타스틱한 경험을 쌓아갔다.


저자님께서는 이들의 운명과 같은 길을 걷고 싶지 않다면 신중히 생각하라고 조언해주셨다.

그런 회사들의 삶은 빠르게 살고, 일찍 죽고, 그리하여 지친 육신을 남기는 것이었다. 라고 덧붙이셨고.


'왜 그토록 오랜 시간 동안 열심히 일을 하는지'


by kelicia 2014. 5. 13. 21:22


최근에 제프 앳우드님께서 저술하신 책

'코딩호러가 들려주는 진짜 소프트웨어 개발자 이야기'

'코딩호러의 이펙티브 프로그래밍'

이 2권을 읽으면서 쭉 궁금했던 게 있는데 그걸 정리해 보고자 한다.


질문은 글 제목과 같이

'Stack Exchange, Stack Overflow 무슨 차이일까?' 라는 의문이다.


Stack Overflow 는 개발자들이 자주 마주치는 사이트라서 알고있지만

저 책들을 읽고나서 Stack Exchange 는 뭐지? 라는 생각에서 피어난 의문.


책을 읽다가 뭔가 놓친 부분이 있어서 이 질문에 대한 답이 있는데도 불구하고

모르는 것일 수도 있겠지만 ㅡ_ㅡ...(...) 


어쨌든 궁금한 건 바로 해결해야 직성이 풀리므로 

N사 검색을 대충 해보니까 한글로 이 질문에 대한 답변?을 구할 수가 없어서 

결국 G사 검색을 때렸다.


답변이 있지만 영어로 blah blah 되있으니_-_ 

짧은 영어실력으로나마 정리해보겠다.

(저 2권의 책 읽고나서 내가 블로그에서 쓰는 말투가 좀 바뀐듯한 걸 느낀다ㅋ)




우선, StackExchange 사이트에 가봤다.


올 ㅋ 역시 깔끔하고 이-뻐. 


Stack Exchange 란 

'특정 분야에 대한 Q&A 커뮤니티 사이트들을 하나로 모아서

내가 원하는 사이트로 연결해주는 네트워크' 라고 보면 된다. 


좀 더 쉽게 말하면 여러 사이트들로 연결해주는 중심 네트워크이고,

이 Stack Exchange가 연결해주는 사이트들 중 하나가 Stack Overflow 이다 !


캡쳐화면 우측 하단 컬럼들을 보면 어떤 느낌인지 알 수 있을  것이다. 

Top Network Sites 에서 Stack Overflow 가 최상단에 표시되어 있다ㅎㅎ


그 위에는 현재 연결해주는 네트워크들 상태를 보여준다. 

100개가 넘는 사이트들에 대한 통계를 보여준다~_~


각 사이트 별로 다루는 특정 분야가 있는데 사이트들 이름만 봐도 어떤 주제를 다루는지 알수있다.

ex) Ask Ubuntu, Mathematics, Server Fault, English Language & Usage 등등 ~


대부분 사이트들의 공통점이라면... 개발자를 위한, 프로그래밍과 관련된 사이트라는 점.

물론 아닌 사이트들도 있다. 예를 들면 photography 나 videogamer 를 위한 커뮤니티로 연결될 수도 있다.

사이트마다 설명이 간단하게 잘 나와있으니 참고하거나 검색하면 된다.


더 자세히 알고 싶다면 http://stackexchange.com/





그리고 위 사이트가 연결해주는 Q&A 사이트 중에서 대표적인 Stack Overflow.

설명에 의하면 'Q&A for professional and enthusiast programmers' 이라고 적혀있다.


이 사이트는 정말... 개발하다가 한번 쯤은 마주치게 되는ㅋㅋㅋㅋ 사이트다.

다양한 개발 랭귀지들을 다루기 때문에 이용자들이 많아서 Top 안에 들어갈 수 밖에 없다. 


제프 앳우드님의 말에 따르면 이 사이트는 게임화 되있다고 한다.

평판, 뱃지, 랭킹, 찬성표 와 같은 시스템들이 있기 때문이다.

쉽게 생각하면 N사 지식in 같은 거ㅋ (물론 지식in 따위와 비교도 할 수 없는 고퀼을 자랑한다)


그러다보니 관리도 꽤 잘되는 편이라 이 사이트를 이용하다보면

상당히 고품질의 답변을 얻을 수 있다. 영어이긴하지만.


개발 관련 질문은 무조건 G사 검색으로 때리시길. 

진짜 필연적으로 여기에 오게된다. 영어라고 꺼려하면 그야말로 낙(落)이다, 다이다이_-_



아, Stack Overflow 메인에서 최하단으로 내려가보니


요렇게 되어있더라. Stack Exchange 에서 연결해주는 사이트들을

주제별로 나눠서 잘 정리해놓았다. 우왕 굳ㅋ


개발과 관련된 기술 말고도 상당히 많은 사이트들이 링크 되어있다.

이렇게 많은 사이트들 관리하는 게 쉬운 일이 아닌데 말이다_-_


평소 검색을 통해 이 사이트의 질문들 가운데 하나로만 접하다보니 

메인 페이지는 본 적이 없었는데 이제 보니 생소하다 ㅋㅋㅋㅋㅋㅋㅋㅋ


아직 안 가봤다면 한번 구경해보시길. http://stackoverflow.com/




꽁시랑 대면서 포스팅 해봤는데 답변만 요약하자면


Stack Exchange : 특정 분야에 대한 Q&A 커뮤니티로 연결해주는 중심 네트워크이자 웹 사이트.

Stack Overflow : 열정적이고 전문 프로그래머를 위한 Q&A 사이트.




추가로 Meta Stack Exchage 라는 사이트도 있다.( http://meta.stackexchange.com/ )

이펙티브 프로그래밍 책에 따르면

Meta 란 그 장소 자체에 대한 논의를 진행하는 장소를 뜻한다고 한다.


이 곳도 Q&A 사이트인데 주제는

Stack Exchange 를 포함해서 Stack Exchange 가 관리하는 패밀리 사이트들 관한 것으로 

그 사이트들에 대한 버그, 특징, 제안사항 등을 논한다. 아래에 잘 나와있다.


나는 여기서 이 포스팅에 대한 답을 얻었다.

완전 신기한 건 이 글에 대한 답변 중에 제프 앳우드님이 직접 답변한 것도 있다 ㅋㅋㅋㅋㅋㅋㅋ

우으ㅇ와와아앙 어뜨케 동시대 사람이라는 게 참..영광ㅠ_ㅠ


( 아, 참고로 http://meta.stackoverflow.com/ 라는 사이트도 있다. )


by kelicia 2014. 5. 13. 17:10
| 1 2 3 4 5 6 |