Тема: Оцінка коду
Добрий день
Отримав невеликве завдання по Джаві, раніше програмував тільки на С++.
Потрібен погляд зі сторони. Мені здається що виглядає програма не дуже ну зі сторони ОПП.
Можете прокоментувати.
Завдання: Implement a simple point of sale.
Assume you have:
– one input device: bar codes scanner
– two output devices: LCD display and printer
Implement:
– single product sale: products bar code is scanned and:
– if the product is found in products database than it's name and price is printed on LCD
– if the product is not found than error message 'Product not found' is printed on LCD
– if the code scanned is empty than error message 'Invalid bar-code' is printed on LCD
– when 'exit' is input than receipt is printed on printer containing a list of all previously scanned items names and prices as well as total sum to be paid for all items; the total sum is also printed on LCD display
Rules:
– use only SDK classes and your favorite test libraries
– mock/stub the database and IO devices
– concentrate on proper design and clean code, rather than supplying fully functioning application
Реалізація:
Клас SalePoint
public class SalePoint {
    private InputDevice codesScanner = new CodesScanner();
    private DBWorker dbWorker = null;
    private OutputDevice lcdDisplay = new LCDDisplay();
    private OutputDevice printer = new Printer();
    private List<Product> list = new ArrayList<Product>();
    public SalePoint(){
        try {
            dbWorker = new DBWorker();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void setDefaultBarCodes(){
        codesScanner.write("exit");
        codesScanner.write("");
        codesScanner.write("0000000001");
        codesScanner.write("0000000002");
    }
    public void run() {
        try {
            Product product = null;
            while(codesScanner.hasNext()) {
                String barCode = codesScanner.readLine();
                switch (barCode) {
                    case "":
                        lcdDisplay.printError("Product not found");
                        break;
                    case "exit":
                        printer.println("Printer: ");
                        printProducts();
                        return;
                    default:
                        product = dbWorker.findProduct(barCode);
                        if (product == null) {
                            lcdDisplay.printError("Invalid bar-code");
                        }
                        lcdDisplay.print(product);
                        list.add(product);
                }
            }
        } catch (EmptyStackException e) {
            e.printStackTrace();
        }
    }
    private void printProducts() {
        double summ = 0.0;
        for (Product product :
                list) {
            summ += product.getPrice();
        }
        ((Printer)printer).printProductsAndTotalPrice(list, summ);
    }
}Class InputDevice
public class InputDevice {
    private Stack<String> buffer = new Stack<>();
    public void write(String message){
        buffer.push(message);
    }
    public String readLine(){
        if(buffer.isEmpty())
            return null;
        return buffer.pop();
    }
    public void clear(){
        buffer.clear();
    }
    public boolean hasNext(){
        return !buffer.isEmpty();
    }
}Class CodesScaner
public class CodesScanner extends InputDevice{
    public CodesScanner() {
        super();
    }
// Не знаю який метод додати. 
}Class OutputDevice
public class OutputDevice {
    void println(String message){
        System.out.println(message);
    }
    void print(String message){
        System.out.print(message);
    }
    void printError(String message){
        System.out.println("Error: " + message);
    }
    void print(Product product){
        System.out.println(product);
    }
}Class Printer
public class Printer extends OutputDevice {
    public Printer() {
        super();
    }
    public void printProducts(List<Product> productList){
        System.out.println("List of products:");
        for (Product product:
             productList) {
            System.out.println(product.getName() + "\t\t\t" + product.getPrice());
        }
    }
    public void printProductsAndTotalPrice(List<Product> productList, double totalPrice){
        System.out.println("List of products:\nName\t\t\tPrice");
        for (Product product:
                productList) {
            System.out.println(product.getName() + "\t\t\t" + product.getPrice());
        }
        System.out.println("Total:\t\t\t" + totalPrice);
    }
}Class LCDDisplay
public class LCDDisplay extends OutputDevice {
    public LCDDisplay() {
    }
    public void print(Product product){
        System.out.println(product.getName() + "\t\t" + product.getPrice());
    }
}Class DBWorker
public class DBWorker {
    private static String URL = "jdbc:mysql://localhost:3306/mydbtest";
    private static String USERNAME = "root";
    private static String PASSWORD = "root";
    private static String SELECT = "SELECT product_name, price, bar_code FROM products WHERE bar_code = ?;";
    private Connection connection;
    public DBWorker() throws SQLException {
        Driver driver = new FabricMySQLDriver();
        DriverManager.registerDriver(driver);
        connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
    }
    public Product findProduct(String barCode) {
        Product product = null;
        PreparedStatement preparedStatement = null;
        try {
            preparedStatement = connection.prepareStatement(SELECT);
            preparedStatement.setString(1, barCode);
            ResultSet resultSet = preparedStatement.executeQuery();
            if(resultSet.next())
                product = new Product(resultSet.getString("product_name"), resultSet.getInt("price"), resultSet.getString("bar_code"));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return product;
    }
}main
public class Main {
    public static void main(String[] args) {
        SalePoint salePoint = new SalePoint();
        salePoint.setDefaultBarCodes();
        salePoint.run();
    }
}Як на ваш погляд моя реалізація?
І не підскажите як зробити тести? Juint i Mockito
Тільки один зробив але не розумію навіщо він - бесполезний.
public class DBTest {
    private static final Product PRODUCT = new Product("beer", 2.3, "0000000001");
    private static final String BAR_CODE = "0000000001";
    @Mock
    SalePoint salePoint;
    @Test
    public void testFindProduct(){
        DBWorker dbWorker = mock(DBWorker.class);
        when(dbWorker.findProduct(BAR_CODE)).thenReturn(new Product("beer", 2.3, "0000000001"));
        Product product = dbWorker.findProduct(BAR_CODE);
        Assert.assertEquals(product, PRODUCT);
    }
}