SlideShare a Scribd company logo
1 of 85
Download to read offline
Working with Code
Kookmin University
Graduate School of Busuness IT
e-Government System Development
석사과정 1학기 안재열
Contents
Identifying
“bed smell”
Refactoring
13가지
소개 및 코드확인
4가지
소개 및 코드확인
테스팅종류
Testing Debugging
+ Extending the Software for a New Project
테스팅종류
UnitTest
xUnit
TDD 소개 및 코드
디버깅종류
UnitTest
IDE사용확인 – 2가지
Four central activities for Coding
Identifying
“bed smell”
Refactoring
Testing Debugging
Four central activities for Coding
Identifying
“bed smell”
Refactoring
Coding/
Debugging
Testing Debugging
RefactoringTesting
Four central activities for Coding
Q
U
A
Software
A
L
I
T
Y
Bad Smells
What is the Bad Smells?
-> A bad smell is a segment of code that doesn’t read
clearly and concisely.
코드가 명확하지 않고 간결하지도 않다.
Bad Smells
What is the Bad Smells?
Kinds of Bad Smells in the code
1) Poorly Named 9) Lazy Class
2) Duplicate Code 10) Speculative Generality
3) Long Method 11) Temporary Fields
4) Large Class 12) Inappropriate Intimacy4) Large Class 12) Inappropriate Intimacy
5) Too Many/Few comments 13) Incomplete Class
6) Data Clump 14) Refused Bequest
7) Parallel Inheritance Hierarchies 15) Feature Envy
8) Primitive Obsession
Bad Smells
1) Poorly Named
-> Variable, method or Class name does not clearly
represent its purpose in the code
<?php
class A{
public $li1;
class A{
public $li1;
public function s(){
$abcd = $this->li1 * 10;
return $abcd;
}
}
?>
Bad Smells
2) Duplicate Code
-> the same sequence of expression or
instruction appears in several places.
<?php
class SumMyScore{
public $math1, $math2;
public function Scoring3(){
$result = $this->math1 * 10;
$result + 100;
return $result;
}
public function Scoring1(){
$result = $this->math1 * 10;
$result + 1;
return $result;
}
public function Scoring2(){
$result = $this->math1 * 10;
$result + 10;
return $result;
}
}
public function Scoring3(){
$result = $this->math1 * 10;
$result + 600;
return $result;
}
}#class end
?>
Bad Smells
3) Long Method
-> A method contains a lot of code
that accomplishes several sub-task
<?php
class MyBestWay{
public $startpoint, $endpoint;
public function finding(){public function finding(){
$result = $this->math1 + $this->math2 ;
$result = $result / 2;
$result splice($result);
….
+ 최단거리알고리즘 + sort + …
return $result;
}
} #class end
?>
Bad Smells
4) Large Class
-> A class has an unusually and diverse collection of instance variables
or methods.
<?php
class Vehicle{
public $size, $color, $weight, $cost;
public $engine; #자동차, 비행기, 오토바이
public $Wings; #비행기
범위가 너무 커서 인스
턴스 변수와 메소드의
public $Wings; #비행기
public $feed, age; #말
….
public function flying(){}
public function jumpStart(){}
public function kickStart(){}
public function eatting(){}
……
} #class end
?>
턴스 변수와 메소드의
개수가 엄청나게 커진
다.
따라서 중복코드의 문
제 또한 발생 할 수가
있다.
Bad Smells
5) Too many or few Comments
-> Too many comments can hide bad code.
Too few comments can make code difficult to read.
<?php
class Vehicle{
public $size, $color, $weight, $cost;
public $engine; #자동차, 비행기, 오토바이
public $Wings; #비행기
public $feed, $age; #말public $feed, $age; #말
….
# flying() 메소드를 사용하실경우에는 vehicle클래스를 사용한 인스턴스들 중 하늘을 나는 경우
#에 한하여 사용하실 수 있습니다. kicKStart() 메소드의 경우에는 멤버변수 $engine을 사용하게
#되며 두 바퀴가 달린 이륜차에 한하여 이용하실 수 있습니다. eatting()메소드의 경우에는 말과
#같은 생물에 한해 사용하실수 있으며, 메소드에서 사용되는 멤버변수로는 $feed, $age가 있습
#니다.
public function flying(){}
public function jumpStart(){}
public function kickStart(){}
public function eatting(){}
……
} #class end
?>
Bad Smells
5) Too many or few Comments
-> Too many comments can hide bad code.
Too few comments can make code difficult to read.
<?php
class Vehicle{
public $size, $color, $weight, $cost;
public $engine;public $engine;
public $Wings;
public $feed, $age;
public function flying(){}
public function jumpStart(){}
public function kickStart(){}
public function eatting(){}
……
} #class end
?>
321
Bad Smells
5) Data Clumps
-> The same three or four variables appear together in several different
place.
Class A Class B Class C
Bad Smells
6) Feature Envy
-> A method requires lots of information from a different class
class First{
public static $temp;
public function __construct(){
$this->temp = new Second();
class Second{
public $maxSize = 10;
public $minSize = 2;
public function maxCal($value){$this->temp = new Second();
}
public function maxCal($value){
return $temp->maxCal($value);
}
public function minCal($value){
$result = $value * $temp->minSize;
return $result;
}
}
public function maxCal($value){
$result = $value * $this->maxSize;
return $result;
}
}
Bad Smells
7) 기본타입에 대한 강박관념 Primitive Obsession
->the code is reluctant to use classes instead of primitive data types.
OOP에서 클래스 사용보다, 기본타입을 우선 고려 할 경우의 문제.
$Students = array();
array_push($Student, “Tom”); //name
array_push($Student, 20); //age
array_push($Student, “Male”);//Gender
array_push($Student, “Swimming”); //hobby 배열내의 요소가
.
.
.
array_push($Student, “Swimming”); //hobby
array_push($Student, true);//자취여부
array_push($Student, 7);//좋아하는 숫자
$Students2 = array();
array_push($Student, “Emily”); //name
array_push($Student, 24); //age
array_push($Student, “Female”);//Gender
array_push($Student, false); //자취여부
array_push($Student, 24);//좋아하는 숫자
.
.
.
.
배열내의 요소가
많아 질 수록
코딩 시 헷갈릴 수
있다.
Bad Smells
8) Lazy Class
->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다.
이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다.
Person TelephoneNumber
->리팩토링 이후 기능이 축소되거나 쓸모 없어진 클래스
Person
name
getTelephoneNumber()
TelephoneNumber
areaCode
number
getTelephoneNumber()
사용
1회
사용
1회
총 2회
Bad Smells
8) Lazy Class
class Person{
private $_name; //이름
private $_officeTelephoneNumber = new TelephoneNumber(); //회사전화(객체)
public function getName(){
return $this->_name;
}
//전화번호가져오기 -> 전화객체에서
public function getTelephoneNumber(){
return $this->_officeTelephoneNumber->getTelephoneNumber();
}
//전화객체가져오기 ->전화객체에서
funcion getOfficeTelephone(){
return $this->_officeTelephoneNumber;
}
}
Bad Smells
8) Lazy Class
class TelephoneNumber{
private $_number; // 개인고유번호
private $_areaCode; // 지역번호
//전화번호 가져오기 ; 지역번호 + 개인고유번호
public function getTelephoneNumber(){
return “(“.$this->_areaCode.”) ”. $this->_number
}
public function getAreaCode(){
return $this->_areaCode;return $this->_areaCode;
}
public function setAreaCode($arg){
$this->_areaCode = $arg;
}
public function getNumber(){
return $this->_number;
}
public function setNumber($arg){
$this->_number = $arg;
}
}
Bad Smells
8) Lazy Class
->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다.
이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다.
-> 추후에 기능이 확장되거나, 활용될 가치가 없다고 판단되면 Lazy Class!
Person
name
getTelephoneNumber()
TelephoneNumber
areaCode
number
getTelephoneNumber()
Bad Smells
9) 추측성 일반화 (Speculative Generality)
->일어날 가능성이 거의 없는 일까지 다 대비한 필요없는 코드들은 제거하
라. 모든 기능들과 절차들은 제대로 이용되었을 때 쓸모가 있다.
Class Test
만약을 위한 멤버변수 1
만약을 위한 멤버변수 2
만약을 위한 멤버변수 3
만약을 위한 멤버변수 4만약을 위한 멤버변수 4
……
만약을 위한 멤버변수 100
만약을 위한 메소드 1
만약을 위한 메소드 2
만약을 위한 메소드 3
….
If 만약을 위한 분기문 1
If 만약을 위한 분기문 2
If 만약을 위한 분기문 3
……
Bad Smells
10) 임시 필드 (Temporary Field)
->때로는 어떤 객체 안의 인스턴스 변수가 특정 상황에서만 세팅되는 경우
가 있다. 보통은 객체의 모든 변수가 값을 가지고 있을 거라고 기대하기 때
문에 이런 코드는 이해하기 어렵다.
Student
$Name //학생이름
$AGE // 학생나이$AGE // 학생나이
$height // 학생키
$temp // 평균 낼 때 사용되는 임시변수
$temp2 // function4와 5, 8에서 사용되는 임시변수
….
Function 1(){}
Function 2(){}
Function 평균(){}
Function 4(){}
……
Bad Smells
11) 지나친 관여(Inappropriate Intimacy)
-> 간혹 클래스끼리 관계가 지나치게 밀접한 나머지 서로의 private 를 알
아내느라 시간을 낭비하게 되는 경우가 있다.
A
Private $a
B extends C
Private $b
C
Private $c =
new D().getD();
Protected getC()
Private $a
Public getA()
Private $b
= new C().getC()
Public getB()
Protected getC()
D
Private $d = 1
Protected getD()
Protected
1. 같은 package 내의 모든 클래스에서 접근가능
2. 다른 패키지의 클래스라도 해당클래스 상속시 접근가능
Bad Smells
12) 불완전한 클래스 (Incomplete Class)
-> One that doesn’t do everything you need.
Sort
Member
Quick Sort?
Member
variables.
Bubble
Select
Insertion
Merge
.
.
.
Quick Sort?
오름차순?
Bad Smells
13) 방치된 상속물 (Refused Bequest)
-> 서브클래스는 메소드와 데이터를 그 부모 클래스로부터 상속 받는다.
그러나 만약 서브클래스가 그들에게 주어진 것을 원치 않는다거나,
필요하지 않는 경우.
Parents
function a
SonA
function a //상속
function b
GrandSonAA
function a //상속
function b//상속
function c
GrandSonAB
SonB
function a //상속
function b
GrandSonBA
Fun!
Fun!
Fun!
Fun!
Software Metrics
- 소프트웨어의 Quality를 평가 할 수 있는 방법 4가지
• Pakages, classes, instance variables, methods, paramethers, lines
• 적당하고 자연스럽게 적을수록 좋다.
Count (수량)
• 메소드 안에서의 분기문 및 제어문의 수량. //
• 많을수록 복잡하다. 한 메소드안에는 10개 미만으로 유지하는게 좋다.
Clarity (명확성)
• 하나의 단위 내에서, 한 기능을 수행하기 위해 각 구성 요소들이 가까이 있는 경우
• 모듈은 응집도를 높이기 위한 방안 중 하나.
• OOP는 정적인데이터와 동작을 함께 묶어 객체를 정의함으로써 높은 응집도를 얻음
• 4장에서 LCOM 의 값이 0에 가까울 수록 응집도가 높음
Cohension (응집도)
• 코드기반의 패키지(모듈,클래스,함수,라이브러리등)이 얼마나 독립적으로 움직일 수 있는가?
Coupling (결합도)
Refactoring
Refactoring
1. 메소드 정리
2. 객체나 클래스 사이의 이동
3. 데이터의 재구성
4. 조건문을 이해하기 쉽게 단순화4. 조건문을 이해하기 쉽게 단순화
5. 메소드 호출 단순화
6. 상속관계 재구성
Refactoring
How to do ?
1) Renaming 7) Simplifying conditionals
2) Extracting a method 8) Removing Useless Code
3) Extracting a methods 9) Removing Violations to Layering Principles
4) Reorganizing a class 10) Merging Similar Functions /Modules4) Reorganizing a class 10) Merging Similar Functions /Modules
5) Unifying data clumps 11) Separating Model, View, Controller Code
6) Removing a parameter
Refactoring - Renaming
네이밍 관례와 표준
파스칼 표기법
"PascalCase"
"쌍봉낙타" 표기법
첫 단어를 대문자로 시작하는 카멜 표기법첫 단어를 대문자로 시작하는 카멜 표기법
예시:
BackgroundColor, TypeName, PowerPoint
Refactoring - Renaming
네이밍 관례와 표준
카멜 표기법
"camelCase"
"단봉낙타" 표기법
첫글자는 소문자,
단어와 단어 만나면 첫 글자 -> 대문자단어와 단어 만나면 첫 글자 -> 대문자
띄어쓰기 대신 대문자로 단어를 구분하는
표기 방식
예시:
backgroundColor, typeName, iPhone
Refactoring - Renaming
네이밍 관례와 표준
헝가리안 표기법
-. 헝가리안 개발자가 창시
-. 변수명 맨 앞에 자료형을 명시함
예시:예시:
-. iNum, iCnt, dAmount //
int ,int, double
언더바 표기법(Underbar Notation), Snake Notaion
-. 단어와 단어 사이에 언더바
-. user_name
Refactoring - Renaming
네이밍 관례와 표준
1.1. 클래스 명에는 파스칼 표기법을 사용한다.
public class HelloWorld
{
...
}
1.일반적으로 클래스
이름은 명사명사들의 조합
혹은 형용사형용사 ++ 명사로명사로
지정한다.}
1.2. 함수(Method) 명에는 카멜 표기법을 사용한다.
void sayHello(string name)
{
...
}
지정한다.
2. 메소드는 동사동사 ++ 명사명사
의의 형태로 지정하는 것
이 일반적이다.
Refactoring - Renaming
네이밍 관례와 표준
올바른 클래스명의 예
class LoginAction;
class HTTPRequest; : 축약어는 모두 대문자로 사용(HTTP는 범용적으로 사용되는 축약어)
abstract class AbstractUserInformation;
잘못된 클래스명의 예
class GSL; : 정확하게 약어의 뜻을 유추할 수 없음
class my_action; : 클래스 명이 소문자로 시작되어 클래스 명 식별이 쉽지 않고,
밑줄을 사용하여 자바 API와 일관성이 떨어짐
class 사용자; : 한글을 클래스 명으로 사용할 경우 일부 OS에서 클래스를 읽을 수 없음
class DoIt; : 클래스는 하나의 엔티티(entity)를 뜻하므로, 어떠한 행동을 기술하는
동사를 사용할 경우, 클래스의 정확한 용도를 유추하기가 어려움
Refactoring - Renaming
올바른 메소드명의 예
Customer getCustomer();
void drawCircle(int x, int y, int radius);
boolean isLive()//boolean의 경우 is를 주로 앞에 붙인다.
클래스 명과 마찬가지로 범용적으로 통하는 경우를 제외하고는 되도록 축약어클래스 명과 마찬가지로 범용적으로 통하는 경우를 제외하고는 되도록 축약어
를 사용하지 않는 것을 원칙으로 하며, 부득이하게 사용해야 할 경우 축약어는
모두 대문자로 지정한다. 예) HTTP, ID
HTTPHeader getHTTPHeader();
void setMessageID(MessageID msgID);
Refactoring - Renaming
네이밍 관례와 표준
1.3. 변수와 함수 파라미터에는 카멜 표기법을 사용한
다.
int totalCount = 0;
void SayHello(string name)
{{
string fullMessage = "Hello " + name;
...
}
Refactoring - Renaming
네이밍 관례와 표준
1.4. 인터페이스에는 접두사 "I"가 포함된 파스칼 표기법을 따른다.
예 : IEntity
1.5. 변수명에 헝가리안 표기법을 사용하지 않는다.
이전에는 많은 프로그래머들이 변수명에 데이터 타입에 해당하는 접두사를 첨가하
였다. 즉, 멤버변수에는 아래와 같이 m_ 을 접두사로 사용하는 것과 같은 헝가리안
표기법을 사용했었다.
string m_sName;
int nAge;
Refactoring - Renaming
네이밍 관례와 표준
1.6. 변수에 모든 의미를 충분히 담아라(약어를 사용하지 말것).
- 좋은 예
string address
int salary
- 나쁜 예
string nam
string addrstring addr
int sal
1.7. "i, n, s,..."와 같이 한 글자로 된 이름을 사용하지 말것.
i, n, s 보다는 index, temp 와 같은 이름을 사용한다.
한 가지 예외가 있다면 루프에서 반복을 의미하는 변수를 허용하는 경우이다.
for ( int i = 0; i < count; i++ )
{
...
}
Refactoring - 10) Merging Similar Functions
8) Lazy Class
->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다.
이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다.
->추후에 기능이 확장되거나, 활용될 가치가 없다고 판단되면 Lazy Class!
Person
name
getTelephoneNumber()
TelephoneNumber
areaCode
number
getTelephoneNumber()
Refactoring - 10) Merging Similar Functions
8) Lazy Class
class Person{
private $_name; //이름
private $_officeTelephoneNumber = new TelephoneNumber(); //회사전화(객체)
public function getName(){
return $this->_name;
}
//전화번호가져오기 -> 전화객체에서
public function getTelephoneNumber(){
return $this->_officeTelephoneNumber->getTelephoneNumber();
}
//전화객체가져오기 ->전화객체에서
funcion getOfficeTelephone(){
return $this->_officeTelephoneNumber;
}
}
Refactoring - 10) Merging Similar Functions
8) Lazy Class
class TelephoneNumber{
private $_number; // 개인고유번호
private $_areaCode; // 지역번호
//전화번호 가져오기 ; 지역번호 + 개인고유번호
public function getTelephoneNumber(){
return “(“.$this->_areaCode.”) ”. $this->_number
}
public function getAreaCode(){
return $this->_areaCode;return $this->_areaCode;
}
public function setAreaCode($arg){
$this->_areaCode = $arg;
}
public function getNumber(){
return $this->_number;
}
public function setNumber($arg){
$this->_number = $arg;
}
}
Refactoring - 10) Merging Similar Functions
class Person{ //논리적 개념의 범위가 더욱 큰 Person으로 변경
private $_number; // 개인고유번호
private $_areaCode; // 지역번호
private $_name; //이름, 원래 Person의 것
//전화번호 가져오기 ; 지역번호 + 개인고유번호
public function getTelephoneNumber(){
return “(“.$this->_areaCode.”) ”. $this->_number}
public function getAreaCode(){
return $this->_areaCode;}
public function setAreaCode($arg){
$this->_areaCode = $arg;}
public function getNumber(){
return $this->_number;}
public function setNumber($arg){
$this->_number = $arg;}
public function getName(){ //원래 Person의 것
return $this->_name;
}
}
Refactoring - 2) Extracting a method
Motive :
메서드가 너무 길거나, 코드에 주석을 달아야만 의도를 이해할 수 있을 때 필요하다.
( Bed Smell - Long Method, Too Many comments)
Why?
-> 1. 메서드가 적절히 잘게 쪼개져 있으면 다른 메서드에서 쉽게 사용 할 수 있다.
2. 재정의하기 쉽다2. 재정의하기 쉽다
Refactoring - 2) Extracting a method
How to?
-> 1. 목적에 부합하는 이름의 새 메서드를 생성한다.
이때 메서드명은 원리가 아니라 기능을 나타내는 이름이어야 한다.
2. 기존 메서드에서 빼낸 코드를 새로 생성한 메서드로 복사한다.
3. 추출한 코드에서 기존 메서드의 모든 지역변수 참조를 찾는다.
그것들을 새로 생성한 메서드의 지역변수나 매개변수로 사용 할 것이다.그것들을 새로 생성한 메서드의 지역변수나 매개변수로 사용 할 것이다.
4. 추출한 코드내에서만 사용되는 임시변수가 있다면,
이를 새로생성한 매서드 안에 임시변수로 선언한다.
.
.
.
Refactoring - 2) Extracting a method
Enumeration
컬렉션인 Vector, Hash의 elements 를 열거하는
인터페이스
import java.util.Vector
import java.util.Enumeration
public class Test{
public static void main(String[]args){
Vector vt = new Vector();
vt.add("one");vt.add(2);vt.add("셋");
Enumeration et = vt.elements();
while(et.hasMoreElements()){
System.out.print(et.nextElement()+" ");
}
}
}
결과 :
one 2 셋
Refactoring - 2) Extracting a method
Order
-Double amount //외상값 합
-Date
+getAmount(); //
HostPrint
+ printOwing(){}
+getAmount(); //
+getDate();
Refactoring - 2) Extracting a method Order
-Double amount //외상값 합
-Date
+getAmount(); //
+getDate();
HostPrint
-String _name
+ printOwing(){}
void printOwing() {
Enumeration e = _orders.elements();
double outstanding = 0.0;
//배너 출력
System.out.println (“****************”);
System.out.println (“*****고객외상*****”);System.out.println (“*****고객외상*****”);
System.out.println (“****************”);
//외상액 계산
while (e.hasMoreElements()){
Order each = (Order) e.nextElement(); //elements 추출
outstanding += each.getAmount(); // elements였던 Order객체의 외상값합계추출
}
//세부내역 출력
System.out.println (“고객명 : ”+_name);
System.out.println (“외상액 : ”+outstanding);
}
Refactoring - 2) Extracting a method
void printOwing() {
Enumeration e = _orders.elements();
double outstanding = 0.0;
printBanner();
//외상액 계산
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
//세부내역 출력
System.out.println (“고객명 : ”+_name);
System.out.println (“외상액 : ”+outstanding);
}
void printBanner(){
//배너 출력
System.out.println (“****************”);
System.out.println (“*****고객외상*****”);
System.out.println (“****************”);
}
Refactoring - 2) Extracting a method
void printOwing() {
Enumeration e = _orders.elements();
double outstanding = 0.0;
printBanner();
printDetails(outstanding);
//외상액 계산
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
}}
void printBanner(){
//배너 출력
System.out.println (“****************”);
System.out.println (“*****고객외상*****”);
System.out.println (“****************”);
}
void printDetails(double outstanding){
//세부내역 출력
System.out.println (“고객명 : ”+_name);
System.out.println (“외상액 : ”+outstanding);
}
Refactoring - 2) Extracting a method
void printOwing() {
double outstanding = getOutstanding(); // 변수 초기값은 확실한 경우만 메모리에 할당된다.
printBanner();
printDetails(outstanding);
}
}
void printBanner(){
//배너 출력
System.out.println (“****************”);
System.out.println (“*****고객외상*****”);
System.out.println (“****************”);
}
void printDetails(double outstanding){
//세부내역 출력//세부내역 출력
System.out.println (“고객명 : ”+_name);
System.out.println (“외상액 : ”+outstanding);
}
double getOutstanding(){
//외상액 계산
Enumeration e = _orders.elements(); //외상액 계산시만 사용될 예정이므로 local variable로
double result = 0.0; // 지역변수 및 임시변수이므로 변수명 혼동을 피하기 위해 변경
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
result += each.getAmount();
}
return result;
}
Refactoring - 2) Extracting a method
void printOwing(double previousAmount) {
double outstanding = previousAmount * 1.2;
outstanding = getOutstanding(); // 변수 초기값은 확실한 경우만 메모리에 할당된다.
printBanner();
printDetails(outstanding);
}
}
void printBanner(){
//배너 출력
System.out.println (“****************”);
System.out.println (“*****고객외상*****”);
System.out.println (“****************”);
}
void printDetails(double outstanding){
}
void printDetails(double outstanding){
//세부내역 출력
System.out.println (“고객명 : ”+_name);
System.out.println (“외상액 : ”+outstanding);
}
double getOutstanding(){
//외상액 계산
Enumeration e = _orders.elements(); //외상액 계산시만 사용될 예정이므로 local variable로
double result = 0.0; // 지역변수 및 임시변수이므로 변수명 혼동을 피하기 위해 변경
while (e.hasMoreElements()){
Order each = (Order) e.nextElement();
result += each.getAmount();
}
return result;
}
Refactoring - 9) Removing Violations to Layering Principles
View
Controller
Model
Controller
Refactoring - 9) Removing Violations to Layering Principles
editshift.php
Refactoring - 9) Removing Violations to Layering Principles
dbPersons.php
PHP는 Dynamic Typing이 가능하다. 따라서 변수의 타입지정은
값 할당 뒤 일어난다. -> 응용가능.
(※내부 logic은 유사하다는 전제.)
Refactoring - 9) Removing Violations to Layering Principles
dbPersons.php
Parameter 2개인 함수는
없어서 새로 만듬
Testing
Identifying
“bed smell”
Refactoring
Testing Debugging
Testing – 결함 발견시기와 비용
비용
제가원한
소프트웨어가
아니네요.
요구사항분석 설계 개발 운영
고객테스팅이
가장어렵다.
(인수테스트
Acceptance Test)
Testing – 종류
• 보통 단위테스트 혹은 Unit Test라고 부른다.
• 모듈이나 객체, 프로그램과 같이 개별적으로 테스트가 가능한 단위에 대해서 테스트
• 우리나라 SI 거의 안 함
Component Test (컴포넌트 테스트)
• 컴포넌트 사이의 인터페이스를 테스트하는 것을 의미한다.
Integration Test (통합테스트)
• 컴포넌트 사이의 인터페이스를 테스트하는 것을 의미한다.
• UI와 서버 부분을 묶거나, 기능 사이에 연결관계를 테스트한다.
• 개발된 시스템이 제대로 동작하는지 확인.
System Test (시스템테스트)
• 고객이 원하는 대로 만들었는지 확인
Acceptance Test (인수테스트)
Testing – 종류
• 보통 단위테스트 혹은 Unit Test라고 부른다.
• 모듈이나 객체, 프로그램과 같이 개별적으로
테스트가 가능한 단위에 대해서 테스트
• 우리나라 SI 거의 안 함. – 착각함.
Component Test
(컴포넌트 테스트)
서비스 개발자는 jsp에서의 문제인지, class에서의 문제인지 확인가능
화면테스트 AddMovie.jsp AddManager.class
테스터는 전체의 과정을 알기 힘들다.
S
T
U
B
D
R
I
V
E
R
Testing – Unit test
Stub, driver =단위마다 테스트 코
드(함수,메소드 작성)
(※DB의 경우 CRUD에 맞춰서)
개별 메소드마다 실행된다.개별 메소드마다 실행된다.
예) Echo 기능의 메소드일
경우 echo 실행.
※만약 10000개 존재?
->
1만라인 실행 및 1만번 수
행
Testing – Unit test
UnitTestCase
….
generate_new_shift()
assertEqual()
assertTrue()
assertFalse()
…
테스트 메소드를
모아놓은 클래스를 만든 후
상속시킨다.
Class TestSuite
Testing – Test suite
A test suite is a collection of “unit tests”
Class 1
메소
드
A
C
test
A
Class 2
C
B
test
C
test
B
Testing – xUnit
Unit test를 위한 Framework.
xUnits Languages
JUnit, TestNG Java
NUnit,csUnit,MbUnit,
MSTest
.NET
Test::Unit Ruby
CUnit CCUnit C
CppUnit C++
PHPUnit PHP
PyUnit Python
DbUnit Database
utPLSQL PL/SQL
leUnit JavaScript,DHTML
Testing – PhpUnit
Testing – UnitTest Cheak list
Test Driven Development - TDD
What? –
Test the program before you write it. – Kent Beck
프로그램 작성하기 전에 테스트 먼저 하라!
디자인 개발 테스트
기존 개발 절차
TestScript
개발
개발 리팩토링
TDD 개발 절차
Test Driven Development - TDD
What?
TestScript
개발
개발 리팩토링
1. TDD는 코드를 먼저 만드는 것이 아니라, Test Script를 먼저 만든다1. TDD는 코드를 먼저 만드는 것이 아니라, Test Script를 먼저 만든다
2. 그다음 실제 서버에서 수행되는 코드를 작성하는데, 먼저 만든 테스트스크립트
를 수행하면 PASS 하도록 코딩한다.
3. 코드작성을 마치고, 그 코드의 가독성, 유지보수성을 높이기 위해 리팩토링한다.
Test Driven Development - TDD
Test Script – 명시적인 코드로 개발 종료조건을 정해 놓은 것
class Calculator{
public function $sum($a, $b){
return 0;
}
}
class TestScript {
$testObject;
$test = new Calulator();
$ts = new TestScript($test);
$ts->test();
------결과--------$testObject;
public function __constant($obj){
$this->testObject = $obj;
}
public function test(){
echo ($testObject->sum(10,20) == 30);
echo ($testObject->sum(1,2) == 3);
echo ($testObject->sum(-10,20) == 10);
echo ($testObject->sum(0,0) == 0);
}
}
------결과--------
false
false
false
true
Test Driven Development - TDD
Test Driven Development - TDD
What?
- 코딩 할 시간도 없는데 무슨 테스트코드를 작성하고 있어?
Debugging
Identifying
“bed smell”
Refactoring
Testing Debugging
Debugging
재현가능성확보
단서의확보
개발지식이 충분하다면,
단계별로 정확하게 진행이 가능하다.
하지만, 개발지식이 부족 할 경우
무작위로 코드를 고쳐보고
이전상태로 돌려보는 상황이 나타난다.
최악의 경우 검색으로 힌트를 얻어,
소거법으로 하나하나 연관 없는 부분을
단서의분석
가설의수립
가설의검증
소거법으로 하나하나 연관 없는 부분을
제거하기도 한다.
Debugging
원초적인 방법으로는
1. Console에 print.
2. Log.debug()와 같이 로거의 메소드를 호출하여
 소스에 흔적이 남을 수 있다.
