2014년 2월 6일 목요일

클래스 다이어그램(Class Diagram)

어떻게 된게 항상 헷갈리는지.... 아무래도 잘 사용하지 않아서 그런지도 모르겠다. 소스를 작성할때 설계를 먼저하고 코딩을 해야 되는데...물론 설계는 먼저하고 소스 코딩을 작성하긴한다. 하지만 정형화된 형식인 아닌 방법을 사용하다보니 개선에 의지가 필요해서 이글을 작성한다. 클래스 다이어그램(Class Diagram)은 시스템의 정적인 상태인 논리적인 구조(클래스)를 표현합니다. Class, Interface, Collaboration 간의 관계를 나타내며, 객체지향 개발에서 가장 공통적으로 많이 사용합니다. 클래스 다이어그램을 구성하는 것은 클래스와 관계입니다.

클래스 다이어그램은 다음과 같은 특징을 가집니다.

  1. 시스템의 요구사항에 표현된 작업 즉, 시스템이 처리해야 하는 작업에 대한 책임을 분할
  2. 모델은 점점 증가되며 관련된 클래스들 끼리 패키지화
  3. 클래스를 너무 작게 쪼개거나 기능을 너무 많이 포함하면 안되며 적절한 방법으로 구현
클래스다이어그램은 시스템의 정적 설계도인 Class Diagram과 시스템의 프로세스도인 Acticle Class Diagram으로 구분할 수 있습니다.

클래스(Class)

 클래스를 구성하는 것은 클래스명, 속성, 메소드입니다. 모든 클래스는 다른 클래스들과 구별되는 유일한 이름을 갖습니다. 클래스명은 단순명과 경로명 두 가지 중 하나를 선택할 수 있습니다. 단순명(Simple Name)은 클래스 이름만 표기하는 방법이고, 경로명(Path Name)은 패키지명을 포함하여 표기하는 방식입니다.
속성은 의미 있는 명사형으로 표현합니다. Visibility Name: Type= Default Value + variableName: byte Visibility는 접근제한자를 나타내며 표기법은 다음과 같습니다.

+ : public

- : private

# : protection

메소드는 의미 있는 동사형으로 표현하며 표기법은 다음과 같습니다.

Visibility Name(Parameter-List): Return-Type Expression

 예)

+ methodName (int param): int

Image 클래스 표기법에 스테레오 타입(Stereo-Type)을 붙일 수 있는데, 스테레오 타입이란 UML의 한정된 모델 요소를 가지고 새로운 어휘를 표현하기 위한 방법입니다. 메소드 명 위에 아래의 예처럼 스테레오 타입을 붙이면 해당 메소드는 생성자라는 것을 표기하는 것입니다.
<<constructor>>
이런 방법으로 클래스명 위에 인터페이스나 추상 클래스임을 나타낼 수 있습니다.

관계(RelationShip)

관계는 모델 요소 간의 논리적 또는 물리적인 연결을 의미하며, 여러 객체의 유기적인 관계를 통해 시스템이 실행됩니다.

1. 의존관계(Dependency)

'Using' 관계를 나타내며, 하나의 모델 요소가 다른 모델 요소를 사용하는 관계를 말합니다. 사용되는 모델 요소가 변경되면 사용하는 요소가 영향을 받지만, 역은 성립되지 않습니다. UML 표기법은 점선으로 된 화살표로 표현합니다. 화살표의 방향은 사용하는 쪽에서 사용되는 쪽으로 향합니다. Image 예제는 프로그래머 클래스가 사용하는 쪽이고 컴퓨터 클래스가 사용되는 쪽입니다. 사용되는 클래스가 사용하는 클래스의 메소드 파라미터로 사용되는 경우, 사용되는 클래스가 사용하는 클래스의 메소드 로컬 변수로 사용되는 경우, 사용되는 클래스가 사용하는 클래스의 전역 변수로 사용되는 경우입니다. 의존 관계는 has a 관계를 가지는 클래스들 간에 변수나, 메소드의 파라미터의 사용을 가지는 클래스의 관계를 표시합니다.

2. 일반화(Generalization)

여러 클래스가 가진 공통적인 특징을 추출하여 공통적인 클래스를 일반화시키는 것을 의미하며, 반드시 클래스간의 'is a' 관계이어야 합니다. 객체지향의 상속 관계를 의미합니다. Image 추상클래스(Abstract) 는 이탤릭체나 스테레오 타입으로 표시합니다.

