- Created folder Contracts holding the interfaces:
- ICommandProcessor
- IMessage
- IPrinter
- IRandomNumberProvider
- Created folder Messages holding related classes like:
- abstract Message
- Message factory
- OneParameterMessage
- TwoParameterMessage
- SimpleMessage
- Printer
- Created folder CommandProcessors holding the different classes processing different commands:
- Abstract CommandProcessor
- Exit, Help, Number, Restart, Top, Invalid CommandProcessors
- Created folder SortingAlgorithms holding the different algorithms used for sorting the scoreboard.
- Created new project for the unit tests
- the tests for each class are separated into different files
- Renamed "numberForGuessString" to "NumberForGuess".
- Renamed "count1" to "CheatAttemptCounter".
- Renamed "count2" to "GuessAttemptCounter".
- Renamed "PlayerInfo" to "PlayerScore".
- Renamed "cows_buls" class to "BullsAndCowsGame".
- Changed the name of the solution from "cows_buls" to "Bulls-And-Cows-Game".
- Extracted class BullsAndCowsCounter, which counts the resulting bulls and cows.
- Moved all related methods to it (CountBullsAndCows, CountCows, CountBulls, CountCowsForCurrentDigit, etc.)
- Extracted class BullsAndCowsResult holding information about the Bulls and Cows on the current turn of the game.
- Extracted class RandomNumberProvider, whose job is to return random numbers in a given range.
- Extracted classes for processing commands and removed unnecessary methods from BullsAndCowsGame class.
- Extracted class ScoreBoard and moved all related methods to it.
- Extracted factory and message classes, as well as printer to handle all messages and objects needed to be printer
- Removed unnecessary empty lines
- Before
public string NickName { get { return nickName; } set { if (nickName == String.Empty) { throw new ArgumentException("NickName should have at least 1 symbol!"); } else { nickName = value; } } }
- After
public string NickName { get { return this.nickName; } set { if (string.IsNullOrWhiteSpace(value)) { throw new ArgumentNullException("NickName should have at least 1 symbol!"); } this.nickName = value; } }
- Before
- Fixed inconsistent line endings
- Removed unnecessary variable "c" and method
- Included "this" everywhere
- Documented everything
- Added access modifiers
- Ordered usings alphabetically for easier following
- Added empty lines where necessary
- Introduced constants
- Examples
private const byte GuessNumberLength = 4; private const byte AllDigitsCount = 10;
public const string FilePath = "../../Common/scores.txt";
- Examples
- Singleton:
- RandomNumberProvider - guarantees a single instance when creating a RandomNumberProvider
- ScoreBoard - allows for only one ScoreBoard
- Lazy Initialization:
- ScoreBoard - creation is delayed until needed
- RandomNumberProvided - delayed until needed
- Simple Factory:
- MessageFactory - Creating different Messages based on an enum
- Composite:
- Message - allows SimpleMessage, OneParameterMessage and TwoParameterMessage to be treated in the same way
- Facade:
- BullsAndCowsArcade - creates, initializes, prepares all needed instances and starts the game
- Chain of Responsibility:
- CommandProcessor - commands are passed from one processor to another allowing for easy extension of command handling
- Strategy:
- In BullsAndCowsGame constructor, Interfaces are passed as dependencies, allowing the user to implement different logic for them
- Sorter - the sorting algorithm of the scoreboard can easily be exchanged for another
- Single Responsibility Principle
- CommandProcessor - each processor handles on it's own command or passes to the next
- PlayerScore - only holds information about the score of the player
- BullsAndCowsResult - only holds the current result
- BullsAndCowsCounter - only calculates the result based on the number and the guess
- Open/Close Principle
- CommandProcessor - easily extended by creating new CommandProcessors. No need to edit the other processors
- Sorter - easy way to add new algorithms for sorting which can be used in the scoreboard
- Liskov Substitution Principle
- CommandProcessors
- Sorters
- Interface Segregation Principle
- ICommandProcessor - implementing only the vital parts of the Chain of Responsibility pattern
- IMessage - no unneeded methods
- IRandomNumberProvider - small interface with only the most important
- Dependency Inversion Principle
- BullsAndCowsGame - outside dependencies are passed through the constructor