3. IDE tool을 이용하기
- Eclipse, VisualStudio 등등
Debugging –IDE 이클립스
Debugging
Debugging – IDE Visual Studio
Debugging – IDE Visual Studio
중단점에서
멈춤
Debugging – IDE Visual Studio
Extending the Software for a New Project
New Use Case
요구사항 뭐지?
User Interface
그래서 뭐필요? ->스케치
Classes& Modules
기존에 있나?
냄새는?
Database
이미 정보가 있나?
테이블 더 필요?
CRUD Availability?
Security
보안정책에 위배?
User Help
사용자를 위한 안내는 어떻게 ?
Team Discussion
기술적으로 잘 될까?
빼먹은건 없을까?
레퍼런스
끝
감사합니다.감사합니다.

More Related Content

What's hot

Java 변수자료형
Java 변수자료형Java 변수자료형
Java 변수자료형Hyosang Hong
 
Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초Park Jonggun
 
파이썬 namespace Binding 이해하기
파이썬 namespace Binding 이해하기 파이썬 namespace Binding 이해하기
파이썬 namespace Binding 이해하기 Yong Joon Moon
 
파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304Yong Joon Moon
 
파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403Yong Joon Moon
 
python data model 이해하기
python data model 이해하기python data model 이해하기
python data model 이해하기Yong Joon Moon
 