3. 연관관계(Association)

클래스로부터 생성된 인스턴스들 간의 관계를 표현합니다. 의존관계와 일반화 관계는 단순히 클래스들 간의 관계를 나타내며, Classifire로부터 생성된 인스턴스 사이의 관계를 나타냅니다. 상대방의 인스턴스를 가리킬 수 있는 속성을 가지며, 참조할 수 있는 속성은 UML 상에서 표현하지 않습니다. 표현하고자 할 경우 Role name을 사용합니다. 연관관계가 가리킬 수 있는 방향의 종류는 양방향과 단방향이 있습니다. Image [인스턴스의 표기법]
표기법 인스턴스의 수
1 1개
0..1 0개 또는 1개
* 다수
1..* 1개 또는 다수

4. 집합연관관계(Aggregation)

전체와 부분을 나타내는 모델요소(whole-part)로 전체를 나타내는 클래스와 이를 이루고 있는 부분 클래스의 관계를 나타냅니다.'has a' 관계를 나타내며 집합연관관계는 전체와 부분은 서로 독립적인 관계를 나타냅니다. Image

5. 복합연관관계(Composition)

전체와 부분을 나타내며(Whole-part), 젠체를 나타내는 클래스와 이를 이루고 있는 부분 클래스 관계를 나타냅니다. 연관관계를 맺고 있는 클래스는 생명주기기 같다. 'has a'관계입니다. Image

6. 실체화, 권력화(Realization)

인터페이스는 컴포넌트 간의 결합력을 느슨하게 합니다.(Loose Coupling) 인터페이스는 프로그램의 수정 없이 쉽게 소프트웨어를 확장할 수 있습니다. Image

※ 클래스 다이어그램 UML 작성시 주의점

  1. 클래스 다이어그램은 'is a'관계를 나타냅니다.
  2. 일반화 관계는 균형있게 유지해야 합니다.
  3. 선들이 교차하지 않도록 주의해야 합니다.
  4. 이해하기 쉬운 정도로 간략하게 표시합니다.
  5. 관련 있는 클래스들은 가까운 곳에 배치합니다.

TDD, BDD 비교

Posted: May 18, 2013 | Author:  | Filed under: 소프트웨어개발이야기애자일이야기 |Leave a comment »

마소에 기고한 TDD와 BDD 내용 중, 코드 작성에 관한 부분을 옮겨 왔다.

bdd

그 전에 앞서 약간의 의견을 담아내자면, BDD에 대해서는 다소 회의적이다. 둘 간의 차이가 크지 않고 BDD가 가진 철학이 이미 충분히 TDD에 반영되어 있을 수 있다. 그런 철학은 꼭 BDD만의 것이라고 하기에는 다소 민망하다. 그럼에도 불구하고 차이를 언급했던 것은, 혹시나 차이를 설명하는 과정에서 TDD/BDD에 익숙하지 않은 사람들이 아이디어를 얻어갈 수 있지 않을까 하는 막연한 기대 때문이었다. 아래는 기고 당시의 일부 내용이다.

 

- 아래 -

이제부터는 간단하게 친구신청/확인 기능을 TDD와 BDD로 작성해보며 이 둘을 살펴보려 한다. 제한된 공간안에 TDD와 BDD를 설명해야 하기 때문에, 바로 구현으로 들어가도 될 만큼 작은 기능을 대상으로 선정했지만, 간단히 기능 정의를 하고 시작하도록 한다.

 

기능 정의

친구 신청/확인에 필요한 기능은 다음과 같다.

  • 사용자는 친구를 맺기 위해, 상대방에게 친구 신청을 할 수 있다.
  • 사용자는 다른 사용자와의 친구 여부를 확인할 수 있다.

 간단하게 클래스로 만들어 볼 수 있는 대상은 2개 정도가 될 것 같다.

  • 사용자
  • 친구신청/확인

하지만 기능이 크지 않으므로, 사용자 클래스 하나를 두고 이 안에서 친구 신청 및 확인 기능을 함께 구현하도록 한다. 정리하면, 사용자 클래스 하나에 친구신청, 친구확인 기능이 필요하다.

 

