From 04fa0756464a7ecc37aa41ccc4ef90d525f5717e Mon Sep 17 00:00:00 2001 From: lightorange0v0 Date: Thu, 1 Jun 2023 22:48:09 +0900 Subject: [PATCH] Refactoring: Lane State Pattern --- BowlerFile.java | 2 +- BowlerRegistrationManager.java | 2 +- DecisionMakingState.java | 21 +++++++ EndOfGameState.java | 9 +++ GameInProgressState.java | 12 ++++ Lane.java | 111 ++++++++++++++------------------- LaneState.java | 3 + NoPartyAssignedState.java | 18 ++++++ PartyAssignedState.java | 15 +++++ PauseGameState.java | 16 +++++ SCOREHISTORY.DAT | 8 +++ ScoreCalculatorStrategy.java | 3 + 12 files changed, 154 insertions(+), 66 deletions(-) create mode 100644 DecisionMakingState.java create mode 100644 EndOfGameState.java create mode 100644 GameInProgressState.java create mode 100644 LaneState.java create mode 100644 NoPartyAssignedState.java create mode 100644 PartyAssignedState.java create mode 100644 PauseGameState.java create mode 100644 ScoreCalculatorStrategy.java diff --git a/BowlerFile.java b/BowlerFile.java index d7123a9..ebc2b25 100644 --- a/BowlerFile.java +++ b/BowlerFile.java @@ -25,7 +25,7 @@ class BowlerFile implements BowlerDatabase { /** The location of the bowelr database */ - private static String BOWLER_DAT = "/Users/yeonjoo/Desktop/pattern_team/src/BOWLERS.DAT"; + private static String BOWLER_DAT = "/Users/yeonjoo/Desktop/pattern_team/BallingManagementSystem_refactoring/BOWLERS.DAT"; private BowlerFile() {} diff --git a/BowlerRegistrationManager.java b/BowlerRegistrationManager.java index 40b1f00..5035a1a 100644 --- a/BowlerRegistrationManager.java +++ b/BowlerRegistrationManager.java @@ -22,7 +22,7 @@ public Bowler registerPatron(String nickName) { try { // only one patron / nick.... no dupes, no checks - patron = BowlerFile.getBowlerInfo(nickName); + patron = BowlerFile.getInstance().getBowlerInfo(nickName); } catch (IOException e) { System.err.println("Error..." + e); diff --git a/DecisionMakingState.java b/DecisionMakingState.java new file mode 100644 index 0000000..e8a81c1 --- /dev/null +++ b/DecisionMakingState.java @@ -0,0 +1,21 @@ +public class DecisionMakingState implements LaneState { + private int result; + + @Override + public void handle(Lane lane){ + if (result == 1) { // yes, want to play again + lane.resetScores(); + lane.resetBowlerIterator(); + lane.setState(lane.gameInProgressState); + lane.handleState(); + } else if (result == 2) { // no, dont want to play another game + lane.printEndGameReportAndNotifyMembers(); + lane.setState(lane.noPartyAssignedState); + lane.handleState(); + } + } + + public void setResult(int result){ + this.result = result; + } +} diff --git a/EndOfGameState.java b/EndOfGameState.java new file mode 100644 index 0000000..a1b7131 --- /dev/null +++ b/EndOfGameState.java @@ -0,0 +1,9 @@ +public class EndOfGameState implements LaneState { + @Override + public void handle(Lane lane){ + int result = lane.promptEndGame(); + ((DecisionMakingState)lane.decisionMakingState).setResult(result); + lane.setState(lane.decisionMakingState); + lane.handleState(); + } +} diff --git a/GameInProgressState.java b/GameInProgressState.java new file mode 100644 index 0000000..7857d26 --- /dev/null +++ b/GameInProgressState.java @@ -0,0 +1,12 @@ +public class GameInProgressState implements LaneState { + @Override + public void handle(Lane lane){ + if (lane.getBowlIterator().hasNext()) { + lane.prepareNextThrow(); + lane.recordFinalScore(); + lane.resetThrow(); + } else { + lane.proceedToNextFrame(); + } + } +} diff --git a/Lane.java b/Lane.java index d5ec910..65e8605 100644 --- a/Lane.java +++ b/Lane.java @@ -134,9 +134,14 @@ import java.util.Vector; import java.util.Iterator; import java.util.HashMap; -import java.util.Date; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; public class Lane extends Thread implements PinsetterObserver { + final LaneState noPartyAssignedState, + partyAssignedState, gameInProgressState, decisionMakingState, + endOfGameState, pauseGameState; + private LaneState state; private Party party; private Pinsetter setter; private HashMap scores; @@ -174,6 +179,14 @@ public Lane() { subscribers = new Vector(); shf = new ScoreHistoryFile(); + this.noPartyAssignedState = new NoPartyAssignedState(); + this.partyAssignedState = new PartyAssignedState(); + this.gameInProgressState = new GameInProgressState(); + this.decisionMakingState = new DecisionMakingState(); + this.endOfGameState = new EndOfGameState(); + this.pauseGameState = new PauseGameState(); + state = noPartyAssignedState; + gameIsHalted = false; partyAssigned = false; @@ -192,45 +205,20 @@ public void run() { // Long Method Refactoring while (true) { - if(partyAssigned){ // we have a party on this lane, - // 동일한 적용인 점에서 분리 - if(!gameFinished){ // so next bower can take a throw - handleGamePlay(); // 게임 시작을 핸들링하는 메소드 - } else{ - handleEndOfGame(); // 게임 종료를 핸들링하는 메소드 - } - } - - doSleep(10); - } - } - - private void doSleep(int millis){ // 중복된 sleep()을 메소드로 변경 - try{ - sleep(millis); - } catch (Exception e) {} - } - - private void handleGamePlay(){ // 게임 시작에 대한 메소드 - gameDoSleep(); - - if (bowlerIterator.hasNext()) { - prepareNextThrow(); - recordFinalScore(); - resetThrow(); - } else { - proceedToNextFrame(); + handleState(); + //doSleep(10); } } - private void gameDoSleep(){ // 게임 정지에 대한 sleep() 메소드 - while(gameIsHalted){ - doSleep(10); - } - } + public void setState(LaneState state) { + this.state = state; + } + public void handleState() { + state.handle(this); + } - private void prepareNextThrow(){ // 다음 볼이 던지도록 반복 + public void prepareNextThrow(){ // 다음 볼이 던지도록 반복 currentThrower = (Bowler)bowlerIterator.next(); canThrowAgain = true; tenthFrameStrike = false; @@ -241,7 +229,7 @@ private void prepareNextThrow(){ // 다음 볼이 던지도록 반복 } } - private void recordFinalScore(){ // 마지막 점수 저장 + public void recordFinalScore(){ // 마지막 점수 저장 if (frameNumber == 9) { finalScores[bowlIndex][gameNumber] = cumulScores[bowlIndex][9]; saveScore(); @@ -250,35 +238,32 @@ private void recordFinalScore(){ // 마지막 점수 저장 private void saveScore(){ // 현재 점수 저장 try{ - Date date = new Date(); - String dateString = "" + date.getHours() + ":" + date.getMinutes() + " " + date.getMonth() + "/" + date.getDay() + "/" + (date.getYear() + 1900); - shf.addScore(currentThrower.getNickName(), dateString, new Integer(cumulScores[bowlIndex][9]).toString()); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm MM/dd/yyyy"); + LocalDateTime now = LocalDateTime.now(); + String dateString = now.format(formatter); + + shf.addScore(currentThrower.getNickName(), dateString, Integer.toString(cumulScores[bowlIndex][9])); } catch (Exception e) {System.err.println("Exception in addScore. "+ e );} } - private void resetThrow(){ // 다음 throw를 위해 모든 상태 초기화 + public void resetThrow(){ // 다음 throw를 위해 모든 상태 초기화 setter.reset(); bowlIndex++; } - private void proceedToNextFrame(){ // 다음 프레임을 위한 동작처리 + public void proceedToNextFrame(){ // 다음 프레임을 위한 동작처리 frameNumber++; resetBowlerIterator(); bowlIndex = 0; if (frameNumber > 9) { gameFinished = true; gameNumber++; + setState(this.endOfGameState); + handleState(); } } - private void handleEndOfGame(){ // 게임 종료에 대한 핸들링 - int result = promptEndGame(); - processEndGameResult(result); - // TODO: send record of scores to control desk - } - - - private int promptEndGame(){ // 게임 종료를 위한 응답 반영 + public int promptEndGame(){ // 게임 종료를 위한 응답 반영 EndGamePrompt egp = new EndGamePrompt( ((Bowler) party.getMembers().get(0)).getNickName() + "'s Party" ); int result = egp.getResult(); egp.distroy(); @@ -286,17 +271,8 @@ private int promptEndGame(){ // 게임 종료를 위한 응답 반영 System.out.println("result was: " + result); return result; } - private void processEndGameResult(int result){ // 재시작 혹은 체크 아웃 응답에 대한 분기 - if (result == 1) { // yes, want to play again - resetScores(); - resetBowlerIterator(); - } else if (result == 2) {// no, dont want to play another game - printEndGameReportAndNotifyMembers(); - } - } - - private void printEndGameReportAndNotifyMembers(){ // 점수 보고서 생성 및 출력 + public void printEndGameReportAndNotifyMembers(){ // 점수 보고서 생성 및 출력 Vector printVector; EndGameReport egr = new EndGameReport( ((Bowler)party.getMembers().get(0)).getNickName() + "'s Party", party); printVector = egr.waitForResult(); @@ -387,7 +363,7 @@ public void receivePinsetterEvent(PinsetterEvent pe) { * @pre the party as been assigned * @post the iterator points to the first bowler in the party */ - private void resetBowlerIterator() { + public void resetBowlerIterator() { bowlerIterator = (party.getMembers()).iterator(); } @@ -398,7 +374,7 @@ private void resetBowlerIterator() { * @pre the party has been assigned * @post scoring system is initialized */ - private void resetScores() { + public void resetScores() { Iterator bowlIt = (party.getMembers()).iterator(); while ( bowlIt.hasNext() ) { @@ -408,9 +384,7 @@ private void resetScores() { } scores.put( bowlIt.next(), toPut ); } - - - + gameFinished = false; frameNumber = 0; } @@ -603,6 +577,13 @@ public boolean isGameFinished() { return gameFinished; } + public boolean isGameHalted(){ + return gameIsHalted; + } + + public Iterator getBowlIterator(){ + return bowlerIterator; + } /** subscribe * * Method that will add a subscriber @@ -657,6 +638,8 @@ public Pinsetter getPinsetter() { */ public void pauseGame() { gameIsHalted = true; + setState(pauseGameState); + handleState(); publish(lanePublish()); } diff --git a/LaneState.java b/LaneState.java new file mode 100644 index 0000000..de24b58 --- /dev/null +++ b/LaneState.java @@ -0,0 +1,3 @@ +public interface LaneState { + public void handle(Lane lane); +} diff --git a/NoPartyAssignedState.java b/NoPartyAssignedState.java new file mode 100644 index 0000000..418efd2 --- /dev/null +++ b/NoPartyAssignedState.java @@ -0,0 +1,18 @@ +public class NoPartyAssignedState extends Thread implements LaneState { + @Override + public void handle(Lane lane){ + if(lane.isPartyAssigned() == true){ + lane.setState(lane.partyAssignedState); + lane.handleState(); + } + else{ + doSleep(10); + } + } + + private void doSleep(int millis){ // 중복된 sleep()을 메소드로 변경 + try{ + sleep(millis); + } catch (Exception e) {} + } +} diff --git a/PartyAssignedState.java b/PartyAssignedState.java new file mode 100644 index 0000000..d0ee4cb --- /dev/null +++ b/PartyAssignedState.java @@ -0,0 +1,15 @@ +public class PartyAssignedState implements LaneState { + + + @Override + public void handle(Lane lane){ + if(lane.isGameFinished() == false){ + lane.setState(lane.pauseGameState); + lane.handleState(); + } + else{ + lane.setState(lane.endOfGameState); + lane.handleState(); + } + } +} diff --git a/PauseGameState.java b/PauseGameState.java new file mode 100644 index 0000000..c996b65 --- /dev/null +++ b/PauseGameState.java @@ -0,0 +1,16 @@ +public class PauseGameState extends Thread implements LaneState { + @Override + public void handle(Lane lane){ + while(lane.isGameHalted()){ + doSleep(10); + } + lane.setState(lane.gameInProgressState); + lane.handleState(); + } + + private void doSleep(int millis){ // 중복된 sleep()을 메소드로 변경 + try{ + sleep(millis); + } catch (Exception e) {} + } +} diff --git a/SCOREHISTORY.DAT b/SCOREHISTORY.DAT index ff032d9..4623074 100644 --- a/SCOREHISTORY.DAT +++ b/SCOREHISTORY.DAT @@ -25,3 +25,11 @@ Tom 18:9 4/2/2023 134 Jim 18:9 4/2/2023 101 Jim 22:34 4/2/2023 161 Mike 22:34 4/2/2023 120 +Lana 22:32 06/01/2023 119 +Tom 22:32 06/01/2023 138 +Tom 22:33 06/01/2023 128 +TomH 22:33 06/01/2023 193 +Tom 22:34 06/01/2023 149 +Jim 22:34 06/01/2023 102 +Tom 22:40 06/01/2023 99 +TomH 22:40 06/01/2023 108 diff --git a/ScoreCalculatorStrategy.java b/ScoreCalculatorStrategy.java new file mode 100644 index 0000000..11360b7 --- /dev/null +++ b/ScoreCalculatorStrategy.java @@ -0,0 +1,3 @@ +public interface ScoreCalculatorStrategy { + +} \ No newline at end of file