파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기Yong Joon Moon
 
파이썬 객체 클래스 이해하기
파이썬  객체 클래스 이해하기파이썬  객체 클래스 이해하기
파이썬 객체 클래스 이해하기Yong Joon Moon
 
파이썬+클래스+구조+이해하기 20160310
파이썬+클래스+구조+이해하기 20160310파이썬+클래스+구조+이해하기 20160310
파이썬+클래스+구조+이해하기 20160310Yong Joon Moon
 
Programming java day2
Programming java day2Programming java day2
Programming java day2Jaehoonyam
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 
파이썬 xml 이해하기
파이썬 xml 이해하기파이썬 xml 이해하기
파이썬 xml 이해하기Yong Joon Moon
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리ETRIBE_STG
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기 Yong Joon Moon
 
자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초진수 정
 
프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js functionYoung-Beom Rhee
 
주니어 개발자도 이해 할 수 있는 Go - Namespace 편
주니어 개발자도 이해 할 수 있는 Go - Namespace 편주니어 개발자도 이해 할 수 있는 Go - Namespace 편
주니어 개발자도 이해 할 수 있는 Go - Namespace 편Darion Kim
 
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩해강
 

What's hot (20)

Java 변수자료형
Java 변수자료형Java 변수자료형
Java 변수자료형
 
Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초Start IoT with JavaScript - 1.기초
Start IoT with JavaScript - 1.기초
 