TDD

우선, TDD로 이 내용을 구현해보도록 한다. 가장 먼저 무엇을 테스트해보는게 좋을까? 친구 여부를 확인하기 위해서는 친구 신청을 먼저 구현해야 할 것 같다. 그런데 잠깐, 친구 신청을 했는지 확인하려면 친구 여부 확인이 먼저 필요한 것 아닐까? 이런 경우는 그냥 둘다 함께 확인 가능한 테스트 코드를 작성하면 된다.

먼저 위에서 정의한 기능을 User 클래스의 메서드로 선언한다.

User.java

@Getter
 @Setter
 public class User {
  private String name;
  public User(String name) {
     // TODO
    }
  public void sendFriendRequestTo(User receiver) {
     // TODO
   }
  
  public boolean isFriendWith(User receiver) {
     // TODO
   }
} 

그리고 이를 확인하기 위해 작성한 코드는 다음과 같다.

UserTest.java

public class UserTest {
   @Test
   public void sendRequestTo() {
       // Given
       User userA = new User("A");
       User userB = new User("B");
       // When
       userA.sendFriendRequestTo(userB);
       // Then
       userA.isFriendWith(userB);
   }
}

A라는 이름의 사용자와, B라는 이름의 사용자가 전제조건(Given)으로 주어져 있고, A가 B에게 친구 요청을 던진 경우(When), A가 B와 친구가 되었는지를 확인(Then)하고 있다. 이제 User의 내부를 빠르게 구현해보면, 다음과 같은 코드가 나온다.

@Getter
@Setter
public class User {
   private String name;
   private List<User> friends;
   public User(String name) {
       this.name = name;
       this.friends = new ArrayList<User>();
   }
   public void sendFriendRequestTo(User receiver) {
       friends.add(receiver);
   }
   public boolean isFriendWith(User receiver) {
       return friends.contains(receiver);
   }
}

대부분 금방 눈치 챘겠지만, 코드를 보면 B의 입장에서 A가 친구인지의 여부가 의심이 될 것이다. 이런 경우라면 다음과 같이 Test 케이스를 추가해 확인해 볼 수 있다.

UserTest.java

public class UserTest {
   ... 생략
   @Test
   public void sendRequestTo_상대방에게_요청을_받은_경우() {
       // Given
       User userA = new User("A");
       User userB = new User("B");
       // When
       userB.sendFriendRequestTo(userA);
       // Then
       Assert.assertTrue("친구 요청을 받으면 친구가 되야 한다.", userA.isFriendWith(userB));
   }
}

필요하다면 다음과 같이 메서드에 설명을 붙여 케이스를 추가해 나갈 수 있다.

  • isFriendWith_친구신청_하지_않은_경우
  • sendRequestTo_중복으로_친구신청을_한_경우

그런데 잠깐, 새롭게 추가한 테스트 케이스가 실패함을 확인할 수 있다. 이는 단방향이 아니라 양방향의 관계를 작성하는 것이 익숙치 않은 경우 종종 발생하는 문제이다. User 클래스는 아래와 같이 고쳐서 Test 코드를 성공으로 돌려놓을 수 있다.

User.java

public class User {
   ... 생략
   public void sendFriendRequestTo(User receiver) {
       friends.add(receiver);
       receiver.getFriends().add(this); // 동기화 코드가 필요함
   }
   ... 생략
}

위의 코드는 친구 중복에 관한 처리 등을 비롯해 테스트 케이스 추가와 코드 보완, 리팩토링이 필요하지만 코드 소개의 목적이 TDD와 BDD의 비교이므로, 일단 이것으로 TDD에 대한 간단한 소개를 마치도록 한다.

 

BDD

 이번에는 똑같은 기능을 BDD로 작성해보도록 하자. BDD를 작성하는데 사용한 프레임웍은 JBehave 이다. 총 5계의 단계를 거쳐 작성을 하게 되는데 이 순서는 다음과 같다.

  1. 스토리 작성
  2. 시나리오를 실행시킬 Step 클래스(POJO)를 작성한다.
  3. Embeddable 클래스를 작성하여 관련된 설정을 지정한다.
  4. 시나리오를 실행시킨다.
  5. 결과를 확인한다.

 

스토리 작성

