<Software Modeling & Analysis> 정적분석서 - 영단어수집왕 - Team.# 3 과목명 소프트웨어모델링및분석 담당교수 유준범교수님 201011320 김용현 팀원 201111360 손준익 201111347 김태호 제출일자 2015-06-09 1
Contents. 1. PMD ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 2. Metrics ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 3. FindBugs ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 4. ㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍㆍ 2
1. PMD PMD AddEmptyString Database.java 빈공백문자추가하는부분삭제 - Database.java String sql = "select * from Word where key = "+randomword; PMD AvoidFieldNameMatchingTypeName Alphabet.java Class 이름과동일한변수이름사용부분수정 - Alphabet.java private char name; public char getname(); public void setname(char name); PMD AvoidInstantiatingObjectsInLoops Database.java Database 검색결과가여럿일수있기때문에그때마다새로운객체를생성하여 Vector 에추가하는것이맞다. 따라서코드를수정하지않았다. PMD EmptyIfStmt DictionaryPanel.java, SoundPlayer.java 비어있는조건문삭제 -DictionaryPanel.java if ((!(a.equalsignorecase(""))) && (!(a.equalsignorecase("123")))) 비어있던조건문을! 연산과 && 연산으로하나로합쳐수정하였다. -SoundPlayer.java public void display(string msg) { 내부에불필요한분기문삭제. Library 사용을위해빈 Method 로수정하였다. 3
PMD EmptyStatementNotInLoop SoundPlayer.java SoundPlayer 의비어있는조건문표기에서 ; 을사용하였던부분을삭제하였다. -SoundPlayer.java public void display(string msg) { 내부에불필요한분기문삭제. Library 사용을위해빈 Method 로수정하였다. PMD ExcessiveMethodLength DictionaryPanel.java, PicturePanel.java 가독성을늘리기위해코드가화면바깥으로나갈경우를대비해엔터를많이사용하여코드가길어졌다. 위두클래스에는레이아웃을설정하는코드가있어서내용이길어졌다. Method 내에기능이많은것이아니므로, 코드를수정하지않았다. 4
2. Metrics Metrics Number of Parameters AlphabetBoard.java Constructor 에 parameter 를 8 개전달했던부분을 Init Method(parameter 4 개 ) 와 Constructor(Parameter 3 개 ) 로나누어인수가지나치게많은것을줄였다. public AlphabetBoard (MainFrame frame, MainController maincontrol, GamePanel panel) public void init (int width, int wordwidth, int dx, int dy, int index) Metrics MaCabe Cyclomatic Complexity Board.java cycle method 에서 if 문과논리연산의개수가총 15 개였다. 7 개, 5 개 3 개로나누었다. if (x > dx && y > dy) { flag = 0; else if (x > dx && y < dy) { flag = 1; else if (x < dx && y > dy) { flag = 2; else { flag = 3; switch(flag) { case 0: x--; y--; case 1: x--; y++; case 2: x++; y--; case 3: x++; y++; default: if (x == dx y == dy) return false else return true 5
Metrics Nested Block Depth MainFrame.java MainFrame GameEvent(Event e) Method 내부에인접한 Block 의 Depth 가 total 6 의수치를가지던것을 4 로줄였다. int wordindex = maincontrol.getgamecontroller().getwordindex(); if(maincontrol.getgamecontroller().getword().get Name().charAt(wordIndex) == c maincontrol.getgamecontroller().getword().getna me().charat(wordindex) == (c + 32)) 6
3. FindBugs FindBug SS_SHOULD_BE_STATIC AlphabetBoard.java, Board.java 상수표현을 static 으로지정하였다. - AlphabetBoard.java private static final int DELAY = 2; - Board.java protected static final int B_WIDTH = 350; protected static final int B_HEIGHT = 350; protected static final int DELAY = 8; FindBug SQL_NONCONSTANT_STRING_PASSED Database.java sql 문에사용되는 String 을 Constant 로지정하였다. - Database.java String sql = "update Word set correct = 1 where name = '"; sql = sql.concat(word.getname()); sql = sql.concat("'"); String sql = "update Picture set URL = '"; sql=sql.concat(p.getimageurl()); sql=sql.concat("' where name ='reward'"); String sql = "select * from Word where name = '"; sql = sql.concat(usertypedword); sql = sql.concat("'"); 7
FindBug SF_SWITCH_NO_DEFAULT AlphabetBoard.java Board.java DictionaryPanel.java switch 문에 Default case 를추가하였다. - AlphabetBoard.java switch(result) { case 0: this.x = (int)((double)math.random() * ((double)this.width-(70*ratio))); case 1: this.x = (int)((double)math.random() * ((double)this.width-(70*ratio))); this.x = this.x+ this.width+this.wordwidth; default: - Board.java switch (maincontrol.getgamecontroller().getword().gettype()){ case 1: dx = width / 2 - width / 4-150; dy = height / 2 - height / 4-150; case 2: dx = width / 2 + width / 4-150; dy = height / 2 - height / 4-150; case 3: dx = width / 2 - width / 4-150; dy = height / 2 + height / 4-150; case 4: dx = width / 2 + width / 4-150; dy = height / 2 + height / 4-150; default: -DictionaryPanel.java switch (maincontrol.getdictionarycontroller().getdictionary().getwordarr().elementat(i).gettype()) - default case 추가 8
FindBug DLS_DEAD_LOCAL_STORE MainController.java, DictionaryPanel.java - MainController.java main 함수에서 Frame 호출이므로값을할당한후사용하지않는다. 코드수정을하지않았다. - DictionaryPanel.java new String() 삭제로객체생성을하지않는다. - DictionaryPanel.java String a; FindBug UCF_USELESS_CONTROL_FLOW SoundPlayer.java 불필요한분기문을삭제하였다. - SoundPlayer.java public void display(string msg) { 내부에불필요한분기문삭제. Library 사용을위해빈 Method 로수정하였다. 9
4. ClassDataAbstractionCouplingCheck DictionaryPanel.java, MainFrame, PicturePanel.java KeyListener, KeyAdapter, Runnable 등 Swing Library 를사용하는데있어직접수정하여사용하지않았다. 해당하는부분에서만사용하므로따로변수를만들어활용하지않았다. CyclomaticComplexityCheck Board.java cycle method 에서 if 문과논리연산의개수가총 15 개였다. 7 개, 5 개 3 개로나누었다. if (x > dx && y > dy) { flag = 0; else if (x > dx && y < dy) { flag = 1; else if (x < dx && y > dy) { flag = 2; else { flag = 3; switch(flag) { case 0: x--; y--; case 1: x--; y++; case 2: x++; y--; case 3: x++; y++; default: if (x == dx y == dy) return false else return true 10
EmptyLineSeparatorCheck 모든 Class 라인수가늘어나고, 가독성이더불편해진다고판단하여코드를수정하지않았다. FileTabCharacterCheck Contents Class 를제외한모든 Class 가독성에문제가없다고판단하여코드를수정하지않았다. JavaNCSSCheck DictionaryPanel.java, PicturePanel.java 가독성을늘리기위해코드가화면바깥으로나갈경우를대비해엔터를많이사용하여코드가길어졌다. 위두클래스에는레이아웃을설정하는코드가있어서내용이길어졌다. Method 내에기능이많은것이아니므로, 코드를수정하지않았다. LocalVariableNameCheck DictionaryPanel.java 코드를수정하였다. - DictionaryPanel.java ImageIcon wordicon = new ImageIcon (maincontrol.getdictionarycontroller().getword().getimageurl().replace(".gif", ".jpg")); int animalcount = 0; int plantcount = 0; int toolcount = 0; int nationcount = 0; 위 Local Variable 을사용하던곳에이름을변경하였다. 11
MemberNameCheck AlphabetBoard.java, Board.java, Contents.java, DictionaryPanel.java, GamePanel.java AlphabetBoard 와 Board 는상수를대문자로표현한것이어서코드를수정하지않았고, 나머지클래스의코드를수정하였다. - Contents.java private String soundurl; private String imageurl; - DictionaryPanel.java private TextField searchtextfield; - GamePanel.java int wordlength; int alphabetposx[] = new int[10]; int alphabetposy[] = new int[10]; int alphabetnow; int keyboardwidth; int keyboardheight; private JPanel rewardpanel; 위 Member Variable 을사용하던곳에이름을변경하였다. SeparatorWrapCheck Board.java, DictionaryPanel.java, GamePanel.java, PicturePanel.java 코드작성시줄이너무길어져서화면을벗어나는경우보다다음줄로내려서보이는것이가독성에있어서더좋다고판단하여코드를변경하지않았다. WhitespaceAfterCheck Database.java, AlphabetBoard.java, MainFrame.java 가독성에문제가없다고판단하여코드를변경하지않았다. WhitespaceAroundCheck DictionaryController.java, MainController.java, PictureController.java, Alphabet.java Database.java, Picture.java, Word.java, AlphabetBoard.java 가독성에문제가없다고판단하여코드를변경하지않았다. 12