파이썬 namespace Binding 이해하기
파이썬 namespace Binding 이해하기 파이썬 namespace Binding 이해하기
파이썬 namespace Binding 이해하기
 
파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304파이썬+주요+용어+정리 20160304
파이썬+주요+용어+정리 20160304
 
파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403
 
python data model 이해하기
python data model 이해하기python data model 이해하기
python data model 이해하기
 
파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기
 
파이썬 객체 클래스 이해하기
파이썬  객체 클래스 이해하기파이썬  객체 클래스 이해하기
파이썬 객체 클래스 이해하기
 
파이썬+클래스+구조+이해하기 20160310
파이썬+클래스+구조+이해하기 20160310파이썬+클래스+구조+이해하기 20160310
파이썬+클래스+구조+이해하기 20160310
 
Programming java day2
Programming java day2Programming java day2
Programming java day2
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
파이썬 xml 이해하기
파이썬 xml 이해하기파이썬 xml 이해하기
파이썬 xml 이해하기
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기
 
자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초자바스크립트 기초문법~함수기초
자바스크립트 기초문법~함수기초
 
프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function
 
주니어 개발자도 이해 할 수 있는 Go - Namespace 편
주니어 개발자도 이해 할 수 있는 Go - Namespace 편주니어 개발자도 이해 할 수 있는 Go - Namespace 편
주니어 개발자도 이해 할 수 있는 Go - Namespace 편
 
Java lambda
Java lambdaJava lambda
Java lambda
 
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
[아꿈사] The C++ Programming Language 11장 연산자 오버로딩
 
파이썬을 활용한 자연어 분석 - 2차
파이썬을 활용한 자연어 분석 - 2차파이썬을 활용한 자연어 분석 - 2차
파이썬을 활용한 자연어 분석 - 2차
 

Similar to Working with code

Refactoring tutorial
Refactoring tutorialRefactoring tutorial
Refactoring tutorialBingu Shim
 
Refactoring tutorial 1주차[refactoring 개요]
Refactoring tutorial 1주차[refactoring 개요]Refactoring tutorial 1주차[refactoring 개요]
Refactoring tutorial 1주차[refactoring 개요]bbongcsu
 
Refactoring Tutorial 1주차[ Refactoring 개요]
Refactoring  Tutorial 1주차[ Refactoring 개요]Refactoring  Tutorial 1주차[ Refactoring 개요]
Refactoring Tutorial 1주차[ Refactoring 개요]Bingu Shim
 
Refactoring Tutorial 1주차[ Refactoring 개요]
Refactoring  Tutorial 1주차[ Refactoring 개요]Refactoring  Tutorial 1주차[ Refactoring 개요]
Refactoring Tutorial 1주차[ Refactoring 개요]Bingu Shim
 
Clean code
Clean codeClean code
Clean codebbongcsu
 