가장 먼저 스토리를 작성한다. 위에서 정의한 기능을 토대로 다음과 같이 작성해볼 수 있다. 

friend_request_story.story

Narrative:
사용자는,
친구를 맺기 위해,
다른 사용자에게 친구 신청을 할 수 있다.
Scenario: 친구 요청
Given ‘A’라는 사용자가 있다.
And ‘B’라는 사용자가 있다.
When 'A'가 'B'에게 친구 신청을 한다.
Then 'A'는 'B'와 친구가 된다.
Scenario: 친구 요청 (받는 경우)
Given ‘A’라는 사용자가 있다.
And ‘B’라는 사용자가 있다.
When 'B'가 'A'에게 친구 신청을 한다.
Then 'A'는 'B'와 친구가 된다.
And ‘B’는 ‘A’와 친구가 된다.

*두꺼운 글씨로 작성된 부분은 꼭 지켜줘야 하는 문법(JBehave 혹은 Grekin Language)이다.

 크게 2가지로 구성되는데, Narrative 부분은 테스트 대상이 되는 스토리를 설명하는 부분이다. 이 형식은 애자일 개발 방법에서 많이 사용하는 사용자 스토리(User Story) 작성 템플릿으로, 역할(Role) – 기능(Feature) – 목적(Benefit)의 요소로 구성되어 있다.

  • As a [역할]
  • I want [기능]
  • So that [목적]

 위의 형식이 기본 템플릿인데, 한글로 작성하였기 때문에 순서를 바꾸어 작성하였다.

 다음으로 Scenario 부분이다. Given에 주어진 조건을 적고, When에 테스트 하고 싶은 어떤 행위를 기술하면 된다. 그리고 마지막 Then에는 기대하는 결과를 작성하면 된다. 기본적인 형식은 다음과 같다.

  • Given [주어진 조건]
  • And [주어진 다른 조건] …
  • When [행위 또는 사건]
  • Then [결과]
  • And [다른 결과] …

스토리를 작성하는 방법에 대해서 자세히 알고 싶으면 다음의 글을 참조하도록 한다.http://dannorth.net/whats-in-a-story

 

Step 클래스 작성

 friend_request_story와 이름 구조를 맞춰 주어야 하므로, FriendRequestStep이라는 이름으로 다음과 같은 Step클래스를 작성하였다.

FriendRequestStep.java

public class FriendRequestStep {
   private UserRepository repository;
   @BeforeStories
   public void setUp() {
       repository = new UserRepository();
   }
   @Given("'$userName'라는 사용자가 있다.")
   public void givenThereIsUser(String userName) {
       User user = new User(userName);
       repository.save(user);
   }
   @When("'$senderName'가 '$receiverName'에게 친구 신청을 한다.")
   public void whenSendFriendRequest(String senderName, String receiverName) {
       User sender = repository.findByName(senderName);
       User receiver = repository.findByName(receiverName);
       sender.sendFriendRequestTo(receiver);
   }
   @Then("'$senderName'는 '$receiverName'와 친구가 된다.")
   public void thenTheyAreFriend(String senderName, String receiverName) {
       User sender = repository.findByName(senderName);
       User receiver = repository.findByName(receiverName);
       Assert.assertTrue(sender.isFriendWith(receiver));
   }
   // DB 관련된 사항이 결정되지 않았다고 가정하고 도우미 클래스를 만든다.
   private class UserRepository {
       private final List<User> userList;
       public UserRepository() {
           userList = new ArrayList<User>();
       }
       public void save(User user) {
           userList.add(user);
       }
       public User findByName(String userName) {
           for (User user : userList) {
               if (user.getName().equals(userName)) {
                   return user;
               }
           }
           return null;
       }
   }
}

