17 | * Bug report: 18 | * The message announcing a correct answer should be 19 | * "Answer was correct!!!!" 20 | * but it is 21 | * "Answer was corrent!!!!" 22 | */ 23 | class GameTestsEpisode3 { 24 | 25 | private ByteArrayOutputStream consoleOutput; 26 | 27 | @BeforeEach 28 | void setup() { 29 | consoleOutput = getConsoleOutput(); 30 | } 31 | 32 | private ByteArrayOutputStream getConsoleOutput() { 33 | ByteArrayOutputStream stream = new ByteArrayOutputStream(); 34 | PrintStream printStream = new PrintStream(stream); 35 | System.setOut(printStream); 36 | return stream; 37 | } 38 | 39 | /** 40 | * Attempt to write a system test: Simply calling method with defect in it. Results in an exception. 41 | */ 42 | @Test 43 | void createSystemTestAttempt1() { 44 | 45 | assertThrows(IndexOutOfBoundsException.class, () -> { 46 | 47 | Game_unmodified game = new Game_unmodified(); 48 | game.wasCorrectlyAnswered(); 49 | 50 | assertEquals("", consoleOutput.toString()); 51 | }); 52 | } 53 | 54 | /** 55 | * Final version of system test: Trace source of exception -> There has to be a player added to the game. 56 | */ 57 | @Test 58 | void gameWasCorrectlyAnsweredWhenNotInPenaltyBox() { 59 | Game_unmodified game = new Game_unmodified(); 60 | game.add("player1"); 61 | game.wasCorrectlyAnswered(); 62 | 63 | assertEquals("player1 was added" + System.lineSeparator() + 64 | "They are player number 1" + System.lineSeparator() + 65 | "Answer was corrent!!!!" + System.lineSeparator() + 66 | "player1 now has 1 Gold Coins." + System.lineSeparator(), consoleOutput.toString()); 67 | } 68 | 69 | @Disabled("Will be deleted later on") 70 | @Test 71 | void correctAnswerMessageIsValid() { 72 | Game game = new Game(); 73 | String expected = "Answer was corrent!!!!"; 74 | String actual = game.getCorrectAnswerMessage(); 75 | 76 | assertEquals(expected, actual); 77 | } 78 | 79 | @Test 80 | void correctAnswerMessageChangedBecauseOfBug() { 81 | Game game = new Game(); 82 | String expected = "Answer was correct!!!!"; 83 | String actual = game.getCorrectAnswerMessage(); 84 | 85 | assertEquals(expected, actual); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/MikadoMethod.md: -------------------------------------------------------------------------------- 1 | # Mikado Method 2 | ## Problem 3 |  4 | 5 | Problem: a simple refactoring ... 6 | 7 |  8 | 9 | ... leads to another necessary refactoring 10 | 11 |  12 | 13 | That way, a tree of dependent refactorings is created 14 | 15 | Solution: only handle one issue at a time 16 | 17 | ## Algorithm 18 | 1. attempt refactoring 19 | 2. run into some issue 20 | 3. write down information about issue in a graph (first refactoring = parent, new issue = child) 21 | 4. revert all changes 22 | 5. begin refactoring issue => 1. step 23 | 6. repeat until all issues are doable (= leaves of the graph) 24 | 7. refactor issues from leaves to the root of the graph 25 | 26 |  27 | 28 | With this algorithm, the tree will be resolved by doing one tiny refactoring after the other, ... 29 | 30 |  31 | 32 | ... until the first refactoring can be implemented without problems. 33 | 34 | ## Exercises 35 | Taken from [Mikado method examples and exercises](https://github.com/mikadomethod), [here](spaceExercise/README.md) are three exercises for the method, including a sample codebase. 36 | 37 | ## Tipps 38 | - Use simple, digital means to "draw" the graph, for example plain text with indentation as levels. Paper doesn't scale well. 39 | - task notation: [ ] for open tasks, [X] for closed tasks 40 | - (huge) Mikado graph can be processed over time instead of in one huge leap. Attention: Too much time = possible changes in graph due to changed codebase 41 | 42 | ## Application 43 | - common trap: thinking to complicated, doing multiple tasks "in parallel" (not possible!) 44 | - method very useful for error tracking, debugging and explorative testing 45 | - very useful for longer analysis 46 | - "I know that I forgot something, but I don't know what ..." - bad feeling! 47 | - Guy that does your code reviews will be happy about smaller commits! 48 | - Drawing forces different thinking processes. 49 | 50 | ## Sources 51 | - Stefan Lieser "Die Mikado Methode" ([youtube](https://www.youtube.com/watch?v=qtIGDc6LTls)) 52 | - [Mikado method examples and exercises](https://github.com/mikadomethod) 53 | - [Home of the Mikado Method](https://mikadomethod.wordpress.com) -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenschwenke/WritingAwesomeJavaCodeWorkshop/cdbb1350cd786861bbc3980a0505859b3935b4e6/src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_1.png -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenschwenke/WritingAwesomeJavaCodeWorkshop/cdbb1350cd786861bbc3980a0505859b3935b4e6/src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_2.png -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenschwenke/WritingAwesomeJavaCodeWorkshop/cdbb1350cd786861bbc3980a0505859b3935b4e6/src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_3.png -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenschwenke/WritingAwesomeJavaCodeWorkshop/cdbb1350cd786861bbc3980a0505859b3935b4e6/src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_4.png -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevenschwenke/WritingAwesomeJavaCodeWorkshop/cdbb1350cd786861bbc3980a0505859b3935b4e6/src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/images/mikado_5.png -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/spaceExercise/README.md: -------------------------------------------------------------------------------- 1 | This repository contains messy code for practicing the Mikado Method, 2 | refactorings and restructurings, clean code and object-oriented design. 3 | 4 | RUNNING THE CODE 5 | ================ 6 | The project has a `Space` class that is the main class. The `main()` method takes no parameters. 7 | 8 | The Space class has two static boolean members that control behavior, `IS_BOUNCING_BALLS` and 9 | `IS_BREAKOUT`. 10 | 11 | If `IS_BOUNCING_BALLS` is `false`, the application is a simulation of a solar system, 12 | not that different from ours. 13 | The value of `IS_BREAKOUT` doesn't matter. 14 | 15 | If `IS_BOUNCING_BALLS` is `true`, the application shows a box of bouncing balls. 16 | If `IS_BREAKOUT` is `true`, the balls can exit through the lower side of the box. 17 | If `IS_BREAKOUT` is `false`, the balls just keep bouncing in the box. 18 | 19 | There are also some tests available. They don't cover all the code, just as in real life. ;-) 20 | 21 | EXERCISES 22 | ========= 23 | Each of the exercises can start from a fresh pull of the code. They can also start from 24 | the previous (working) state as the exercises are completed. 25 | 26 | Easy level 27 | ---------- 28 | ##### Background 29 | The `PhysicalObject` is to be used in another project. However, the entire `Space` class must NOT be shared. 30 | Your task is to extract the `PhysicalObject` to a new project. 31 | ##### Goal 32 | Enable reuse of `PhysicalObject` 33 | 34 | 35 | Intermediate level 36 | ------------------ 37 | ##### Background 38 | The solar system and bouncing balls applications are to be sold in separate delivery packages. 39 | Due to legal issues, the solar system may not contain any bouncing balls logic and vice versa. 40 | ##### Goal 41 | Two separate, minimal, deliverables for bouncing balls and solar system. 42 | 43 | 44 | Difficult level 45 | --------------- 46 | ##### Background 47 | The application is a huge success, and will be ported to a limited 48 | device without Swing/AWT support. The exact API of the new graphics support is 49 | not ready, but to be first on the market when it arrives, you need to start 50 | separating presentation logic from domain ASAP. 51 | ##### Goal 52 | The domain logic is compilable without Swing/AWT dependencies. When Swing/AWT + 53 | any bridging code is available, the application should be runnable. 54 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part2MethodsForLegacyCode/mikadoMethod/spaceExercise/test/TestMergeObjects.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part2MethodsForLegacyCode.mikadoMethod.spaceExercise.test; 2 | 3 | import de.stevenschwenke.java.writingawesomejavacodeworkshop.part2MethodsForLegacyCode.mikadoMethod.spaceExercise.src.PhysicalObject; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | 8 | 9 | /** 10 | * This example code is taken from https://github.com/mikadomethod/space. 11 | */ 12 | class TestMergeObjects { 13 | @Test 14 | void mergeWithoutSpeed() { 15 | PhysicalObject one = new PhysicalObject(1, 1, 0, 0, 0, 1); 16 | PhysicalObject other = new PhysicalObject(1, 0, 1, 0, 0, 1); 17 | PhysicalObject merge = one.absorb(other); 18 | assertEquals(0.5, merge.x, 0.00001); 19 | assertEquals(0.5, merge.y, 0.00001); 20 | assertEquals(0.0, merge.vx, 0.00001); 21 | assertEquals(0.0, merge.vy, 0.00001); 22 | } 23 | 24 | @Test 25 | void mergeWithSpeed() { 26 | PhysicalObject one = new PhysicalObject(1, 1, 0, 1, 0, 1); 27 | PhysicalObject other = new PhysicalObject(1, 0, 1, 0, 1, 1); 28 | PhysicalObject merge = one.absorb(other); 29 | assertEquals(0.5, merge.x, 0.00001); 30 | assertEquals(0.5, merge.y, 0.00001); 31 | assertEquals(0.5, merge.vx, 0.00001); 32 | assertEquals(0.5, merge.vy, 0.00001); 33 | assertEquals(2, merge.mass, 0.00001); 34 | } 35 | 36 | @Test 37 | void mergeWithSpeedAndDifferentMasses() { 38 | PhysicalObject one = new PhysicalObject(1, 1, 1, 1, 0, 1); 39 | PhysicalObject other = new PhysicalObject(4, 0, 0, 0, 1, 1); 40 | PhysicalObject merge = one.absorb(other); 41 | assertEquals(0.2, merge.x, 0.00001); 42 | assertEquals(0.2, merge.y, 0.00001); 43 | assertEquals(0.2, merge.vx, 0.00001); 44 | assertEquals(0.8, merge.vy, 0.00001); 45 | assertEquals(5, merge.mass, 0.00001); 46 | } 47 | 48 | @Test 49 | void headsOnMergeConservesZeroSumMomentum() { 50 | PhysicalObject one = new PhysicalObject(10, 0, 0, 100, 100, 1); 51 | PhysicalObject other = new PhysicalObject(100, 0, 0, -10, -10, 1); 52 | PhysicalObject merge = one.absorb(other); 53 | assertEquals(0, merge.x, 0.00001); 54 | assertEquals(0, merge.y, 0.00001); 55 | assertEquals(0, merge.vx, 0.00001); 56 | assertEquals(0, merge.vy, 0.00001); 57 | assertEquals(110, merge.mass, 0.00001); 58 | } 59 | 60 | @Test 61 | void headsOnMergeConservesMomentum() { 62 | PhysicalObject one = new PhysicalObject(10, 0, 0, 10, 10, 1); 63 | PhysicalObject other = new PhysicalObject(100, 0, 0, 0, 0, 1); 64 | PhysicalObject merge = one.absorb(other); 65 | assertEquals(0, merge.x, 0.00001); 66 | assertEquals(0, merge.y, 0.00001); 67 | assertEquals(100 / 110.0, merge.vx, 0.00001); 68 | assertEquals(100 / 110.0, merge.vy, 0.00001); 69 | assertEquals(110, merge.mass, 0.00001); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/BitSet.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class BitSet { 4 | 5 | public String get(Long factoryOID) { 6 | return null; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/CalenderExcelExportRenderer.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class CalenderExcelExportRenderer { 4 | 5 | public HSSFCellStyle prepareClientCellStyle(Object workBook, boolean b, boolean b1, boolean b2) { 6 | return null; 7 | } 8 | 9 | public HSSFCellStyle prepareFactoryCellStyle(Object workBook, boolean b, boolean b1, boolean b2) { 10 | return null; 11 | } 12 | 13 | public HSSFCellStyle prepareLinieCellStyle(Object workBook, boolean b, boolean b1, boolean b2) { 14 | return null; 15 | } 16 | 17 | public HSSFCellStyle prepareModellCellStyle(Object workBook, boolean b, boolean b1, boolean b2, boolean b3, 18 | boolean color) { 19 | return null; 20 | } 21 | 22 | public HSSFCellStyle getProgrammDatenCellStyle(Object workBook) { 23 | return null; 24 | } 25 | 26 | public HSSFCellStyle getWocheSummeDatenCellStyle(Object workBook) { 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/CellRangeAddress.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class CellRangeAddress { 4 | 5 | public CellRangeAddress(int rowNum, int rowNum1, int eopAnfangsColumn, int eopEndeColumn) { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/DayShortDTOImpl.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class DayShortDTOImpl { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/FactoryCalendarReportModel.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | 4 | public class FactoryCalendarReportModel { 5 | 6 | private BitSet factoryNames; 7 | private BitSet linienNamen; 8 | private BitSet produktNamen; 9 | private String markeName; 10 | private boolean quartal; 11 | private boolean clientFactoryLinieModell; 12 | private boolean clientFactoryModell; 13 | private boolean clientFactory; 14 | private boolean clientFactoryLine; 15 | 16 | public BitSet getFactoryNames() { 17 | return factoryNames; 18 | } 19 | 20 | public void setFactoryNames(BitSet factoryNames) { 21 | this.factoryNames = factoryNames; 22 | } 23 | 24 | public BitSet getLinienNamen() { 25 | return linienNamen; 26 | } 27 | 28 | public void setLinienNamen(BitSet linienNamen) { 29 | this.linienNamen = linienNamen; 30 | } 31 | 32 | public BitSet getProduktNamen() { 33 | return produktNamen; 34 | } 35 | 36 | public void setProduktNamen(BitSet produktNamen) { 37 | this.produktNamen = produktNamen; 38 | } 39 | 40 | public String getClientName() { 41 | return markeName; 42 | } 43 | 44 | public void setMarkeName(String markeName) { 45 | this.markeName = markeName; 46 | } 47 | 48 | public boolean isQuartal() { 49 | return quartal; 50 | } 51 | 52 | public void setQuartal(boolean quartal) { 53 | this.quartal = quartal; 54 | } 55 | 56 | public boolean isClientFactoryLinieModell() { 57 | return clientFactoryLinieModell; 58 | } 59 | 60 | public void setClientFactoryLinieModell(boolean clientFactoryLinieModell) { 61 | this.clientFactoryLinieModell = clientFactoryLinieModell; 62 | } 63 | 64 | public boolean isClientFactoryModell() { 65 | return clientFactoryModell; 66 | } 67 | 68 | public void setClientFactoryModell(boolean clientFactoryModell) { 69 | this.clientFactoryModell = clientFactoryModell; 70 | } 71 | 72 | public boolean isClientFactory() { 73 | return clientFactory; 74 | } 75 | 76 | public void setClientFactory(boolean clientFactory) { 77 | this.clientFactory = clientFactory; 78 | } 79 | 80 | public boolean isClientFactoryLinie() { 81 | return clientFactoryLine; 82 | } 83 | 84 | public void setClientFactoryLine(boolean clientFactoryLine) { 85 | this.clientFactoryLine = clientFactoryLine; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/HSSFCell.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class HSSFCell { 4 | 5 | private HSSFRichTextString cellValue; 6 | private HSSFCellStyle cellStyle; 7 | 8 | public void setCellValue(double cellValue) { 9 | 10 | } 11 | 12 | public HSSFRichTextString getCellValue() { 13 | return cellValue; 14 | } 15 | 16 | public void setCellStyle(HSSFCellStyle cellStyle) { 17 | this.cellStyle = cellStyle; 18 | } 19 | 20 | public HSSFCellStyle getCellStyle() { 21 | return cellStyle; 22 | } 23 | 24 | public void setCellValue(String s) { 25 | 26 | } 27 | 28 | public void setCellValue(HSSFRichTextString cellValue) { 29 | this.cellValue = cellValue; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/HSSFCellStyle.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class HSSFCellStyle { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/HSSFRichTextString.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class HSSFRichTextString { 4 | 5 | public HSSFRichTextString(String markeName) { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/HSSFRow.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class HSSFRow { 4 | 5 | private int rowNum; 6 | 7 | public HSSFCell createCell(int i) { 8 | return null; 9 | } 10 | 11 | public int getRowNum() { 12 | return rowNum; 13 | } 14 | 15 | public void setRowNum(int rowNum) { 16 | this.rowNum = rowNum; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/HSSFSheet.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class HSSFSheet { 4 | 5 | public void autoSizeColumn(int i) { 6 | 7 | } 8 | 9 | public void setColumnWidth(int i, Object quartalprogrammdatencolumnwidth) { 10 | 11 | } 12 | 13 | public void addMergedRegion(CellRangeAddress cellRangeAddress) { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_real_code/StringCharBuffer.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_real_code; 2 | 3 | public class StringCharBuffer { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/legacy_ugly_trivia/GameRunner.java: -------------------------------------------------------------------------------- 1 | package de.stevenschwenke.java.writingawesomejavacodeworkshop.part3ApplyingToLegacyCode.legacy_ugly_trivia; 2 | 3 | 4 | import java.util.Random; 5 | 6 | /** 7 | * This is the Java implementation of the "ugly trivia game", see 8 | * https://github.com/jbrains/trivia/blob/master/java/src/main/java/com/adaptionsoft/games/uglytrivia/Game.java 9 | */ 10 | public class GameRunner { 11 | 12 | private static boolean notAWinner; 13 | 14 | public static void main(String[] args) { 15 | Game aGame = new Game(); 16 | 17 | aGame.add("Chet"); 18 | aGame.add("Pat"); 19 | aGame.add("Sue"); 20 | 21 | Random rand = new Random(); 22 | 23 | do { 24 | 25 | aGame.roll(rand.nextInt(5) + 1); 26 | 27 | if (rand.nextInt(9) == 7) { 28 | notAWinner = aGame.wrongAnswer(); 29 | } else { 30 | notAWinner = aGame.wasCorrectlyAnswered(); 31 | } 32 | 33 | 34 | 35 | } while (notAWinner); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/de/stevenschwenke/java/writingawesomejavacodeworkshop/part3ApplyingToLegacyCode/refactoring/refactoring_checklist.md: -------------------------------------------------------------------------------- 1 | These checklists is extracted from "Refactoring" by Martin Fowler. It can be used together with code that has to be refactored, for example the ugly trivia game. 2 | 3 | # checklist 1: identifying bad smells 4 | [ ] Duplicated Code 5 | [ ] Long method 6 | [ ] Large Class 7 | [ ] Long parameter list 8 | [ ] Divergent Change 9 | [ ] Shotgun Surgery 10 | [ ] Feature Envy 11 | [ ] Data Clumps 12 | [ ] Primitive Obsession 13 | [ ] Switch Statements 14 | [ ] Parallel Inheritance Hierarchies 15 | [ ] Lazy Class 16 | [ ] Speculative Generality 17 | [ ] Temporary Field 18 | [ ] Message Chains 19 | [ ] Middle Man 20 | [ ] Inappropriate Intimacy 21 | [ ] Alternative Classes with Different Interfaces 22 | [ ] Refused Bequest 23 | [ ] Comments 24 | 25 | # checklist 2: doing the refactorings 26 | ## Simple refactorings 27 | [ ] extract method 28 | [ ] Renaming 29 | [ ] Move Method 30 | [ ] Replace Temporary Variables with Query 31 | [ ] extract method 32 | [ ] replace temp with query 33 | [ ] extract and move methods to create consistent classes 34 | [ ] Introduce inheritance 35 | 36 | ## Composing methods 37 | [ ] Extract method 38 | [ ] Inline method 39 | [ ] Inline temp 40 | [ ] Replace temp with query 41 | [ ] Introduce explaining variable 42 | [ ] Split temporary variable 43 | [ ] Remove assignments to parameters 44 | [ ] Replace method with method object 45 | 46 | ## Moving features between objects 47 | [ ] Move method 48 | [ ] Move field 49 | [ ] Extract class 50 | [ ] Inline class 51 | [ ] Hide delegate 52 | [ ] Remove middle man 53 | [ ] Introduce foreign method 54 | [ ] Introduce local extension 55 | 56 | ## Organizing Data 57 | [ ] Self encapsulate field 58 | [ ] Replace data value with object 59 | [ ] Change value object to reference object 60 | [ ] Change reference object to value object 61 | [ ] Replace array with object 62 | [ ] Duplicate observed data 63 | [ ] Change unidirectional association to bidirectional 64 | [ ] Change bidirectional association with unidirectional 65 | [ ] Replace magic number with symbolic constant 66 | [ ] Encapsulate field 67 | [ ] Encapsulate collection 68 | [ ] Replace record with data class 69 | [ ] Replace type code with class 70 | [ ] Replace type code with subclasses 71 | [ ] Replace type code with state / strategy 72 | [ ] Replace subclass with fields 73 | 74 | ## Simplifying conditional expressions 75 | [ ] Decompose Conditional 76 | [ ] Consolidate Conditional Expression 77 | [ ] Consolidate duplicate conditional fragments 78 | [ ] Remove control flag 79 | [ ] Replace nested conditional with guard clauses 80 | [ ] Replace conditional with polymorphism 81 | [ ] Introduce null object 82 | [ ] Introduce assertion --------------------------------------------------------------------------------