Интересно мнение экспертов. Программа угадывает задуманное число, и пишет за скольо ходов она угадала.
Класс Main
public class Main {
public static void main(String[] args) {
GuessingConsoleGame game = new GuessingConsoleGame();
game.Start();
}
}
Класс GuessingConsoleGame
import java.util.Scanner;
public class GuessingConsoleGame {
public void Start() {
Scanner scanner = new Scanner(System.in);
GuessingBinary guessing = new GuessingBinary();
System.out.println("Guessing game number");
System.out.println("If we guessed your num - press [y]" +
"\nIf your number bigger than proposed by us - press [>]" +
"\nIf your number less than proposed us - press [<]");
System.out.print("Enter min border: ");
int min = scanner.nextInt();
System.out.print("Enter max border: ");
int max = scanner.nextInt();
while (max < min) {
System.out.println("Max can't be less than min. Try again");
System.out.print("Enter max border: ");
max = scanner.nextInt();
}
guessing.initialization(min, max);
while (!guessing.isTrue()) {
System.out.println("Attempt: " + guessing.getCount());
System.out.println("Your num is: " + guessing.getGuessedNum());
System.out.print(":");
guessing.guessing(scanner.next());
}
}
}
Класс GuessingBinary
public class GuessingBinary {
private int min, max;
private int count;
private int guessedNum;
private boolean isTrue;
private int half;
public void initialization(int min, int max) {
this.min = min;
this.max = max;
isTrue = false;
count = 1;
half = max / 2;
guessedNum = half;
}
public int getGuessedNum() {
return guessedNum;
}
public int getCount() {
return count;
}
public boolean isTrue() {
return isTrue;
}
public void guessing(String string) {
if (string.equals("y")) {
isTrue = true;
} else if (string.equals("<")) {
max = half;
} else if (string.equals(">")) {
min = half;
}
half = ((max - min) / 2) + min;
count++;
guessedNum = half;
}
}
Затолкать все методы в один класс != хорошо.
По сути, у вас тут плохо всё.
1) у вас есть класс Guessing
, но пучему то он делает не только Guessing
, но ещё и занимаетеся валидацией, выводом в консоль, хренением состояния. Это всё нарушает S из SOLID и делает вашу программу более связной. Точнее, выводит её на максимальный уровень связности, так как у вас по сути все делает один класс. Вы говорите, что применяете ООП - поясните, какие приемы, кроме создания класса, из ООП вы применили?
2) Единственно полезный метод из всего класса Guessing
у вас - это метод guessedNum
, который внезапно приватный. То есть у вас класс предназначен для угадывания числа, но метод угадать число
у него недоступен. Это как так?
3) Вот в этом методе
public void setMax(int max) {
if (min > max) {
System.out.println("Max value can't be less than min. So we have changed them");
this.max = min;
min = max;
} else {
this.max = max;
}
}
Вы решаете за юзера, какое вам надо угадать число. В чем смысл угадывания числа, которое вы сами за юзера и назначили? Почему указанием значений по умолчанию занимается класс, который эти значения угадывает? Вы не видите тут логических противоречий?
Что можно было бы сделать:
чтобы понять ООП немножко получше, я добавлю вам условие - что если у нас будет несколько способов угадать число? Тогда нам понадобится интерфейс, например
interface GuessingNumber {
int guessedNum(int min, int max, int userNum);
}
Напишекм парочку имплементаций, ваша
class GuessingBinary implements GuessingNumber {
@Override
public int guessedNum(int min, int max, int userNum) {
int count = 0;
boolean isTrue = false;
int half = max / 2;
while (!isTrue) {
count++;
if (userNum == half || userNum == max || userNum == min) {
isTrue = true;
} else if (userNum < half) {
max = half;
} else {
min = half;
}
half = ((max - min) / 2) + min;
}
return count;
}
}
Линейная
class GuessingLinear implements GuessingNumber {
@Override
public int guessedNum(int min, int max, int userNum) {
int count = 0;
for (int i = min; i <= max; i++) {
count++;
if (i == userNum) break;
}
return count;
}
}
Напишем класс для вашей игры
class GuessingConsoleGame {
private GuessingNumber guessing;
public GuessingConsoleGame(GuessingNumber guessing) {
this.guessing = guessing;
}
public void Start() {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter min border: ");
int min = scanner.nextInt();
System.out.println("Enter max border: ");
int max = scanner.nextInt();
while (max < min) {
System.out.println("max cant be less than " + min + ". Please, try again.");
System.out.println("Enter max border: ");
max = scanner.nextInt();
}
System.out.print("Enter num: ");
int userNum = scanner.nextInt();
while (userNum < min || userNum > max) {
System.out.println("num should be between " + min + " and " + max + ". Please, try again.");
System.out.println("Enter num: ");
userNum = scanner.nextInt();
}
int guessCount = guessing.guessedNum(min, max, userNum);
System.out.println("You guessed: " + userNum + "\nWe guessed num on " + guessCount + " try");
}
}
Теперь мы можем содавать класс игры и подсовывать ему любую имплементацию для угадываний, например
public static void main(String[] args) {
GuessingNumber guessing = new GuessingBinary();
GuessingConsoleGame game = new GuessingConsoleGame(guessing);
game.Start();
}
Что улучшилось: мы отвязали логику угадывания числа от консоли и вообще от всего. Захотите писать мобильное приложение с угадыванием или сайт - сможете переиспользовать созданные классы. Захотите добавить ещё один способ угадывания числа - достаточно написать 1 класс. реализовать интерфейс, и подставить этот класс в конструктор игры.
Что можно улучшить: класс игры все ещё зависит от консоли. Если вывести ввод/вывод в отдельные классы, то получите ещё большую гибкоть. Но делать это стоит только если вы в самом деле планируете иметь несколько способов ввода, так как просто беспричинное добавление классов увеличивает сложность и не приносит профита.
Что почитать: раз, два, три, ну и про SOLID почитайте и паттерны, лишним не будет.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Допустим, я прошу пользователя ввести любую формулу графика, для простоты пусть это будет
Проблема следующая: когда я добавляю новый комментарий под публикацией на своем сайте, он отображается нормально, но если вдруг зажать какую-либо...