우선, User 데이터들을 관리하는 모듈이 필요한데, 여기서는 DB Access(DAO, Repository 사용 여부 등) 관련 사항이 결정되지 않아서 UserRepository라는 Mock을 사용하였다. 이런 식으로, 아직 구현되지 않은 모듈이 있는 경우에도, 원래 구현하려던 기능에 집중하여 코드를 작성할 수 있다. 추후 DB관련 사항이 결정되면 UserRepository를 실제 모듈로 대체할 수 있을 것이다.

 @BeforeStory 부분은 시나리오를 실행하기 전에 환경적인 부분을 설정하는 곳이다. 물론, 데이터를 미리 설정하는 공간으로 활용할 수도 있지만, 필자는 주로 환경적인 부분을 만드는데 이를 활용하여 @Given과의 용도를 구분한다.

 @Given, @When, @Then은 story 파일에서 Given, When, Then을 매핑하는 애노테이션이다. 그리고 각 애노테이션 안에 story의 각 문장을 매핑하는 값들이 있다. 달러($)표시로 시작하는 부분은 story 파일에서 마음대로 값을 지정할 수 있는 부분을 의미한다. 이런 특징으로 인해, 하나의 매핑 메서드에 여러개의 문장을 다양한 값으로 대응시킬 수 있는데, 이는 JBehave가 주는 꽤나 좋은 이점이다. 프레임웍 없이 작성했다고 하면, 우리는 일일이 똑같은 테스트 메서드를 추가하여 그 안에 Given이나 When등을 작성해야 했을 것이다.

 실제로 Given에서 표현한 2개의 문장은, 하나의 메서드로 모두 수행 가능하다.

  • Step 메서드: givenThereIsUser
  • Scenario 문장
  • Given ‘A’라는 사용자가 있다.
  • And ‘B’라는 사용자가 있다.

만약, 한 명의 사용자를 더 두어 시나리오를 테스트하고 싶거나, 또 다른 시나리오를 추가하려는 경우 이러한 재사용은 점점 이점으로 다가올 것이다. 흔히, Step 클래스는 Story의 Type이며, Story는 이 시스템의 구체적 행위이자 인스턴스라고 표현하기도 한다.

 

Embeddable 클래스를 작성

여기서 설정 코드를 작성하는 것은 생략하도록 한다. 이 설정에서는 story를 step에 매핑하는 방식이라던지, 결과를 어떤 형태로 보여줄 것인지 등을 결정할 수 있다.

 

시나리오 실행

JUnit을 통해 우리는 결과를 확인할 수 있는데, 위의 경우 다음과 같은 결과를 확인할 수 있다.

 

결과 확인

(BeforeStories)Running story friends/friend_request_story.story(friends/friend_request_story.story)Scenario: 친구 요청Given 'Jobs'라는 사용자가 있다.And 'Gates'라는 사용자가 있다.When 'Jobs'가 'Gates'에게 친구 신청을 한다.Then 'Jobs'는 'Gates'와 친구가 된다.
 

코드를 통해 느껴본 TDD와 TDD

지금까지 친구 신청/확인 기능을 구현하는 TDD와 BDD에 대해서 살펴보았다. 위에서 살펴본 것처럼, TDD와 BDD의 의미 있는 차이라고 한다면, story 파일의 존재이다. 이것은 비 개발자와 소통하는 동시에 시스템의 행위를 보존해주는 도구로 사용될 수도 있다. 분명, 도표나 그림등을 통해서 더 많은 것을 쉽게 표현할 수도 있기 때문에, 시나리오로 모든 것을 표현하는 데에는 한계가 있다. 그럼에도 불구하고 필자는 코드를 작성하기 전에 이런 시나리오들을 간단히 작성해 보는 것을 좋은 개발 시작 지점으로 삼을 수 있었다. JBehave는 이것을 프레임웍에서 지원해주며, 이것이 BDD가 가진 주요 철학 중 하나이다.

더불어, 프레임웍을 통해서 TDD의 반복되는 코드 작업을 줄여주는 이점을 취할 수도 있다. 프레임웍을 사용하지 않는 경우, 여러 케이스를 표현하기 위해 중복되는 코드들이 나오기 마련이다. 이를 SetUp(JUnit에서는 @Before 애노테이션 사용)부분에 넣으면, 반복 작업은 줄지만 가독성이 떨어지고 점점 코드가 복잡해질 여지가 있다. 해서, 어느 정도의 반복작업을 하게 되는 것이다. 그런데 JBehave는 위에서 보듯 Step을 Type으로 작성하여, 여러 시나리오들을 좀 더 수월하게 테스트해볼 수 있었다. 이는 테스트 코드 관리의 부담을 줄여주는 하나의 방법이 될 수 있다고 본다.