Legacy code refactoring video rental system
Legacy code refactoring   video rental systemLegacy code refactoring   video rental system
Legacy code refactoring video rental systemJaehoon Oh
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기Wonchang Song
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java유리 하
 
The roadtocodecraft
The roadtocodecraftThe roadtocodecraft
The roadtocodecraftbbongcsu
 
[A1]루비는 패셔니스타
[A1]루비는 패셔니스타[A1]루비는 패셔니스타
[A1]루비는 패셔니스타NAVER D2
 
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여iamprogrammerofficial
 
유지보수 가능한 개발 원칙
유지보수 가능한 개발 원칙유지보수 가능한 개발 원칙
유지보수 가능한 개발 원칙Hyosang Hong
 
Java 유지보수 가능한 개발 원칙
Java 유지보수 가능한 개발 원칙Java 유지보수 가능한 개발 원칙
Java 유지보수 가능한 개발 원칙Hyosang Hong
 
소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙Hong Hyo Sang
 

Similar to Working with code (20)

Refactoring tutorial
Refactoring tutorialRefactoring tutorial
Refactoring tutorial
 
Refactoring tutorial 1주차[refactoring 개요]
Refactoring tutorial 1주차[refactoring 개요]Refactoring tutorial 1주차[refactoring 개요]
Refactoring tutorial 1주차[refactoring 개요]
 
Refactoring Tutorial 1주차[ Refactoring 개요]
Refactoring  Tutorial 1주차[ Refactoring 개요]Refactoring  Tutorial 1주차[ Refactoring 개요]
Refactoring Tutorial 1주차[ Refactoring 개요]
 
Refactoring Tutorial 1주차[ Refactoring 개요]
Refactoring  Tutorial 1주차[ Refactoring 개요]Refactoring  Tutorial 1주차[ Refactoring 개요]
Refactoring Tutorial 1주차[ Refactoring 개요]
 
Clean code
Clean codeClean code
Clean code
 
The Introduction to Refactoring
The Introduction to Refactoring The Introduction to Refactoring
The Introduction to Refactoring
 
Legacy code refactoring video rental system
Legacy code refactoring   video rental systemLegacy code refactoring   video rental system
Legacy code refactoring video rental system
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java
 
PHP 사용하기
PHP 사용하기PHP 사용하기
PHP 사용하기
 
The roadtocodecraft
The roadtocodecraftThe roadtocodecraft
The roadtocodecraft
 
메이크챗봇 자연어기초
메이크챗봇 자연어기초메이크챗봇 자연어기초
메이크챗봇 자연어기초
 
Java tutorial
Java tutorialJava tutorial
Java tutorial
 
[A1]루비는 패셔니스타
[A1]루비는 패셔니스타[A1]루비는 패셔니스타
[A1]루비는 패셔니스타
 
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
2015 나는 프로그래머다 컨퍼런스 (11) 염산악 - 가독성에 대하여
 
유지보수 가능한 개발 원칙
유지보수 가능한 개발 원칙유지보수 가능한 개발 원칙
유지보수 가능한 개발 원칙
 
Java 유지보수 가능한 개발 원칙
Java 유지보수 가능한 개발 원칙Java 유지보수 가능한 개발 원칙
Java 유지보수 가능한 개발 원칙
 
Java script
Java scriptJava script
Java script
 
소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙소프트웨어 개선 그룹(Sig) 개발 원칙
소프트웨어 개선 그룹(Sig) 개발 원칙
 
파이썬을 활용한 자연어분석 기초
파이썬을 활용한 자연어분석 기초파이썬을 활용한 자연어분석 기초
파이썬을 활용한 자연어분석 기초
 

More from JaeYeoul Ahn

