Этот код был создан, чтобы позволить пользователю вводить, редактировать, искать, удалять и распечатывать отчет обо всех продуктах компании. Есть ли способ улучшить мой код?
public class Admin
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String menuTask, exit;
Scanner sc = new Scanner(System.in); // Allows user input
Products product = new Products(); // Creates the Products class
System.out.println("BRIGHT FUTURE TECHNOLOGIES APPLICATION");
System.out.println("***************************************");
System.out.println("Enter (1) to launch menu or any other key to exit: ");
exit = sc.next();
if (exit.equals("1") == false) {
product.ExitApplication(); // Exits the application
}
do {
menuTask = product.DisplayMenu(); // Displays the menu
switch (menuTask) {
case "1":
exit = product.CaptureProduct(); // Allows user to capture a product
break;
case "2":
exit = product.SearchProduct(); // Allows user to search for a product
break;
case "3":
exit = product.UpdateProduct(); // Allows user to update the product data
break;
case "4":
exit = product.DeleteProduct(); // Allows user to delete a product
break;
case "5":
exit = product.DisplayReport(); // Displays all the products and its data
break;
case "6":
product.ExitApplication(); // Exits the application
break;
default:
System.out.println("Thats not a valid key"); // Displays if the user enters an invalid key
}
} while (exit.equals("1")); // Loops executes at least once and will continue until the user wants to exit
}
}
Products.java
public class Products {
Scanner sc = new Scanner(System.in);
ReportData data = new ReportData();
public String SearchProduct() {
int locationOfProduct;
System.out.println("Please enter the product code to search: ");
locationOfProduct = data.getLocationOfProduct(sc.next());
System.out.println("***************************************");
if (locationOfProduct != -1) {
System.out.println("***************************************");
System.out.println("PRODUCT SEARCH RESULTS");
System.out.println("***************************************");
data.toString(locationOfProduct);
} else {
System.out.println("The product cannot be located. Invalid product key");
}
System.out.println("Enter (1) to launch the menu or any other key to exit");
return sc.next();
}
public void SaveProduct(String prodName, String prodCat, String prodCode, String prodSup, String prodWar, int prodLevel, double prodPrice) {
data.setProductName(prodName);
switch (prodCat) {
case "1":
data.setProductCat("Desktop Computer");
break;
case "2":
data.setProductCat("Laptop");
break;
case "3":
data.setProductCat("Tablet");
break;
case "4":
data.setProductCat("Printer");
break;
case "5":
data.setProductCat("Gaming Console");
break;
}
data.setProductCode(prodCode);
data.setProductSup(prodSup);
data.setProductWar(prodWar);
data.setProductLevel(prodLevel);
data.setProductPrice(prodPrice);
}
public String UpdateProduct() {
String update, war;
int locationOfProduct;
System.out.println("Please enter the product code to update: ");
locationOfProduct = data.getLocationOfProduct(sc.next());
System.out.println("***************************************");
if (locationOfProduct != -1) {
System.out.println("Update the warranty? (y) Yes, (n) No ");
update = sc.next();
if (update.equals("y")) {
System.out.printf("Indicate the new warrenty for %s. Enter (1) for 6 months or any other key for 2 years ", data.getProductName().get(locationOfProduct));
if (sc.next().equals("1")) {
war = "6 Months";
} else {
war = "2 years";
}
data.getProductWar().set(locationOfProduct, war);
System.out.println("Update the product price? (y) Yes, (n) No ");
update = sc.next();
if (update.equals("y")) {
System.out.printf("Enter the new price for %s ", data.getProductName().get(locationOfProduct));
data.getProductPrice().set(locationOfProduct, sc.nextDouble());
}
System.out.println("Update the stock level? (y) Yes, (n) No ");
update = sc.next();
if (update.equals("y")) {
System.out.printf("Enter the new stock level for %s ", data.getProductName().get(locationOfProduct));
data.getProductLevel().set(locationOfProduct, sc.nextInt());
}
}
} else {
System.out.println("The product cannot be located. Invalid product key");
}
System.out.println("Product details have been saved successfully");
System.out.println("Enter (1) to launch the menu or any other key to exit");
return sc.next();
}
public String DeleteProduct() {
int locationOfProduct;
System.out.println("Please enter the product code to delete: ");
System.out.println("***************************************");
locationOfProduct = data.getLocationOfProduct(sc.next());
if (locationOfProduct != -1) {
data.getProductCat().remove(locationOfProduct);
data.getProductCode().remove(locationOfProduct);
data.getProductLevel().remove(locationOfProduct);
data.getProductName().remove(locationOfProduct);
data.getProductPrice().remove(locationOfProduct);
data.getProductSup().remove(locationOfProduct);
data.getProductWar().remove(locationOfProduct);
} else {
System.out.println("The product cannot be located. Invalid product key");
}
System.out.println("Enter (1) to launch the menu or any other key to exit");
return sc.next();
}
public String DisplayMenu() {
System.out.println("Please select one of the following menu items: ");
System.out.println("(1) Capture a new product. n" + "(2) Search for a product. n" + "(3) Update a product. n" + "(4) Delete a product. n" + "(5) Print report. n" + "(6) Exit application. ");
return sc.next();
}
public String CaptureProduct() {
String name, cat, sup, war;
int level;
double price;
System.out.println("CAPTURE A NEW PRODUCT");
System.out.println("*********************");
System.out.println("Enter the product code: ");
String code = sc.nextLine();
System.out.println("Enter the product name: ");
name = sc.nextLine();
System.out.print("Select the product Category:n" + "Desktop Computer - 1n" + "Laptop - 2n" + "Tablet - 3n" + "Printer - 4n" + "Gaming Console - 5 nProduct Category >> ");
cat = sc.nextLine();
System.out.println("Indicate the product warrenty. Enter (1) for 6 months or any other key for 2 years");
if (sc.next().equals("1")) {
war = "6 Months";
} else {
war = "2 years";
}
System.out.printf("Enter the price for %s: ", name);
price = sc.nextDouble();
System.out.printf("Enter the stock level for %s: ", name);
level = sc.nextInt();
System.out.printf("Enter the supplier for %s: ", name);
sup = sc.next();
SaveProduct(name, cat, code, sup, war, level, price); // Saves the details of the product
System.out.println("Product details have been saved successfully");
System.out.println("Enter (1) to launch the menu or any other key to exit");
return sc.next();
}
public void ExitApplication() {
System.exit(0);
}
public String DisplayReport() {
double totalPrice = 0, itemPrice;
int count;
System.out.println("PRODUCT REPORT");
System.out.println("=====================================================");
count = data.getProductCat().size();
for (int i = 0; i < count; i++) {
System.out.printf("PRODUCT %sn", i + 1);
System.out.println("-----------------------------------------------------");
data.toString(i);
System.out.println("-----------------------------------------------------");
itemPrice = Integer.parseInt(data.getProductSup().get(i)) * data.getProductPrice().get(i);
totalPrice = totalPrice + itemPrice ;
}
System.out.println("=====================================================");
System.out.printf("TOTAL PRODUCT COUNT: t%sn", count);
System.out.printf("TOTAL PRODUCT VALUE: tR %sn", totalPrice);
System.out.printf("AVERAGE PRODUCT VALUE: tR %sn", totalPrice / count);
System.out.println("=====================================================");
System.out.println("Enter (1) to launch the menu or any other key to exit");
return sc.next();
}
}
ReportData.java
public class ReportData {
ArrayList<String> productName = new ArrayList<>();
ArrayList<String> productCat = new ArrayList<>();
ArrayList<String> productCode = new ArrayList<>();
ArrayList<String> productSup = new ArrayList<>();
ArrayList<String> productWar = new ArrayList<>();
ArrayList<Integer> productLevel = new ArrayList<>();
ArrayList<Double> productPrice = new ArrayList<>();
public void setProductName(String productName) {
this.productName.add(productName);
}
public void setProductCat(String productCat) {
this.productCat.add(productCat);
}
public void setProductCode(String productCode) {
this.productCode.add(productCode);
}
public void setProductSup(String productSup) {
this.productSup.add(productSup);
}
public void setProductWar(String productWar) {
this.productWar.add(productWar);
}
public void setProductLevel(int productLevel) {
this.productLevel.add(productLevel);
}
public void setProductPrice(double productPrice) {
this.productPrice.add(productPrice);
}
public ArrayList<String> getProductName() {
return productName;
}
public ArrayList<String> getProductCat() {
return productCat;
}
public ArrayList<String> getProductCode() {
return productCode;
}
public ArrayList<String> getProductSup() {
return productSup;
}
public ArrayList<String> getProductWar() {
return productWar;
}
public ArrayList<Integer> getProductLevel() {
return productLevel;
}
public ArrayList<Double> getProductPrice() {
return productPrice;
}
public int getLocationOfProduct(String prodCode) {
return getProductCode().indexOf(prodCode); // Gets the location of the product in the array
}
public void toString(int locationOfProduct){
System.out.printf("PRODUCT CODE:tt%sn", getProductCode().get(locationOfProduct));
System.out.printf("PRODUCT NAME:tt%sn", getProductName().get(locationOfProduct));
System.out.printf("PRODUCT WARRANTY:t%sn", getProductWar().get(locationOfProduct));
System.out.printf("PRODUCT CATEGORY:t%sn", getProductCat().get(locationOfProduct));
System.out.printf("PRODUCT PRICE:ttR%sn", getProductPrice().get(locationOfProduct));
System.out.printf("PRODUCT STOCK LEVEL:t%sn", getProductLevel().get(locationOfProduct));
System.out.printf("PRODUCT SUPPLIER:t%sn", getProductSup().get(locationOfProduct));
}
}
1 ответ
Соглашения об именах
Методы использования Java lowerCamelCase
, как показано в вашем классе ReportData. PascalCase
ist используется только для классов, поэтому имена методов в классе Products следует изменить.
Запутанные имена
Products
не относится к классу, связанному с продуктами, он обрабатывает ввод данных пользователем (предлагаяMenu
вместо)exit
не является флагом выхода, он сохраняет выбор меню пользователя (предлагаяinput
вместо)setProduct*()
ничего не устанавливает, добавляет в список (предлагаяaddProduct*()
вместо)getProduct*()
не получает стоимость отдельного продукта, он получает список значений всех продуктов (предполагаяgetAllProducts*()
вместо)ReportData.toString()
печатает продукт, составленный из списка. Поскольку это перегружаетObject.toString()
это особенно проблематично, поскольку ожидается, что методы с таким именем вернут строковое представление всего объекта ReportData. ПредлагаяprintAll()
вместо.
System.exit ()
В целом этот метод следует использовать редко. Он немедленно останавливает JVM, и поэтому остальная часть программы может быть не в состоянии очистить и / или корректно завершить работу. Здесь это не проблема, но если вы хотите сохранить данные в файл, это будет невозможно, если вы не воспользуетесь ловушкой выключения, что приведет к ненужной сложности.
Кроме того, в этом случае это не обязательно. Вместо, exit
может быть установлен на что угодно, кроме "1"
и цикл do-while завершается нормально, как если бы пользователь запросил его в одном из других диалогов.
По сравнению с логическим
exit.equals("1") == false
неудобно читать. equals()
уже возвращает логическое значение, которое можно использовать непосредственно в операторе if, поэтому нет необходимости сравнивать его с false
.
if (exit.equals("1") == false)
// reads "if exit equals "1" is the same as false" --> weird and long
if (!exit.equals("1"))
// reads "if not exit equals "1"" --> better and shorter
ReportData класс
Кажется, что есть список массивов для каждого атрибута продукта (название, код, гарантия), а продукт — это все, что находится под одним индексом. Это слишком сложно и в конечном итоге приведет к ошибкам и противоречивым данным.
Вместо этого сделайте класс Product
где каждый экземпляр имеет одно имя / код / и т. д. Затем вы можете манипулировать более простым и последовательным ArrayList<Product>
вместо. Этот список может даже быть статическим членом класса Product. В конце концов, в этом и суть ООП: моделировать реальный продукт простым / абстрактным способом, Product
класс например.
Проверка ввода
В большинстве случаев программа выполняет простые сравнения строк, что кажется достаточно стабильным. В какой-то момент пользователь должен ввести число (int / float), хотя это вызовет InputMismatchExceptions
если введено что-то недопустимое. Их здесь не ловят. Кроме того, числа следует проверять в соответствии со здравым смыслом и / или бизнес-логикой, ввод отрицательного приза в лучшем случае бессмысленно, а в худшем — дорого.
Программа запрашивает в предварительном меню цифру «1» для запуска меню или что-то еще для выхода, а затем предлагает отдельную опцию выхода в главном меню. Это может сбивать с толку или раздражать. Если предварительное меню удалено, цикл do-while в main
может печатать главное меню каждый раз, когда он зацикливается, а также обеспечивает возможность выхода из программы. Таким образом, методы в Products
не нужно будет печатать само предварительное меню (что является ненужным дублированием кода, которое тратит время на изменение диалога) и exit
В большинстве случаев флаг может быть удален. Он все равно понадобится в случае выхода, поскольку цикл do-while должен как-то заканчиваться.
Выбор числового меню может быть константой или enum
.
В больших меню может иметь смысл переместить каждый диалог в его собственный класс, а затем эти классы либо расширяют абстрактный базовый класс, либо реализуют интерфейс. Я сохраняю это кратко и расплывчато, поскольку в вашем случае достаточно иметь один дескриптор класса для всего интерфейса.
Длинная печать
System.out.println("(1) Capture a new product. n" + "(2) Search for a product. n" + "(3) Update a product. n" + "(4) Delete a product. n" + "(5) Print report. n" + "(6) Exit application. ");
Эту строку странно читать, и ее следует разбить на несколько println()
с.