그 외에, In-Out 방식과 시나리오 형태로 테스트 주도 개발을 할 수 있다는 점은 BDD(정확히는 JBehave 프레임웍이)가 강제하는 형식이다. 물론, Out-In 방식이 유리한 경우도 있고, 시나리오가 아닌 단순 스펙 확인 방식이 좋은 경우도 있다. BDD 프레임웍이 이런 유연성을 제한하는 것은 분명 한계일 것이다. 그럼에도 불구하고, BDD가 가진 철학들은 한 번은 적용해볼 만한 내용일 것이다.

IntelliJ Mac에서 Eclipse 단축키 그대로 사용하기(change Ctrl to Command)

1 - Grab this xml file (Eclipse on Mac):

https://github.com/thatha/IntelliJ-IDEA-Eclipse-on-Mac-Keymap/blob/master/Eclipse%20on%20Mac.xml

2 - Save the file to this directory:

~/Library/Preferences/IntelliJIdea11/keymaps/

note - this directory may vary depending on your system/version of IntelliJ. According to this link:

http://www.jetbrains.com/idea/webhelp/configuring-keyboard-shortcuts.html

It should be of the form: ~/Library/Preferences/.IntelliJ IDEA/keymaps/

Dig around and you will find it!

3 - Open IntelliJ, navigate to Preferences ( cmd + , ). Under IDE Settings > Keymap, select "Eclipse on Mac" from the Keymaps drop down list.

svn 사용자 변경

  1. - Win XP
    • 시작 - 실행 - %HOMEPATH%\Application Data\Subversion\auth\svn.simple 폴더의 파일 삭제
  2. - Win 7
    • C:\Users\%사용자계정%\AppData\Roaming\Subversion\auth\svn.simple 파일 삭제

 

TDD Test Double이란...

1. Test Double

- 테스트를 수행하기 위해서 실제 컴포넌트 역할을 대체하는 기능을 가진 객체나 컴포넌트를 말한다.

2. Test Double 분류

  • Dummy Object : 가장 기본적인 유형으로, 매개 변수 값과 같이 작업을 수행하는 메소드가 없는, 값 전달만을 위한 객체를 말한다.
  • Test Stub : 아직 개발되지 않은 클래스나 메소드가 처리 후 리턴해야 하는 값을 전달해주는 역할을 한다. 대부분 그 값은 하드 코딩되어 있다. 
  • Test Spy : Stub과 비슷하지만, 어떤 작업을 수행했는지에 대한 이력을 남긴다는 점이 다르다. Stub과 같은 역할을 하는 척하지만 이름 그대로 스파이 같은 행동을 한다. 
  • Mock Object : Dummy, Stub, Spy를 통합해 놓은 것과 비슷하다 볼수 있다. 보통 라이브러리를 사용하여 동적으로 데이터를 처리해줄 부분을 생성한다. 즉, Stub기능에 검증(assertion) 기능을 추가한 형태라고 생각하면 된다. 
  • Fake Object : 테스트에 직접적인 연관은 없지만, 테스트하고자 하는 시스템과 연계되는 시스템이 너무 느리거나, DB가 아직 구성되지 않았을 경우에 해당 부분이 실제 존재하는 것처럼 하는 부분을 말한다. 

 

프로그래머란..

1. 꾸준히 한다.

.프로그래밍언어도 언어(?)라서, 하루에 몰아서 하는 것보다 매일 꾸준히 하는 것이 중요하다. 경력이 많은 프로그래머들도 몇달만 코딩을 안해도 감이 많이 떨어지는 것을 느낀다. .특히 프로그래밍을 처음 배우는 사람이라면, 꼭 컴퓨터 앞에 앉지 않더라도 책을 항상 가까이해서 문법 및 표현에 익숙해지도록 하는 것이 중요하다. 자주보는 것이 중요하다.

2. 반복해서 한다.

.단지 태권도교본을 잘이해했다고 해서 멋진 발차기를 기대할수 없는 것처럼, 책의 내용을 잘 이해했다고 해서 하루아침에 프로그래밍을 잘할수 있는 것은 아니다. .이해한 내용을 바탕으로 수많은 반복연습을 통해서만 지식을 진정한 자신의 것으로 만들 수 있다. (같은 예제를 공부하더라도 이리저리 조금씩 변경해서 공부하는 것이 좋다.) .처음 2~3번은 자세히 보고, 그 다음 부터는 하루에 10분간 10페이지를 훑어보는 식으로 반복하자. 몇달안에 책에 있는 모든 목차와 예제의 위치와 주요내용을 모두 파악할수 있을 것이다. (적어도 언어책 한권, 데이터베이스책한권 정도는 이렇게 할 필요가 있다.)

