소프트웨어 공학 Lecture #8: 코딩 안 병 익 강의 블로그 Mobilecom.tistory.com.

Slides:



Advertisements
Similar presentations
Copyright © 2006 The McGraw-Hill Companies, Inc. 프로그래밍 언어론 2nd edition Tucker and Noonan 5 장 타입 “ 타입은 컴퓨터 프로그래밍의 효소이다 ; 프로그래밍은 타입을 통해 소화할만한 것이 된다.” 로빈.
Advertisements

Vision System Lab, Sang-Hun Han
제 3 장 변수와 자료형.
어서와 Java는 처음이지! 제2장 자바 프로그래밍 기초.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제3장 배열과 포인터.
제 1장 C 언어의 소개.
Internet Computing KUT Youn-Hee Han
제 4장 문 장 배정문 혼합문 제어문 표준 입출력.
제 2 장 배열과 스트링.
제6장 제어(Control) 6.1 구조적 프로그래밍(Structured Programming)
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
10장 예외 처리 프로그래밍 언어론 10.6 Pascal과 C의 에러 처리 10.1 설계 주제 10.2 PL/I의 예외 처리
16강. 자바 빈 빈 이란? 빈 만들기 빈 관련 액션 태그(useBean, getProperty, setProperty)
Internet Computing KUT Youn-Hee Han
2주 실습강의 Java의 기본문법(1) 인공지능연구실.
Chapter 02 자바 기본구조 자바 프로그래밍의 기초적인 문법을 소개
8. 객체와 클래스 (기본).
제7장 제어구조 I – 식과 문장.
[ 단원 08 ] 예외처리와 스레드.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
연결리스트 (Linked List) 충북대학교 컴퓨터공학과 서 영 훈.
JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심.
배열, 포인터, 참조 배열은 같은 형을 가지는 변수들의 묶음이다..
자바 5.0 프로그래밍.
Choi, Namseok Java 기초 (Java의 제어문과 배열) Choi, Namseok
Power Java 제15장 예외 처리 (Exception Handling).
스택(stack) SANGJI University Kwangman Ko
이쁜 코드 작성하기 마이에트 레이더즈팀 중원.
7.1 프로그래밍 원리 7.2 코딩 스타일 7.3 리팩토링 7.4 코드 품질 향상 방법
3장. 포인터, 배열, 구조체 포인터, 배열, 구조체 학습목표 기본적 데이터 타입
명품 Java Programming.
10장 다중 스레드 10.1 스레드 개요 10.2 Thread 클래스 10.3 스레드 생성
2장 자바환경과 자바 프로그램 2.1 자바 개발 환경 2.2 자바 통합환경 2.3 자바 응용 프로그램과 애플릿 프로그램
DataScience Lab. 박사과정 김희찬 (월)
인터페이스(Interfaces) 강원대학교.
C++ 개요 객체지향 윈도우즈 프로그래밍 한국성서대학교 유일선
제 3 장 상수와 변수
6장 객체-지향 설계 ①.
제 4주 2014년 1학기 강원대학교 컴퓨터학부 담당교수: 정충교
4장 제어문 선택문: if 문, if – else 문, switch 문
제1장 서론.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
adopted from KNK C Programming : A Modern Approach
6장 객체-지향 설계 ①.
배열과 연결리스트 연결리스트 배열 메모리 할당이 연속적이어서 인덱스 사용시 검색이 빠르다.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
03. 안드로이드를 위한 Java 문법 제목. 03. 안드로이드를 위한 Java 문법 제목.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
Java의 정석 제 2 장 변수(Variable) Java 정석 남궁성 강의
[CPA340] Algorithms and Practice Youn-Hee Han
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Java Chapter 4 ~ 주차.
컴퓨터공학실습(I) 3주 인공지능연구실.
Java의 정석 제 4 장 조건문과 반복문 Java 정석 남궁성 강의
3장. 클래스의 기본.
Java 3장. 자바의 기본 구조 I : 변수, 자료형, 연산자 public class SumTest {
C89(C++03) 프로그래밍 (Part 2) 7 배열 8 변수 범위 9 포인터 10 유도 자료형.
[ 단원 06 ] 상속과 다형성.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
자바 5.0 프로그래밍.
Chapter 4 클래스 작성.
제5장 디버깅과 추적 문봉근.
이번 시간에는... 지난 시간까지 2회차에 걸쳐 WML의 택스트 포맷, 이미지 처리, 페이지 이동, 태스크 수행과 이벤트 처리 및 WML 사용자 Input 처리 태그 등, WML 개발에 대해서 알아보았습니다. 이번 시간에는 2회차에 걸쳐, WML 스크립트 개발에 대해서.
개정판 누구나 즐기는 C언어 콘서트 제10장 문자열 출처: pixabay.
DataScience Lab. 박사과정 김희찬 (화)
C# 09장. 클래스와 객체.
1. 객체-지향 프로그래밍.
Presentation transcript:

소프트웨어 공학 Lecture #8: 코딩 안 병 익 강의 블로그 Mobilecom.tistory.com

학습 목표 2 코딩 원리 코딩 스타일 리팩토링 코드 품질 향상 방법

코딩 단계 코딩 작업 각 모듈에 대한 원시코드를 작성하고 모듈 안에 포함된 오류를 검출하는 단계 코딩 원칙 설계를 철저히 반영시킨다 원시코드는 간단 명료하도록 한다 디버깅이 쉽게 시험이 용이 수정이 간편 설계 사양 원시코드 목적코드 코딩 컴파일 디버깅 모듈 테스트 3

Weinberg 의 실험 상반되는 원칙을 잘 조화시켜야 함 결과 (1 = 최적 ) O1O2O3O4O5 코딩 작성에 드는 노력의 최소화 (O1) 문장 수의 최소화 (O2) 소요 메모리 최소화 (O3) 프로그램 명확성의 극대화 (O4) 출력 명확성의 극대화 (O5)

8.1 코딩 원리 코딩 정의 분리하여 구현할 수 있는 작은 단위를 프로그래밍 하는 작업 절차적 방법 : 모듈 안의 함수 작성 객체지향 방법 : 개별 메소드의 프로그래밍 코딩의 목표 설계 명세에 나타낸 요구를 만족하는 프로그램을 작성  요구분석서, 아키텍처 설계서 참조 오류가 적은 품질 좋은 프로그램 작성  원리와 가이드 준수 5

코딩 과정 상세설계 - 의사코드 - 흐름도 각 프레임워크 패키지 또는 애플리케이션 패키지에 대하여... 모든 클래스에 대하여... 요구사항 2. 메소드를 구현 1. 코딩 표준을 정의 4. 단위 테스트 3. 클래스 인스펙션 5. 통합을 위하여 릴리스 아키텍처 6

코딩 작업 순서  원시코드를 같은 스타일로 만들기 위한 코딩 표준 작성  아키텍처 설계 결과를 근거로 프레임워크 패키지와 응용 패키지를 구분. 요구사항과 상세설계를 반영하여 메소드 코딩  인스펙션  클래스 단위로 테스트  통합을 위하여 릴리스 7

코딩 오류 (1) 오류를 피하기 위하여 오류 타입을 잘 알고 있어야 함 메모리 누수 메모리가 프리되지 않는 현고 프로그램에 계속 할당되는 현상 char * foo(int s) { char *output; if ( s > 0 ) output = (char *) malloc (size); if ( s == 1 ) return NULL; /* if s == 1 then memory leaked */ return(output); } 8

코딩 오류 (2) 중복된 프리 선언 이미 프리로 소멸된 자원을 또 다시 프리로 선언하는 경우 NULL 의 사용 NULL 를 포인트하고 있는 곳의 콘텐트를 접근하려 하면 오류 Alias 를 사용하는 경우 유의 main() { char *str; str = ( char * ) malloc (10); if ( global == 0 ) free(str); free(str); /* str is already freed } 9

코딩 오류 (3) 별칭의 남용 서로 다른 주소값을 예상하고 사용한 두 변수가 Alias 로 선언된 경우 예 ) strcat(src, destn) src 와 destn 이 alias 로 선언된 경우 char *ch = NULL; if ( x > 0 ) { ch = 'c'; } printf("\%c", *ch); // ch may be NULL *ch = malloc(size); ch = 'c'; // ch will be NULL if malloc returns NULL 10

코딩 오류 (4) 배열 인덱스 오류 인덱스 한도를 벗어난 배열 수식 예외 오류 0 으로 나누는 오류, 변동 소수점 예외 오류 하나 차이에 의한 오류 예 ) < N <= 오류 if( number = SSN ) { == 의 오류 dataArray[80]; for ( i=0; i <= 80; i++ ) dataArray[i] = 0; 11

코딩 오류 (5) 사용자 정의 자료형 오류 스트링 처리 오류 strcpy, sprintf 등 많은 스트링 처리 함수 매개 변수가 NULL 이거나 스트링이 ‘ \0 ’ 이 아니거나 typedef enum {A, B, C, D} grade; void foo(grade x) { int l, m; l = GLOBAL_ARRAY[x - 1]; // Underflow possible m = GLOBAL_ARRAY[x + 1]; // Overflow possible } 12

코딩 오류 (6) 버퍼 오류 버퍼 오류시 리턴 주소가 반환되는 것을 이용하여 해킹에 이용될 수 있음 void mygets(char *str) { int ch; while ( ch = getchar() != '\n' && ch != '\0' ) *(str++) = ch; *str = '\0'; } main () { char s2[4]; mygets( s2 ); } 13

코딩 오류 (7) 동기화 오류 다수의 스레드가 있는 병렬 프로그램에서의 오류 데드락 다수의 스레드가 서로 자원을 점유하고 릴리스 하지 않는 상태 레이스 컨디션 두 개의 스레드가 같은 자원을 접근하려 하여 수행 결과가 스레드들의 실 행 순서에 따라 다르게 되는 경우 모순 있는 동기화 공유하는 변수를 접근 할 때 로킹과 언로킹을 번갈아 할 때 일어나는 오류 14

구조적 프로그래밍 정의 프로그램의 제어흐름을 선형화시켜 논리구조가 명백하게 하려는 코딩 규 율 구조적 프로그램 세가지 제어구조 ( 순차, 선택, 반복 ) 로 무조건적 goto 에 의한 복잡한 제어흐 름을 방지 제어구조가 하향식 stepwise refinement 를 이용한 프로그래밍 Proper Program 단일입구, 단일 출구 모든 노드는 입구에서 도달할 수 있는 경로가 있어야 모든 노드는 출구까지 도달할 수 있는 경로가 있어야 15

Go To 문의 사용 구조적인 제어흐름을 해치지 않는 범위에서 사용 DO 50 I=1, COUNT. IF (ERROR1) GO TO 60. IF (ERROR2) GO TO CONTINUE 60 {Code for Error1 handling} GO TO {Code for Error handling} 80 CONTINUE I = 1for I = 1 to TableSize do while I <= TableSize and if Table(I) = Target then goto Found Table(I) <> Target do I = I + 1 NotFound: {code for Target not found} if I > TableSize then Found: {code for Target found} {code for target not found} else { code for Target found} (a) 구조적 코딩 (b) goto 의 사용 16

정보 은닉 일반적으로 어떤 정보에 대하여 제한된 방법으로만 사용됨 예 : 회계 원장 ( 차변, 대변, 잔고확인 ) 모든 차변을 더하여 대변의 합으로 나누는 것과 같은 오퍼레이션은 적용되지 않음 자료구조 정의 내부의 정의가 시스템의 다른 부분으로부터 감추어져 있어야 장점 결합도를 줄이고 시스템의 유지보수를 쉽게 만듦 데이터를 관리하는 관점과 데이터를 사용하는 관점을 분리할 수 있음 언어자체의 메커니즘 17

8.2 코딩 스타일 스타일 어떤 작업이나 선택에서 일관된 유형 예 ) 패션 스타일 프로그래밍 스타일 간결하고 읽기 쉬운 코드 문형 구조, 원시 코드의 편집 상태 등에 의하여 가독성이 달라짐 설계에 의하여 좌우됨 모듈화 – 높은 응집력, 낮은 결합도 18

명명 규칙 명명 원칙 - 의미 있게 if (a < 65) { // What property does 'a' describe? y = 65 - a; // What is being calculated here? } else { y = 0; } if (age < RETIREMENT_AGE) { yearToRetirement = RETIREMENT_AGE - age; } else { yearToRetirement = 0; } 이름만 보아도 무엇인지 ( 클래스, 멤버함수, 상수 등 ) 알 수 있게 19

이름 붙이기 단어 붙이기 예 ) cylinderLength 클래스 이름은 대문자로 시작 변수 이름은 소문자로 시작 상수 이름은 모두 대문자로 예 ) MAX_NAME_LENGTH static final 을 사용 예 ) static final String XML_DOCUMENT = ‘text/XML”; 데이터의 이름은 underline 예 ) _timeOfDay 20

이름 붙이기 임시변수 문자형 c, d, e 좌표 x, y, z 예외 e 그래픽 g 객체 o 스트림 in, out, inout 스트링 s 약자의 사용 SetDSTOffst() setDstOffset() loadXMLDocument() loadXmlDocument() 21

타입 이름 클래스와 인터페이스. 이름의 첫 글자는 대문자 public class PrintStream extends FilterOutputStream {... } public interface ActionListener extends EventListener {... } 클래스 이름은 명사 인터페이스의 이름은 명사나 형용사 능력을 나타내는 인터페이스의 이름은 형용사 “able”, “ible” 22

메소드 이름 첫 단어는 소문자, 연속되는 단어의 첫 글자는 대문자 class MyImage extends Image { public MyImage() {... } public void flush() {... } public Image getScaledInstance() {... } 23

메소드 이름 메소드와 오퍼레이션은 일반적으로 동작을 나타냄 동사로 표현 class Account { private int balance;... public void withdraw(int amount) { deposit(-1 * amount); } public void deposit(int amount) { this.balance += amount; } 24

메소드 이름 boolean isValid() { return this.isValid; } String getName() { return this.name; } String getAlias(int index) { return this.aliases[index]; } void setValid(boolean isValid) this.isValid = is.Valid; } void setName(String name) { this.name = name; } 25

변수 이름 첫 문자는 소문자, 연속되는 단어의 첫 문자는 대문자 class Customer {... private Address address; private Phone daytimePhone;... public Address setAddress(Address address) { Address oldAddress = this.address; this.address = address; return oldAddress; }... public void setDaytimePhone(Phone daytimePhone);... }... } 26

상수이름 대문자로 하되 단어 사이에는 밑줄로 연결 class Byte { public static final byte MAX_VALUE = 255; public static final byte MIN_VALUE = 0; public static final Class TYPE = Byte.class; } 27

포인터와 레퍼런스 C++ 에서는 매개변수를 레퍼런스 타입으로 사용 swap(int &x, int &y) { int t; t=x; x= y; y=t; } new() 의 사용을 피하고 메모리 관리 루틴 getNewCObject() 와 같은 팩 토리 멤버함수 사용 28

자료형 객체 타입을 리턴하는 클래스는 캐스트를 사용 public class Queue { public void enque(Object object) {... }; public Object dequeue() {... }; } public class OrderQueue { private Queue queue; public OrderQueue() { this.queue = new Queue(); } public void enqueue(Order order) { this.queue.enqueue(order); } public Order dequeue() { return (Order)this.queue.dequeue(); } 29

문장과 수식 되풀이 되는 문장 메소드나 클래스로 패키지화 블록 문장의 사용으로 dangling else 문제 해결 if (x >= 0) if (x > 0) positiveX(); else // Oops! Actually matches most recent if! negativeX() if (x >= 0) { if (x > 0) positiveX(); } else { negativeX(); // This is what we really wanted! } 30

문장과 수식 괄호를 이용 오퍼레이션의 순서 명확히 // Extraneous but useful parentheses. int width = (( buffer * offset ) / pixelWidth ) + gap; 객체 동일설 체크 Date today = new Date(); while (date != today) {... } String name;... if (name == "Bob") { hiBob(); } Date today = new Date(); while (!date.equal(today)) {... } String name;... if ("Bob".equals(name)) { hiBob(); } 31

오류 처리 잘 못된 데이터를 어떻게 처리할 것인가 ? 예 ) 은행 구좌가 없는 구좌번호 체계적인 접근 방법이 필수 SpecializedVehicle createACar() SpecializedVehicle createATruck() SpecializedVehicle createABus() evaluate( String vehicleP ) // problem with illegal string evaluate( SpecializedVehicle vehicleP ) // parameter value cannot be illegal 32

코드 문서화 코드 안의 커멘트 공개 인터페이스 – 사용을 위하여 정확히 문서화 되어야 비공개 인터페이스 – 유지보수 할 수 있도록 문서화 원시코드에 대하여 잘 모르는 것으로 가정하고 문서화 코드와 문서는 항상 일치시켜야 불필요한 것 생략하고 명확하고 간결하게 기술 클래스, 인터페이스, 메소드, 생성자, 필드 정의 앞에 문서화 주석 클라이언트와 서비스 제공자 사이에 프로그래밍 계약관계 (programming contract) 를 정의 33

문서화의 사례 /** * The Rectangle2D class describes * a rectangle defined by location (x, y) and dimensions (w, h). *... */ public abstract class Rectangle2D extends RectangularShape { /** * The Double class defines a */ static class Double extends Rectangle2D {... } /** * The bitmask that indicates that a point lies below this Rectangle2D... */ static int OUT_BOTTOM;... /** * Adds a Rectangle2D to this Rectangle2D... */ public void add(Rectangle2D r) {... } /** * This is an abstract class that cannot be instantiated directly... */ protected Rectangle2D() {... }... } 34

문서화의 사례 잘못된 사례 public int occurrencesOf(Object item) { // This turned out to be much simpler // than I expected. Let's Go Lions!!! return (find(item) != null) ? 1 : 0; } // Apply a 5% discount to all invoices // over a thousand dollars: if (this.invoiceTotal > ) { this.invoiceTotal = this.invoiceTotal * 0.95; // This term corrects for the effects of Jupiter, // Venus, and the flattening of the earch: sigma += (c1 * Angle.sin(a1) + c2 * Angle.sin(Angle.minus(L1, F)) + c3 * Angle.sin(a2) ); 잘된 사례 public int occurrencesOf(Object item) { // This works because no duplicates are allowed: return (find(item) != null) ? 1 : 0; } if (this.invoiceTotal > ) { this.invoiceTotal = this.invoiceTotal * 0.95; int cur = 0; // Index of current pattern element int prev = 0; // Index of previous pattern element 35

8.3 리팩토링 리팩토링 소프트웨어를 보다 쉽게 이해할 수 있고 적은 비용으로 수정할 수 있도록 겉으로 보이는 동작의 변화 없이 내부구조를 변경하는 것 프로그래밍의 가치 당장 수행되어 작업에 도움이 되는 가치 향후 변경이나 필요에 대비한 가치 코드 스멜 (smell) 읽기 어려운 프로그램 중복된 로직을 가진 프로그램 실행 중인 코드를 변경해야 하는 특별 동작을 요구하는 프로그램 복잡한 조건이 포함된 프로그램 36

두 개 모자의 비유 리팩토링 : 두 개의 모자 기능 추가 작업 리팩토링은 신경 쓰지 않고 기능 구현을 위하여 코딩하고 테스트하여 잘 동작 하는지 확인 리팩토링 기능추가에 신경 쓰지 않고 리팩토링, 즉 코드의 구조에만 관심을 기울임 목표에 맞는 작업만 하는 것이 효율적 37

리팩토링의 목적 소프트웨어의 디자인을 개선시킴 소프트웨어를 이해하기 쉽게 만듦 버그를 찾는 데 도움을 줌 프로그램을 빨리 작성할 수 있게 도와 줌 38

리팩토링 사례 리팩토링 하기 전 void foo(char c) { int i,count,len char str[MAX]; cin>>str len=strlen(str); count=0; for(i=0;i<=len;i++) if(str[i]==c) { count++; str[i]='\n'; } cout<<str<<" "<<count<<"\n"; } 리팩토링 한 후 void foo(char c) { int i,count,len char str[MAX]; cin>>str len=strlen(str); newfun(count,len,str,c); cout<<str<<" "<<count<<"\n"; } newfun(int& count,int len, char* str,char c) { int i; count=0; for(i=0;i<=leni++) if(str[i]==c) { count++; str[i]='\n'; } 39

리팩토링 프로세스  소규모의 변경 – 단일 리팩토링  코드가 전부 잘 작동하는지 테스트  전체가 잘 작동하면 다음 리팩토링 단계로 전진.  작동하지 않으면 문제를 해결하고 리팩토링 한 것을 undo 하여 시스 템이 작동되도록 유지. 40

41 코드 스멜 41

8.4 코드 품질 향상 방법 테스트 이 외에도 더욱 효과적인 방법이 많이 있음 코드 인스펙션 프로그램뿐만 아니라 설계, 분석 등의 문서에서도 오류를 찾아내기 위하여 사용할 수 있는 좋은 검사 방법 정적 분석 방법 프로그램을 실행시키지 않고 텍스트를 조직적으로 분석하여 결함 을 찾아내는 방법 증명 증명 수학 정리처럼 증명 수학 정리처럼 증명 42

코드 인스펙션 43

정적 분석 방법 대부분의 컴파일러는 제한된 기능이지만 정적 분석을 실행 코드에 존재하는 결함으로 나타날 비정상적인 패턴이나 원하지 않는 패턴을 찾는 방법 자료 흐름이나 논리 흐름을 분석하는 것 자료 흐름 : 자료가 어디서 정의되고 사용되었는지 나타내는 그래프 44

정적 분석 방법 정의 변칙 (define anomaly) 정의되지 않고 사용된 변수 사용 변칙 (use anomaly) 정의 되고 사용되지 않는 변 수 45

증명 프로그램을 위한 요구와 코드 자체에 기초하여 이루어짐 소프트웨어 품질이 아주 중요한 경우 증명을 사용 결함이 없다는 것을 증명할 정도로 중요한 시스템 항공기 탑재 시스템 원전 제어 시스템 요구 사항에 기초하여 프로그램의 전제조건과 사후 결과를 논리식으 로 표현하여 증명 46

증명 사례 // Define I: j <= n-1 < 100 & r = max{g[0], g[1], …, g[j]} // After the following two commands, I is true: int r = g[0]; int j = 0; // This block keeps I true while( j < n-1 ) { if( g[ j+1 ] > r ) r = g[ j+1 ]; ++j; } 47

증명 사례 불변조건 I 가 참이다. 루프가 종료된다고 가정하면 종료 시점에는 조 건 j =n-1 이다. 이상을 종합하면 j >=n-1, AND j <= n-1 (from statement I) AND k = max{ a[0], a[1], …, a[j] } (from statement I)

증명 사례 루프가 종료된다고 가정하면 종료 시점에 j < n-1 조건은 더 이상 참이 아니다. 그러나 불변조건 I 는 항상 참이므로 이를 종합하면, j < n-1 is false, AND j <= n-1 (from of statement I), AND r = max{ g[0], g[1], …, g[j] } (from statement I) 따라서 j = n-1 AND r = max{ g[0], g[1], …, g[n-1] } -- 바로 이것이 이 프로그램의 목표. 루프가 종료되는지를 증명하는 것이 남아 있음. 불변조건 I 가 참 이므 로 n-j 는 항상 양수이다. 또한 n-j 는 반복되면서 1 씩 감소된다. 따라서 루프는 언젠가는 종료된다. 49