[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지
[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지
[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지JaeYeoul Ahn
 
Mitm(man in the middle) ssl proxy attacks
Mitm(man in the middle) ssl proxy attacksMitm(man in the middle) ssl proxy attacks
Mitm(man in the middle) ssl proxy attacksJaeYeoul Ahn
 
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티JaeYeoul Ahn
 
16년도 하반기 국민대 BIT 전자정부 연구실 학생모집 1
16년도 하반기 국민대 BIT 전자정부 연구실 학생모집 116년도 하반기 국민대 BIT 전자정부 연구실 학생모집 1
16년도 하반기 국민대 BIT 전자정부 연구실 학생모집 1JaeYeoul Ahn
 
How to use the Ruby programing language
How to use the Ruby programing languageHow to use the Ruby programing language
How to use the Ruby programing languageJaeYeoul Ahn
 

More from JaeYeoul Ahn (7)

Trumpia fp study
Trumpia fp studyTrumpia fp study
Trumpia fp study
 
[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지
[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지
[DomainDriven 6월 정기세미나] Eclipse Platform의 Test, build 에서 CI까지
 
Mitm(man in the middle) ssl proxy attacks
Mitm(man in the middle) ssl proxy attacksMitm(man in the middle) ssl proxy attacks
Mitm(man in the middle) ssl proxy attacks
 
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
 
16년도 하반기 국민대 BIT 전자정부 연구실 학생모집 1
16년도 하반기 국민대 BIT 전자정부 연구실 학생모집 116년도 하반기 국민대 BIT 전자정부 연구실 학생모집 1
16년도 하반기 국민대 BIT 전자정부 연구실 학생모집 1
 
Java 다형성
Java 다형성Java 다형성
Java 다형성
 
How to use the Ruby programing language
How to use the Ruby programing languageHow to use the Ruby programing language
How to use the Ruby programing language
 

Working with code

  • 1. Working with Code Kookmin University Graduate School of Busuness IT e-Government System Development 석사과정 1학기 안재열
  • 2. Contents Identifying “bed smell” Refactoring 13가지 소개 및 코드확인 4가지 소개 및 코드확인 테스팅종류 Testing Debugging + Extending the Software for a New Project 테스팅종류 UnitTest xUnit TDD 소개 및 코드 디버깅종류 UnitTest IDE사용확인 – 2가지
  • 3. Four central activities for Coding Identifying “bed smell” Refactoring Testing Debugging
  • 4. Four central activities for Coding Identifying “bed smell” Refactoring Coding/ Debugging Testing Debugging RefactoringTesting
  • 5. Four central activities for Coding Q U A Software A L I T Y
  • 6. Bad Smells What is the Bad Smells? -> A bad smell is a segment of code that doesn’t read clearly and concisely. 코드가 명확하지 않고 간결하지도 않다.
  • 7. Bad Smells What is the Bad Smells? Kinds of Bad Smells in the code 1) Poorly Named 9) Lazy Class 2) Duplicate Code 10) Speculative Generality 3) Long Method 11) Temporary Fields 4) Large Class 12) Inappropriate Intimacy4) Large Class 12) Inappropriate Intimacy 5) Too Many/Few comments 13) Incomplete Class 6) Data Clump 14) Refused Bequest 7) Parallel Inheritance Hierarchies 15) Feature Envy 8) Primitive Obsession
  • 8. Bad Smells 1) Poorly Named -> Variable, method or Class name does not clearly represent its purpose in the code <?php class A{ public $li1; class A{ public $li1; public function s(){ $abcd = $this->li1 * 10; return $abcd; } } ?>
  • 9. Bad Smells 2) Duplicate Code -> the same sequence of expression or instruction appears in several places. <?php class SumMyScore{ public $math1, $math2; public function Scoring3(){ $result = $this->math1 * 10; $result + 100; return $result; } public function Scoring1(){ $result = $this->math1 * 10; $result + 1; return $result; } public function Scoring2(){ $result = $this->math1 * 10; $result + 10; return $result; } } public function Scoring3(){ $result = $this->math1 * 10; $result + 600; return $result; } }#class end ?>
  • 10. Bad Smells 3) Long Method -> A method contains a lot of code that accomplishes several sub-task <?php class MyBestWay{ public $startpoint, $endpoint; public function finding(){public function finding(){ $result = $this->math1 + $this->math2 ; $result = $result / 2; $result splice($result); …. + 최단거리알고리즘 + sort + … return $result; } } #class end ?>
  • 11. Bad Smells 4) Large Class -> A class has an unusually and diverse collection of instance variables or methods. <?php class Vehicle{ public $size, $color, $weight, $cost; public $engine; #자동차, 비행기, 오토바이 public $Wings; #비행기 범위가 너무 커서 인스 턴스 변수와 메소드의 public $Wings; #비행기 public $feed, age; #말 …. public function flying(){} public function jumpStart(){} public function kickStart(){} public function eatting(){} …… } #class end ?> 턴스 변수와 메소드의 개수가 엄청나게 커진 다. 따라서 중복코드의 문 제 또한 발생 할 수가 있다.
  • 12. Bad Smells 5) Too many or few Comments -> Too many comments can hide bad code. Too few comments can make code difficult to read. <?php class Vehicle{ public $size, $color, $weight, $cost; public $engine; #자동차, 비행기, 오토바이 public $Wings; #비행기 public $feed, $age; #말public $feed, $age; #말 …. # flying() 메소드를 사용하실경우에는 vehicle클래스를 사용한 인스턴스들 중 하늘을 나는 경우 #에 한하여 사용하실 수 있습니다. kicKStart() 메소드의 경우에는 멤버변수 $engine을 사용하게 #되며 두 바퀴가 달린 이륜차에 한하여 이용하실 수 있습니다. eatting()메소드의 경우에는 말과 #같은 생물에 한해 사용하실수 있으며, 메소드에서 사용되는 멤버변수로는 $feed, $age가 있습 #니다. public function flying(){} public function jumpStart(){} public function kickStart(){} public function eatting(){} …… } #class end ?>
  • 13. Bad Smells 5) Too many or few Comments -> Too many comments can hide bad code. Too few comments can make code difficult to read. <?php class Vehicle{ public $size, $color, $weight, $cost; public $engine;public $engine; public $Wings; public $feed, $age; public function flying(){} public function jumpStart(){} public function kickStart(){} public function eatting(){} …… } #class end ?>
  • 14. 321 Bad Smells 5) Data Clumps -> The same three or four variables appear together in several different place. Class A Class B Class C
  • 15. Bad Smells 6) Feature Envy -> A method requires lots of information from a different class class First{ public static $temp; public function __construct(){ $this->temp = new Second(); class Second{ public $maxSize = 10; public $minSize = 2; public function maxCal($value){$this->temp = new Second(); } public function maxCal($value){ return $temp->maxCal($value); } public function minCal($value){ $result = $value * $temp->minSize; return $result; } } public function maxCal($value){ $result = $value * $this->maxSize; return $result; } }
  • 16. Bad Smells 7) 기본타입에 대한 강박관념 Primitive Obsession ->the code is reluctant to use classes instead of primitive data types. OOP에서 클래스 사용보다, 기본타입을 우선 고려 할 경우의 문제. $Students = array(); array_push($Student, “Tom”); //name array_push($Student, 20); //age array_push($Student, “Male”);//Gender array_push($Student, “Swimming”); //hobby 배열내의 요소가 . . . array_push($Student, “Swimming”); //hobby array_push($Student, true);//자취여부 array_push($Student, 7);//좋아하는 숫자 $Students2 = array(); array_push($Student, “Emily”); //name array_push($Student, 24); //age array_push($Student, “Female”);//Gender array_push($Student, false); //자취여부 array_push($Student, 24);//좋아하는 숫자 . . . . 배열내의 요소가 많아 질 수록 코딩 시 헷갈릴 수 있다.
  • 17. Bad Smells 8) Lazy Class ->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다. 이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다. Person TelephoneNumber ->리팩토링 이후 기능이 축소되거나 쓸모 없어진 클래스 Person name getTelephoneNumber() TelephoneNumber areaCode number getTelephoneNumber() 사용 1회 사용 1회 총 2회
  • 18. Bad Smells 8) Lazy Class class Person{ private $_name; //이름 private $_officeTelephoneNumber = new TelephoneNumber(); //회사전화(객체) public function getName(){ return $this->_name; } //전화번호가져오기 -> 전화객체에서 public function getTelephoneNumber(){ return $this->_officeTelephoneNumber->getTelephoneNumber(); } //전화객체가져오기 ->전화객체에서 funcion getOfficeTelephone(){ return $this->_officeTelephoneNumber; } }
  • 19. Bad Smells 8) Lazy Class class TelephoneNumber{ private $_number; // 개인고유번호 private $_areaCode; // 지역번호 //전화번호 가져오기 ; 지역번호 + 개인고유번호 public function getTelephoneNumber(){ return “(“.$this->_areaCode.”) ”. $this->_number } public function getAreaCode(){ return $this->_areaCode;return $this->_areaCode; } public function setAreaCode($arg){ $this->_areaCode = $arg; } public function getNumber(){ return $this->_number; } public function setNumber($arg){ $this->_number = $arg; } }
  • 20. Bad Smells 8) Lazy Class ->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다. 이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다. -> 추후에 기능이 확장되거나, 활용될 가치가 없다고 판단되면 Lazy Class! Person name getTelephoneNumber() TelephoneNumber areaCode number getTelephoneNumber()
  • 21. Bad Smells 9) 추측성 일반화 (Speculative Generality) ->일어날 가능성이 거의 없는 일까지 다 대비한 필요없는 코드들은 제거하 라. 모든 기능들과 절차들은 제대로 이용되었을 때 쓸모가 있다. Class Test 만약을 위한 멤버변수 1 만약을 위한 멤버변수 2 만약을 위한 멤버변수 3 만약을 위한 멤버변수 4만약을 위한 멤버변수 4 …… 만약을 위한 멤버변수 100 만약을 위한 메소드 1 만약을 위한 메소드 2 만약을 위한 메소드 3 …. If 만약을 위한 분기문 1 If 만약을 위한 분기문 2 If 만약을 위한 분기문 3 ……
  • 22. Bad Smells 10) 임시 필드 (Temporary Field) ->때로는 어떤 객체 안의 인스턴스 변수가 특정 상황에서만 세팅되는 경우 가 있다. 보통은 객체의 모든 변수가 값을 가지고 있을 거라고 기대하기 때 문에 이런 코드는 이해하기 어렵다. Student $Name //학생이름 $AGE // 학생나이$AGE // 학생나이 $height // 학생키 $temp // 평균 낼 때 사용되는 임시변수 $temp2 // function4와 5, 8에서 사용되는 임시변수 …. Function 1(){} Function 2(){} Function 평균(){} Function 4(){} ……
  • 23. Bad Smells 11) 지나친 관여(Inappropriate Intimacy) -> 간혹 클래스끼리 관계가 지나치게 밀접한 나머지 서로의 private 를 알 아내느라 시간을 낭비하게 되는 경우가 있다. A Private $a B extends C Private $b C Private $c = new D().getD(); Protected getC() Private $a Public getA() Private $b = new C().getC() Public getB() Protected getC() D Private $d = 1 Protected getD() Protected 1. 같은 package 내의 모든 클래스에서 접근가능 2. 다른 패키지의 클래스라도 해당클래스 상속시 접근가능
  • 24. Bad Smells 12) 불완전한 클래스 (Incomplete Class) -> One that doesn’t do everything you need. Sort Member Quick Sort? Member variables. Bubble Select Insertion Merge . . . Quick Sort? 오름차순?
  • 25. Bad Smells 13) 방치된 상속물 (Refused Bequest) -> 서브클래스는 메소드와 데이터를 그 부모 클래스로부터 상속 받는다. 그러나 만약 서브클래스가 그들에게 주어진 것을 원치 않는다거나, 필요하지 않는 경우. Parents function a SonA function a //상속 function b GrandSonAA function a //상속 function b//상속 function c GrandSonAB SonB function a //상속 function b GrandSonBA
  • 26. Fun!
  • 27. Fun!
  • 28. Fun!
  • 29. Fun!
  • 30. Software Metrics - 소프트웨어의 Quality를 평가 할 수 있는 방법 4가지 • Pakages, classes, instance variables, methods, paramethers, lines • 적당하고 자연스럽게 적을수록 좋다. Count (수량) • 메소드 안에서의 분기문 및 제어문의 수량. // • 많을수록 복잡하다. 한 메소드안에는 10개 미만으로 유지하는게 좋다. Clarity (명확성) • 하나의 단위 내에서, 한 기능을 수행하기 위해 각 구성 요소들이 가까이 있는 경우 • 모듈은 응집도를 높이기 위한 방안 중 하나. • OOP는 정적인데이터와 동작을 함께 묶어 객체를 정의함으로써 높은 응집도를 얻음 • 4장에서 LCOM 의 값이 0에 가까울 수록 응집도가 높음 Cohension (응집도) • 코드기반의 패키지(모듈,클래스,함수,라이브러리등)이 얼마나 독립적으로 움직일 수 있는가? Coupling (결합도)
  • 32. Refactoring 1. 메소드 정리 2. 객체나 클래스 사이의 이동 3. 데이터의 재구성 4. 조건문을 이해하기 쉽게 단순화4. 조건문을 이해하기 쉽게 단순화 5. 메소드 호출 단순화 6. 상속관계 재구성
  • 33. Refactoring How to do ? 1) Renaming 7) Simplifying conditionals 2) Extracting a method 8) Removing Useless Code 3) Extracting a methods 9) Removing Violations to Layering Principles 4) Reorganizing a class 10) Merging Similar Functions /Modules4) Reorganizing a class 10) Merging Similar Functions /Modules 5) Unifying data clumps 11) Separating Model, View, Controller Code 6) Removing a parameter
  • 34. Refactoring - Renaming 네이밍 관례와 표준 파스칼 표기법 "PascalCase" "쌍봉낙타" 표기법 첫 단어를 대문자로 시작하는 카멜 표기법첫 단어를 대문자로 시작하는 카멜 표기법 예시: BackgroundColor, TypeName, PowerPoint
  • 35. Refactoring - Renaming 네이밍 관례와 표준 카멜 표기법 "camelCase" "단봉낙타" 표기법 첫글자는 소문자, 단어와 단어 만나면 첫 글자 -> 대문자단어와 단어 만나면 첫 글자 -> 대문자 띄어쓰기 대신 대문자로 단어를 구분하는 표기 방식 예시: backgroundColor, typeName, iPhone
  • 36. Refactoring - Renaming 네이밍 관례와 표준 헝가리안 표기법 -. 헝가리안 개발자가 창시 -. 변수명 맨 앞에 자료형을 명시함 예시:예시: -. iNum, iCnt, dAmount // int ,int, double 언더바 표기법(Underbar Notation), Snake Notaion -. 단어와 단어 사이에 언더바 -. user_name
  • 37. Refactoring - Renaming 네이밍 관례와 표준 1.1. 클래스 명에는 파스칼 표기법을 사용한다. public class HelloWorld { ... } 1.일반적으로 클래스 이름은 명사명사들의 조합 혹은 형용사형용사 ++ 명사로명사로 지정한다.} 1.2. 함수(Method) 명에는 카멜 표기법을 사용한다. void sayHello(string name) { ... } 지정한다. 2. 메소드는 동사동사 ++ 명사명사 의의 형태로 지정하는 것 이 일반적이다.
  • 38. Refactoring - Renaming 네이밍 관례와 표준 올바른 클래스명의 예 class LoginAction; class HTTPRequest; : 축약어는 모두 대문자로 사용(HTTP는 범용적으로 사용되는 축약어) abstract class AbstractUserInformation; 잘못된 클래스명의 예 class GSL; : 정확하게 약어의 뜻을 유추할 수 없음 class my_action; : 클래스 명이 소문자로 시작되어 클래스 명 식별이 쉽지 않고, 밑줄을 사용하여 자바 API와 일관성이 떨어짐 class 사용자; : 한글을 클래스 명으로 사용할 경우 일부 OS에서 클래스를 읽을 수 없음 class DoIt; : 클래스는 하나의 엔티티(entity)를 뜻하므로, 어떠한 행동을 기술하는 동사를 사용할 경우, 클래스의 정확한 용도를 유추하기가 어려움
  • 39. Refactoring - Renaming 올바른 메소드명의 예 Customer getCustomer(); void drawCircle(int x, int y, int radius); boolean isLive()//boolean의 경우 is를 주로 앞에 붙인다. 클래스 명과 마찬가지로 범용적으로 통하는 경우를 제외하고는 되도록 축약어클래스 명과 마찬가지로 범용적으로 통하는 경우를 제외하고는 되도록 축약어 를 사용하지 않는 것을 원칙으로 하며, 부득이하게 사용해야 할 경우 축약어는 모두 대문자로 지정한다. 예) HTTP, ID HTTPHeader getHTTPHeader(); void setMessageID(MessageID msgID);
  • 40. Refactoring - Renaming 네이밍 관례와 표준 1.3. 변수와 함수 파라미터에는 카멜 표기법을 사용한 다. int totalCount = 0; void SayHello(string name) {{ string fullMessage = "Hello " + name; ... }
  • 41. Refactoring - Renaming 네이밍 관례와 표준 1.4. 인터페이스에는 접두사 "I"가 포함된 파스칼 표기법을 따른다. 예 : IEntity 1.5. 변수명에 헝가리안 표기법을 사용하지 않는다. 이전에는 많은 프로그래머들이 변수명에 데이터 타입에 해당하는 접두사를 첨가하 였다. 즉, 멤버변수에는 아래와 같이 m_ 을 접두사로 사용하는 것과 같은 헝가리안 표기법을 사용했었다. string m_sName; int nAge;
  • 42. Refactoring - Renaming 네이밍 관례와 표준 1.6. 변수에 모든 의미를 충분히 담아라(약어를 사용하지 말것). - 좋은 예 string address int salary - 나쁜 예 string nam string addrstring addr int sal 1.7. "i, n, s,..."와 같이 한 글자로 된 이름을 사용하지 말것. i, n, s 보다는 index, temp 와 같은 이름을 사용한다. 한 가지 예외가 있다면 루프에서 반복을 의미하는 변수를 허용하는 경우이다. for ( int i = 0; i < count; i++ ) { ... }
  • 43. Refactoring - 10) Merging Similar Functions 8) Lazy Class ->클래스를 생성할 때마다, 그것을 유지하고 이해하기 위한 비용이 발생한다. 이 비용을 감당할만큼 충분한 일을 하지 않는 클래스는 삭제되어야 한다. ->추후에 기능이 확장되거나, 활용될 가치가 없다고 판단되면 Lazy Class! Person name getTelephoneNumber() TelephoneNumber areaCode number getTelephoneNumber()
  • 44. Refactoring - 10) Merging Similar Functions 8) Lazy Class class Person{ private $_name; //이름 private $_officeTelephoneNumber = new TelephoneNumber(); //회사전화(객체) public function getName(){ return $this->_name; } //전화번호가져오기 -> 전화객체에서 public function getTelephoneNumber(){ return $this->_officeTelephoneNumber->getTelephoneNumber(); } //전화객체가져오기 ->전화객체에서 funcion getOfficeTelephone(){ return $this->_officeTelephoneNumber; } }
  • 45. Refactoring - 10) Merging Similar Functions 8) Lazy Class class TelephoneNumber{ private $_number; // 개인고유번호 private $_areaCode; // 지역번호 //전화번호 가져오기 ; 지역번호 + 개인고유번호 public function getTelephoneNumber(){ return “(“.$this->_areaCode.”) ”. $this->_number } public function getAreaCode(){ return $this->_areaCode;return $this->_areaCode; } public function setAreaCode($arg){ $this->_areaCode = $arg; } public function getNumber(){ return $this->_number; } public function setNumber($arg){ $this->_number = $arg; } }
  • 46. Refactoring - 10) Merging Similar Functions class Person{ //논리적 개념의 범위가 더욱 큰 Person으로 변경 private $_number; // 개인고유번호 private $_areaCode; // 지역번호 private $_name; //이름, 원래 Person의 것 //전화번호 가져오기 ; 지역번호 + 개인고유번호 public function getTelephoneNumber(){ return “(“.$this->_areaCode.”) ”. $this->_number} public function getAreaCode(){ return $this->_areaCode;} public function setAreaCode($arg){ $this->_areaCode = $arg;} public function getNumber(){ return $this->_number;} public function setNumber($arg){ $this->_number = $arg;} public function getName(){ //원래 Person의 것 return $this->_name; } }
  • 47. Refactoring - 2) Extracting a method Motive : 메서드가 너무 길거나, 코드에 주석을 달아야만 의도를 이해할 수 있을 때 필요하다. ( Bed Smell - Long Method, Too Many comments) Why? -> 1. 메서드가 적절히 잘게 쪼개져 있으면 다른 메서드에서 쉽게 사용 할 수 있다. 2. 재정의하기 쉽다2. 재정의하기 쉽다
  • 48. Refactoring - 2) Extracting a method How to? -> 1. 목적에 부합하는 이름의 새 메서드를 생성한다. 이때 메서드명은 원리가 아니라 기능을 나타내는 이름이어야 한다. 2. 기존 메서드에서 빼낸 코드를 새로 생성한 메서드로 복사한다. 3. 추출한 코드에서 기존 메서드의 모든 지역변수 참조를 찾는다. 그것들을 새로 생성한 메서드의 지역변수나 매개변수로 사용 할 것이다.그것들을 새로 생성한 메서드의 지역변수나 매개변수로 사용 할 것이다. 4. 추출한 코드내에서만 사용되는 임시변수가 있다면, 이를 새로생성한 매서드 안에 임시변수로 선언한다. . . .
  • 49. Refactoring - 2) Extracting a method Enumeration 컬렉션인 Vector, Hash의 elements 를 열거하는 인터페이스 import java.util.Vector import java.util.Enumeration public class Test{ public static void main(String[]args){ Vector vt = new Vector(); vt.add("one");vt.add(2);vt.add("셋"); Enumeration et = vt.elements(); while(et.hasMoreElements()){ System.out.print(et.nextElement()+" "); } } } 결과 : one 2 셋
  • 50. Refactoring - 2) Extracting a method Order -Double amount //외상값 합 -Date +getAmount(); // HostPrint + printOwing(){} +getAmount(); // +getDate();
  • 51. Refactoring - 2) Extracting a method Order -Double amount //외상값 합 -Date +getAmount(); // +getDate(); HostPrint -String _name + printOwing(){} void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; //배너 출력 System.out.println (“****************”); System.out.println (“*****고객외상*****”);System.out.println (“*****고객외상*****”); System.out.println (“****************”); //외상액 계산 while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); //elements 추출 outstanding += each.getAmount(); // elements였던 Order객체의 외상값합계추출 } //세부내역 출력 System.out.println (“고객명 : ”+_name); System.out.println (“외상액 : ”+outstanding); }
  • 52. Refactoring - 2) Extracting a method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; printBanner(); //외상액 계산 while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } //세부내역 출력 System.out.println (“고객명 : ”+_name); System.out.println (“외상액 : ”+outstanding); } void printBanner(){ //배너 출력 System.out.println (“****************”); System.out.println (“*****고객외상*****”); System.out.println (“****************”); }
  • 53. Refactoring - 2) Extracting a method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; printBanner(); printDetails(outstanding); //외상액 계산 while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } }} void printBanner(){ //배너 출력 System.out.println (“****************”); System.out.println (“*****고객외상*****”); System.out.println (“****************”); } void printDetails(double outstanding){ //세부내역 출력 System.out.println (“고객명 : ”+_name); System.out.println (“외상액 : ”+outstanding); }
  • 54. Refactoring - 2) Extracting a method void printOwing() { double outstanding = getOutstanding(); // 변수 초기값은 확실한 경우만 메모리에 할당된다. printBanner(); printDetails(outstanding); } } void printBanner(){ //배너 출력 System.out.println (“****************”); System.out.println (“*****고객외상*****”); System.out.println (“****************”); } void printDetails(double outstanding){ //세부내역 출력//세부내역 출력 System.out.println (“고객명 : ”+_name); System.out.println (“외상액 : ”+outstanding); } double getOutstanding(){ //외상액 계산 Enumeration e = _orders.elements(); //외상액 계산시만 사용될 예정이므로 local variable로 double result = 0.0; // 지역변수 및 임시변수이므로 변수명 혼동을 피하기 위해 변경 while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); result += each.getAmount(); } return result; }
  • 55. Refactoring - 2) Extracting a method void printOwing(double previousAmount) { double outstanding = previousAmount * 1.2; outstanding = getOutstanding(); // 변수 초기값은 확실한 경우만 메모리에 할당된다. printBanner(); printDetails(outstanding); } } void printBanner(){ //배너 출력 System.out.println (“****************”); System.out.println (“*****고객외상*****”); System.out.println (“****************”); } void printDetails(double outstanding){ } void printDetails(double outstanding){ //세부내역 출력 System.out.println (“고객명 : ”+_name); System.out.println (“외상액 : ”+outstanding); } double getOutstanding(){ //외상액 계산 Enumeration e = _orders.elements(); //외상액 계산시만 사용될 예정이므로 local variable로 double result = 0.0; // 지역변수 및 임시변수이므로 변수명 혼동을 피하기 위해 변경 while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); result += each.getAmount(); } return result; }
  • 56. Refactoring - 9) Removing Violations to Layering Principles View Controller Model Controller
  • 57. Refactoring - 9) Removing Violations to Layering Principles editshift.php
  • 58. Refactoring - 9) Removing Violations to Layering Principles dbPersons.php PHP는 Dynamic Typing이 가능하다. 따라서 변수의 타입지정은 값 할당 뒤 일어난다. -> 응용가능. (※내부 logic은 유사하다는 전제.)
  • 59. Refactoring - 9) Removing Violations to Layering Principles dbPersons.php Parameter 2개인 함수는 없어서 새로 만듬
  • 61. Testing – 결함 발견시기와 비용 비용 제가원한 소프트웨어가 아니네요. 요구사항분석 설계 개발 운영 고객테스팅이 가장어렵다. (인수테스트 Acceptance Test)
  • 62. Testing – 종류 • 보통 단위테스트 혹은 Unit Test라고 부른다. • 모듈이나 객체, 프로그램과 같이 개별적으로 테스트가 가능한 단위에 대해서 테스트 • 우리나라 SI 거의 안 함 Component Test (컴포넌트 테스트) • 컴포넌트 사이의 인터페이스를 테스트하는 것을 의미한다. Integration Test (통합테스트) • 컴포넌트 사이의 인터페이스를 테스트하는 것을 의미한다. • UI와 서버 부분을 묶거나, 기능 사이에 연결관계를 테스트한다. • 개발된 시스템이 제대로 동작하는지 확인. System Test (시스템테스트) • 고객이 원하는 대로 만들었는지 확인 Acceptance Test (인수테스트)
  • 63. Testing – 종류 • 보통 단위테스트 혹은 Unit Test라고 부른다. • 모듈이나 객체, 프로그램과 같이 개별적으로 테스트가 가능한 단위에 대해서 테스트 • 우리나라 SI 거의 안 함. – 착각함. Component Test (컴포넌트 테스트) 서비스 개발자는 jsp에서의 문제인지, class에서의 문제인지 확인가능 화면테스트 AddMovie.jsp AddManager.class 테스터는 전체의 과정을 알기 힘들다. S T U B D R I V E R
  • 64. Testing – Unit test Stub, driver =단위마다 테스트 코 드(함수,메소드 작성) (※DB의 경우 CRUD에 맞춰서) 개별 메소드마다 실행된다.개별 메소드마다 실행된다. 예) Echo 기능의 메소드일 경우 echo 실행. ※만약 10000개 존재? -> 1만라인 실행 및 1만번 수 행
  • 65. Testing – Unit test UnitTestCase …. generate_new_shift() assertEqual() assertTrue() assertFalse() … 테스트 메소드를 모아놓은 클래스를 만든 후 상속시킨다.
  • 66. Class TestSuite Testing – Test suite A test suite is a collection of “unit tests” Class 1 메소 드 A C test A Class 2 C B test C test B
  • 67. Testing – xUnit Unit test를 위한 Framework. xUnits Languages JUnit, TestNG Java NUnit,csUnit,MbUnit, MSTest .NET Test::Unit Ruby CUnit CCUnit C CppUnit C++ PHPUnit PHP PyUnit Python DbUnit Database utPLSQL PL/SQL leUnit JavaScript,DHTML
  • 69. Testing – UnitTest Cheak list
  • 70. Test Driven Development - TDD What? – Test the program before you write it. – Kent Beck 프로그램 작성하기 전에 테스트 먼저 하라! 디자인 개발 테스트 기존 개발 절차 TestScript 개발 개발 리팩토링 TDD 개발 절차
  • 71. Test Driven Development - TDD What? TestScript 개발 개발 리팩토링 1. TDD는 코드를 먼저 만드는 것이 아니라, Test Script를 먼저 만든다1. TDD는 코드를 먼저 만드는 것이 아니라, Test Script를 먼저 만든다 2. 그다음 실제 서버에서 수행되는 코드를 작성하는데, 먼저 만든 테스트스크립트 를 수행하면 PASS 하도록 코딩한다. 3. 코드작성을 마치고, 그 코드의 가독성, 유지보수성을 높이기 위해 리팩토링한다.
  • 72. Test Driven Development - TDD Test Script – 명시적인 코드로 개발 종료조건을 정해 놓은 것 class Calculator{ public function $sum($a, $b){ return 0; } } class TestScript { $testObject; $test = new Calulator(); $ts = new TestScript($test); $ts->test(); ------결과--------$testObject; public function __constant($obj){ $this->testObject = $obj; } public function test(){ echo ($testObject->sum(10,20) == 30); echo ($testObject->sum(1,2) == 3); echo ($testObject->sum(-10,20) == 10); echo ($testObject->sum(0,0) == 0); } } ------결과-------- false false false true
  • 74. Test Driven Development - TDD What? - 코딩 할 시간도 없는데 무슨 테스트코드를 작성하고 있어?
  • 76. Debugging 재현가능성확보 단서의확보 개발지식이 충분하다면, 단계별로 정확하게 진행이 가능하다. 하지만, 개발지식이 부족 할 경우 무작위로 코드를 고쳐보고 이전상태로 돌려보는 상황이 나타난다. 최악의 경우 검색으로 힌트를 얻어, 소거법으로 하나하나 연관 없는 부분을 단서의분석 가설의수립 가설의검증 소거법으로 하나하나 연관 없는 부분을 제거하기도 한다.
  • 77. Debugging 원초적인 방법으로는 1. Console에 print. 2. Log.debug()와 같이 로거의 메소드를 호출하여  소스에 흔적이 남을 수 있다. 3. IDE tool을 이용하기 - Eclipse, VisualStudio 등등
  • 80. Debugging – IDE Visual Studio
  • 81. Debugging – IDE Visual Studio 중단점에서 멈춤
  • 82. Debugging – IDE Visual Studio
  • 83. Extending the Software for a New Project New Use Case 요구사항 뭐지? User Interface 그래서 뭐필요? ->스케치 Classes& Modules 기존에 있나? 냄새는? Database 이미 정보가 있나? 테이블 더 필요? CRUD Availability? Security 보안정책에 위배? User Help 사용자를 위한 안내는 어떻게 ? Team Discussion 기술적으로 잘 될까? 빼먹은건 없을까?