3. 좋은코드를 많이 보고 따라한다.

.이미 수많은 선배들이 여러문제들에 대한 코딩을 다 작성해 놓았다. 새로운 방법으로 문제를 풀겠다고 도전하는 것은 별 의미가 없다. "이럴때는 이렇게 하는 구나..."라는 것을 배우고 유사한 상황에서 활용하면 되는 것이다. 여러분들이 해야할일은 이러한 경험들을 많이 쌓아 나가는 일이지, 기존과는 다른 새로운 코딩방식을 만들어 내는 것이 아니다. .좋은 코드는 보기에도 좋다. 잘정리되어 있고, 별로 특별한 것이 없다. 프로그래밍의 각요소들을 잘이해하고, 각 요소들을 적재적소에 바르게 사용하면 되는 것이다. 단지 소스의 라인수를 줄인다고해서 좋은 코딩이 아닌것이다. 로직이 소스코드에 잘드러날수있게 쉽고 평범하게 작성하는 것이 좋은 코드인 것이다. 이창호의 바둑이 평범하듯이...

4. 기본에 충실한다.

.빨리 프로그래밍을 배워서 뭔가 해보고 싶은 여러분들의 마음을 이해하지 못하는 것은 아니다. 그러나, 프로그래밍 하루이틀 할 것도 아니고... 처음에 기본을 잘배워놓지 않으면, 그 이후에는 기회가 잘 없다. 실무에서는 매일 개발하기 바쁘고, 새로운 기술 배우기 바쁘고... .배울것이 많다고 생각할지 모르나, 실제로 원리는 모두 같다고 해도 과언이 아니다. 하나를 깊이있게 파고들면 나머지는 다 여러분 손에 있을 것이다.

5. 코드를 작성하기전에 순서도를 그린다.

."프로그래밍 = 코딩"이 아니라 "프로그래밍 = 로직설계 + 코딩"이다. 필자가 생각하는 로직설계 와 코딩간의 비율은 8:2정도이다. .포토샵만 잘한다고 디자이너가 아니라는것은 여러분들도 잘알고 있을 것이다. 새로운 기술이나 프로그램을 공부하는 것도 중요하지만,  어떤 과제가 주어졌을때 이를 잘 분석하고 설계하는 능력을 장기적으로 키워나가도록 노력해야할 것이다.(다양한 주제에 대해서 문제를 풀어보고 다양한 종류의 책을 읽자.) .문제를 구성하고 있는 주인공들을 찾아서 나열해보라. 그리고 이들간의 관계는 무엇이고, 규칙은 무엇인지 적어보라.(머릿속으로만 생각하지말고!!!)

6. 주석을 가능한한 많이 적는다.

.주석은 매우 유용하고도 중요한 요소이다. 그럼에도 불구하고 많은 사람들이 이를 소홀히 한다. 자신이 작성한 코드도 몇일만 지나면 이해가 안되는 경우가 많다. 적어도 이해하는데 시간이 걸린다. 주석은 이러한 시간들을 절약해줄것이며, 보다 에러가 적은 코드를 작성하는데 도움을 줄 것이다. 특히 여러사람이 공동작업을 하는 경우에는 더욱 더 중요하다. 서로를 위해서... .작업과 관련된 가능한한 많은 정보를 주석에 담도록 하자.

7. 작업일지를 작성한다.

.과학자들이 매일 연구한 내용을 일지로 적듯이 여러분들도 일지를 적어보자. 오늘은 이렇게 저렇게 해봤는데 잘안되었다... xxx.java의 코드를 이렇게 바꾸었다. 몇시몇분에 xx로 백업받아 놓았다... 라는 식으로 가능한한 자세히 적도록 한다. 이렇게 함으로써 여러분들의 경험을 기록 으로 쉽게 보관할수 있으며, 문제해결에 많은 도움이 된다.

8. 자신의 소스를 가꾼다.

