스탠포드식 쉬운 프로그래밍 / 코딩 첫걸음 (5) - 메소드

스탠포드식 쉬운 프로그래밍 / 코딩 첫걸음 (5) - 메소드 본문

스탠포드식 쉬운 프로그래밍 / 코딩 첫걸음 (5) - 메소드

KRONNA 2016.07.01 10:00


카렐은 딱 네가지 기능만 할 줄 알지만, 여러분이 그 네가지 기능을 어떤 순서로 몇번이나 반복하는가에 따라 다양한 기능을 수행할 수 있죠. 마찬가지로 여러분의 컴퓨터에 있는 마법같은 프로그램들도 정말 간단한 기능들을 창의적으로 조합한 것 뿐입니다. 네가지 기능으로도 카렐은 많은걸 할 수 있지만, 카렐이 다른 기능을 배울 수 있다면 신문을 가져오는 과제가 훨씬 더 간단하지 않았을까요? 예를 들어 왼쪽으로 3번 도는 대신, 바로 오른쪽으로 도는 기능을 안다면 말이죠. 이번 강의에선 카렐에게 새로운 기능을 가르치는 방법을 배워보겠습니다.




카렐에게 오른쪽으로 회전하는 기능을 가르쳐봅시다. 왼쪽으로 도는 기능이 "turnLeft();"니까 오른쪽으로 도는 기능은 "turnRight();"라고 부르도록 하죠. 이렇게 작성하면 이클립스는 turnRight(); 아래 빨간색 밑줄을 통해 우리가 카렐이 할 줄 모르는 기능을 불러내려 하고 있다고 알려줍니다. 강제로 실행하려하면 에러 메세지가 뜨며 실패하고 말이죠. (만약 실행이 된다면 코드에 public class CollectNewspaper extends 다음에 "SuperKarel"이라 적혀있는 것을 "Karel"이라고 바꿔주세요. SuperKarel은 우리가 이번 글에서 카렐에게 가르칠 turnRight와 turnAround를 이미 할 줄 아는 똑똑한 카렐입니다. 다음 과제부턴 여러분이 turnRight와 turnAround를 다시 가르치지 않아도 되도록 슈퍼카렐을 사용할 거에요.)




프로그래밍에선 기능을 "메소드"라고 부른답니다. (자바에선 "메소드", C언어에선 "펑션(함수)"라는 표현을 사용합니다). 우리가 turnRight(); 기능을 카렐에게 가르치는건 "turnRight(); 메소드를 새로 작성한다"고 얘기하면 됩니다. 카렐을 위해 새로운 메소드를 작성하려면 우리가 코드를 작성했던 public void run() {} 블락 밖에 void 메소드_이름() {} 라고 적어주세요. (혹시 까먹으셨을까봐 다시 설명드리자면 블락은 "{"와 "}" 사이를 뜻합니다). 왜 void를 적는가에 대해서는 아직 걱정하지 마세요. 지금은 카렐을 위한 메소드는 이름 앞에 "void"를 붙인다고만 기억해주세요!




turnRight 메소드는 오른쪽으로 회전하는 기능입니다. 신문 가져오기 과제에서 카렐이 오른쪽으로 돌아야할 때 어떻게 명령했죠? 맞습니다. 왼쪽으로 회전하는 turnLeft 메소드를 3번 명령했습니다. 카렐 프로그램을 실행한다는 뜻은 public void run() 메소드 블락 안에 있는 명령들을 수행한다는 의미죠. public void run() 메소드를 실행하는 도중 turnRight();처럼 카렐이 모르는 메소드가 있다면 카렐은 아래 그 이름의 메소드가 설명되어 있는지를 확인합니다. 우리는 public void run() {} 블락 아래에 void turnRight() {} 블락으로 turnRight();를 설명해놓았죠. 그래서 위에 코드를 실행하면 카렐은 turnRight();를 실행하라는 의미를 turnLeft();를 3번 실행으로 받아들입니다. 위의 코드를 따라하고 한번 실행해보세요.




여기서 잠깐! 연습 문제: 인생을 살다보면 가끔씩 도저히 우회전으로는 해결되지 않는 상황이 오기 마련이죠. 거친 세상을 살아갈 카렐에게 미리 뒤로 돌아보는 turnAround 기능을 가르쳐주도록 해요. 위에서 배운 내용을 토대로 여러분이 한번 직접 turnAround 메소드를 적어보세요. 정답은 댓글로 적어두겠습니다. ^^


* 위의 코드에서 수정하지 않고 그대로 실행하려하면 이클립스가 실행을 시켜주지 않습니다. public void run()에서 turnAround() 메소드를 불렀지만 코드 어디에도 turnAround() 메소드를 설명하지 않았기 때문이죠! turnRight()를 적었을 때와 똑같은 방법으로 turnAround() 메소드를 적으시면 됩니다.