.보통 코딩을 마치고 나면, 모든 것을 덮어두곤 한다. 원하는 결과를 얻었다고 거기서 그치지말고 이제 로직과 코드를 보다 효율적으로 개선할 방법이 없는지 고민해보자. 글을 써놓고 좋은 글로 만들기 위해 읽고 또 읽고 다듬듯이 코드를 다듬어보자. 여러분들의 코드를 구사하는 능력이 보다 향상되어가는 것을 느낄 수 있을 것이다. .여러분들을 위한 제안은 작은 프로그램을 만들어서 오랜기간동안 점차 발전시켜 나가는 것이다. 새로운 기능들을 하나씩 추가해가고, 기능을 발전시켜나가보자. 이과정을 통해서 여러분들의 실력 은 몰라보게 향상될 것이다.

9. 생각하라.

.항상 머릿속에 한 가지 문제를 준비하라. 지하철을 기다리거나, 화장실에서 볼일 볼때 문제를 풀어 보자. 유레카를 외치고 뛰어나올지도...^^;

10. 좋은 책을 선택한다.

.공부를 시작할때 제일 먼저 하는 일은 아마도 책을 고르는 일일 것이다. 보통 책하나에 수십시간을 학습하게 되는데, 책을 잘못선택한 경우 수십시간과 노력을 허비하는 셈이다. 바른 책을 고르는 일은 쉬운일이 아니지만, 최소한 몇시간을 투자해서 최선의 선택을 하도록 노력 해야 수십시간을 허비하는 일이 없을 것이다. .책을 고르는 법은 여러가지가 있겠으나, 가장 중요한 것은 본인이다. 서점에서 같은 종류의 몇가지 책을 놓고 서로 비교해보면, 시간을 들인 만큼 보다 나은 선택을 할 가능성이 높아진다. .많은 컴퓨터 서적이 독자들의 선택을 어렵게 하고, 컴퓨터 업계 특성상 좋은책을 만들기 보다 빨리찍어서 파는 것이 더 중요해진 요즘. 독자들의 바른 선택이 보다 나은 책이 출판되는 것을 가능하게 한다는 것을 알았으면 한다

코드잘 짜기

1. 설계는 프로그래밍에 있어 가장 중요하다.
2. 만들려는 것을 그림으로 그려라
3. 80%의 머리를 쓰면 20%의 비용이 절약되고 20%의 머리를 쓰면 80%의 추가 비용이 들어간다.
4. 프로그램 개발 속도를 좌우하는 것은 사람수도 잡다한 지식도 아닌 기본적인 문법이다.
5. 모듈적(Component)으로 개발하고 다른 시스템에 대한 영향은 최대한 줄여라
6. 메모리 문제는 메모리 관리를 고려해야 발생하지 않는다( pool, smart_ptr )
7. 기본적인 규칙은 지켜라. 특히 CQS(command query separator)는 특히 중요하다.
8. NVI(non virtual interface)는 매우 유용하다.
9. 개발을 위한 개발 환경을 만들어라. Log System, Bug Traps(LIB X), Reload 등의 기능들은 유용하다.
10. 버그의 85%는 잘못된 읽기와 쓰기 그리고 알고리즘에서 나온다( 트랩을 설치하자 )
11. C++ 에서 meta programming(template), pure programming(functor - pure function)은 능률을 높이고 버그를 줄여준다.
12. 데이터와 컨트롤 객체(interface)는 분리하라.
13. 다양한 프로그램들이 사용하는 기법은 언제든지 내가 만드는 프로그램에 적용될 수 있다. - 이벤트 드리븐, 데이터지향 드리븐, 파이프라인, 메세지드리븐 아키텍쳐, 가비지컬렉션 등
14. 버그를 유발할만한 데이타라면 코드가 아닌 데이터로 만들고 내가 아닌 다른 사람이 컨트롤하도록 하라.
15. 라이브러리를 사용하라.
16. 자기자신이 만든 코드를 기억하기 힘들고 사용하기 힘들다면 남들이 이해할 것이란 확신을 가지지 마라.
17. 파이프라인, 컴포넌트 레이아웃 등의 기법은 버그를 보다 쉽게 찾을 수 있도록 도와준다.
18. 코드는 반드시 재사용하도록 만들고 고려한다.
19. 코드가 주석이며 코드로는 이해하기 힘든 곳은 반드시 주석을 남긴다.