여러분이 프로그래밍을 계속 하시다보면 수백 수천줄에 달하는 코드를 직접 작성하시게 될겁니다. 그때 여러분이 코드를 더 빨리 작성할 수 있기 위해서, 혹은 남들이 여러분의 코드를 읽었을 때 여러분의 의도를 이해할 수 있도록 도와주기 위해선 코드에서 여러번 반복되는 기능들을 새로운 메소드로 적어줘야 합니다. 예를 들어 카렐의 신문 가져오기 프로그램에는 오른쪽으로 돌기 위해 turnLeft();를 3번 반복하는 명령이 여러번 일어나니까 turnRight(); 메소드를 작성하고, 코드에서 turnLeft();가 3번 반복되는 곳을 모두 turnRight();로 바꿔주어야 하는것이죠. 이런식으로 길고 읽기 어려운 코드를 새로운 메소드의 도움으로 간결하게 새로 적는 것을 프로그래밍에선 "decomposing (디콤포징)"이라고 한답니다!




여러분이 저번에 작성한 신문을 가져오는 카렐 코드를 완벽히 디콤포징 해보세요. 논리적으로 하나의 기능을 수행하는 여러줄의 코드는 하나의 새로운 메소드로 묶어주는 것이 좋습니다. 예를 들어 왼쪽으로 회전하는 코드 3줄은 "왼쪽으로 3번 회전하는 것"이 목적이 아니라 "오른쪽으로 회전"하는 것이 목적이니까 묶어주는 것이 좋죠. 그리고 앞으로 재사용하게될 기능들은 새로운 메소드로 만들어두는것이 좋습니다. 오른쪽으로 회전하거나 뒤로 돌아보는 기능은 카렐이 다른 문제를 해결할 때도 유용할 가능성이 높으니 새로운 메소드로 만들어 두는것이 좋다고 볼 수 있습니다. 하지만 카렐이 "앞으로 걸어가서 오른쪽으로 회전하고 앞으로 전진한 뒤 옆으로 돌아서 신문까지 도착"하는 기능을 하나의 메소드로 만들어도 다른 문제를 해결할 때 다시 그대로 사용할 확률이 낮으니 새로운 메소드로 만들지 않아도 괜찮습니다. 




코드는 두가지 잣대로 평가할 수 있습니다. 1번은 기능성, 즉 코드가 문제를 제대로 해결할 수 있는가 입니다. 스탠포드가 매우 강조하는 2번 잣대는 바로 스타일입니다. 아마추어 개인 개발자들도 프로그래밍을 조금만 배우면 원하는 기능을 수행하는 작은 프로그램들을 얼마든지 만들 수 있지만, 코드를 간결하게 쓰고 남들이 읽었을 때 이해하기 쉽게 쓸 수 있어야 다른 개발자들과 함께 큰 규모의 프로그래밍 프로젝트를 진행할 수 있기 때문이죠. 지난 글에서 아무것도 할 줄 모르는 카렐이 신문을 가져오도록 코딩을 한 것에 비하면 카렐이 이미 할 줄 아는 기능을 새로 가르친 이번 강의가 비교적 덜 흥미로울지도 모릅니다. 하지만 이런 작은 차이가 명품 프로그래머를 만들죠! ^^


정말 중요한 기술인 "새로운 메소드 작성하기"는 자신 있으신가요? 다음 강의에선 여러분이 미리 시킨대로만 무작정 명령을 수행하는게 아니라 카렐이 그때 그때 상황을 보고 스스로 판단하라고 지시할 수 있는 "if문 (조건문)"에 대해서 배워보겠습니다!


Stanford CS106A 수업에 대한 모든 권리는 스탠포드 대학교가 가지고 있습니다. "스탠포드식 쉬운 프로그래밍 / 코딩 첫걸음"은 스탠포드 대학교의 CS106A 수업을 남녀노소 누구나 쉽게 배울 수 있도록 각색하고 한국어로 번역한 내용이며, 본글에 대한 모든 권리도 스탠포드 대학교가 가지고 있습니다. CS106A 수업에 사용되는 교재인 Karel the Robot Learns Java와 The Art & Science of Java를 작성해주신 Eric Roberts 교수님과 CS106A 수업을 가르치고 계시며 해외로 수업 내용 반출을 허락해주신 Mehran Sahami 교수님 그리고 Marty Stepp 교수님께 감사드립니다.


스탠포드 대학교에서 컴퓨터 과학을 전공중인 박준원이라고 합니다. 질문은 junwonpk@stanford.edu로 보내주시면 24시간 내로 답변 드리겠습니다. 설명을 따라했는데도 똑같이 작동하지 않거나 설명에 이해하기 어려운 부분이 있으면 주저하지 말고 질문 보내주세요! ^^

5 Comments
댓글쓰기 폼