Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLID #1256

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

SOLID #1256

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions src/main/java/core/basesyntax/HelloWorld.java

This file was deleted.

54 changes: 54 additions & 0 deletions src/main/java/core/basesyntax/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package core.basesyntax;

import core.basesyntax.service.DataConverter;
import core.basesyntax.service.MyFileReader;
import core.basesyntax.service.MyFileWriter;
import core.basesyntax.service.ReportGenerator;
import core.basesyntax.service.impl.DataConverterImpl;
import core.basesyntax.service.impl.FileReaderImpl;
import core.basesyntax.service.impl.FileWriterImpl;
import core.basesyntax.service.impl.ReportGeneratorImpl;
import core.basesyntax.strategy.BalanceOperation;
import core.basesyntax.strategy.FruitTransaction;
import core.basesyntax.strategy.OperationHandler;
import core.basesyntax.strategy.OperationStrategy;
import core.basesyntax.strategy.OperationStrategyImpl;
import core.basesyntax.strategy.PurchaseOperation;
import core.basesyntax.strategy.ReturnOperation;
import core.basesyntax.strategy.ShopService;
import core.basesyntax.strategy.ShopServiceImpl;
import core.basesyntax.strategy.SupplyOperation;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class Main {
public static void main(String[] args) {
Map<FruitTransaction.Operation, OperationHandler> operationHandlers = new HashMap<>();

operationHandlers.put(FruitTransaction.Operation.BALANCE, new BalanceOperation());
operationHandlers.put(FruitTransaction.Operation.PURCHASE, new PurchaseOperation());
operationHandlers.put(FruitTransaction.Operation.RETURN, new ReturnOperation());
operationHandlers.put(FruitTransaction.Operation.SUPPLY, new SupplyOperation());
OperationStrategy operationStrategy = new OperationStrategyImpl(operationHandlers);

ShopService shopService = new ShopServiceImpl(operationStrategy);
DataConverter dataConverter = new DataConverterImpl();
MyFileReader fileReader = new FileReaderImpl();

ClassLoader classLoader = Main.class.getClassLoader();
File file = new File(Objects.requireNonNull(classLoader
.getResource("toRead.csv")).getFile());
List<String> inputReport = fileReader.read(file.getPath());

shopService.process(dataConverter.convertToTransaction(inputReport));

ReportGenerator reportGenerator = new ReportGeneratorImpl();
String finalReport = reportGenerator.getReport();

MyFileWriter fileWriter = new FileWriterImpl();
fileWriter.write(finalReport, "src/main/resources/finalReport.csv");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output file path should be relative to ensure the project can be run by anyone without modifications. Consider using a path like "src/main/resources/finalReport.csv".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output file path should be relative and placed in the src/main/resources folder as per the checklist. Consider changing the path to src/main/resources/finalReport.csv.

}
}
20 changes: 20 additions & 0 deletions src/main/java/core/basesyntax/db/Storage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package core.basesyntax.db;

import java.util.HashMap;
import java.util.Map;

public class Storage {
private static final Map<String, Integer> fruits = new HashMap<>();

public static void add(String fruit, int quantity) {
fruits.put(fruit, fruits.getOrDefault(fruit, 0) + quantity);
}

public static void subtract(String fruit, int quantity) {
fruits.put(fruit, fruits.getOrDefault(fruit, 0) - quantity);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The subtract method should check if the resulting quantity is negative before updating the storage. Consider throwing a RuntimeException if the subtraction would result in a negative quantity, to prevent invalid storage states.

Comment on lines +13 to +14

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The subtract method should check if the resulting quantity is negative before updating the map. If the quantity becomes negative, consider throwing a RuntimeException to prevent invalid states in the storage.

}

public static Map<String, Integer> getAll() {
return new HashMap<>(fruits);
}
}
8 changes: 8 additions & 0 deletions src/main/java/core/basesyntax/service/DataConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.service;

import core.basesyntax.strategy.FruitTransaction;
import java.util.List;

public interface DataConverter {
List<FruitTransaction> convertToTransaction(List<String> rawData);
}
7 changes: 7 additions & 0 deletions src/main/java/core/basesyntax/service/MyFileReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package core.basesyntax.service;

import java.util.List;

public interface MyFileReader {
List<String> read(String filePath);
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/service/MyFileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.service;

public interface MyFileWriter {
void write(String report, String fileName);
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/service/ReportGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.service;

public interface ReportGenerator {
String getReport();
}
21 changes: 21 additions & 0 deletions src/main/java/core/basesyntax/service/impl/DataConverterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package core.basesyntax.service.impl;

import core.basesyntax.service.DataConverter;
import core.basesyntax.strategy.FruitTransaction;
import java.util.ArrayList;
import java.util.List;

public class DataConverterImpl implements DataConverter {
public List<FruitTransaction> convertToTransaction(List<String> rawData) {
List<FruitTransaction> fruitTransactions = new ArrayList<>();
for (int i = 1; i < rawData.size(); i++) {
String[] parts = rawData.get(i).split(",");
FruitTransaction.Operation operation = FruitTransaction.Operation.fromCode(parts[0]);
String fruit = parts[1];
int quantity = Integer.parseInt(parts[2]);
Comment on lines +12 to +15

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation assumes that the raw data is always correctly formatted. Consider adding error handling to manage cases where the data might be malformed, such as catching ArrayIndexOutOfBoundsException or NumberFormatException.

fruitTransactions.add(new FruitTransaction(operation, fruit, quantity));
}
Comment on lines +11 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation assumes that the input data is always well-formed. Consider adding validation to handle potential parsing errors, such as checking if parts has the expected length and catching NumberFormatException when parsing the quantity.


return fruitTransactions;
}
}
25 changes: 25 additions & 0 deletions src/main/java/core/basesyntax/service/impl/FileReaderImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package core.basesyntax.service.impl;

import core.basesyntax.service.MyFileReader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class FileReaderImpl implements MyFileReader {
public List<String> read(String filePath) {
List<String> lines = new ArrayList<>();

try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
throw new RuntimeException("Failed to read file: " + filePath, e);
}

return lines;
}
}
16 changes: 16 additions & 0 deletions src/main/java/core/basesyntax/service/impl/FileWriterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package core.basesyntax.service.impl;

import core.basesyntax.service.MyFileWriter;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterImpl implements MyFileWriter {
@Override
public void write(String report, String filePath) {
try (FileWriter writer = new FileWriter(filePath)) {
writer.write(report);
} catch (IOException e) {
throw new RuntimeException("Failed to write to file: " + filePath, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package core.basesyntax.service.impl;

import core.basesyntax.db.Storage;
import core.basesyntax.service.ReportGenerator;

public class ReportGeneratorImpl implements ReportGenerator {
public static final String REPORT_TITLE = "fruit,quantity\n";

@Override
public String getReport() {
StringBuilder reportBuilder = new StringBuilder(REPORT_TITLE);
Storage.getAll().forEach((fruit, quantity) -> reportBuilder.append(fruit)
.append(",")
.append(quantity)
.append("\n"));

return reportBuilder.toString();
}
}
9 changes: 9 additions & 0 deletions src/main/java/core/basesyntax/strategy/BalanceOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;

public class BalanceOperation implements OperationHandler {
public void handle(FruitTransaction transaction) {
Storage.add(transaction.getFruit(), transaction.getQuantity());
}
}
49 changes: 49 additions & 0 deletions src/main/java/core/basesyntax/strategy/FruitTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package core.basesyntax.strategy;

public class FruitTransaction {
private final Operation operation;
private final String fruit;
private final int quantity;

public FruitTransaction(Operation operation, String fruit, int quantity) {
this.operation = operation;
this.fruit = fruit;
this.quantity = quantity;
}

public Operation getOperation() {
return operation;
}

public String getFruit() {
return fruit;
}

public int getQuantity() {
return quantity;
}

public enum Operation {
BALANCE("b"),
SUPPLY("s"),
PURCHASE("p"),
RETURN("r");

private final String code;

Operation(String code) {
this.code = code;
}

public static Operation fromCode(String code) {
for (Operation o : values()) {
if (o.code.equals(code)) {
return o;
}
}

throw new IllegalArgumentException("Unknown operation code: " + code);
}

}
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/strategy/OperationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.strategy;

public interface OperationHandler {
void handle(FruitTransaction transaction);
}
5 changes: 5 additions & 0 deletions src/main/java/core/basesyntax/strategy/OperationStrategy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core.basesyntax.strategy;

public interface OperationStrategy {
OperationHandler getOperationHandler(FruitTransaction.Operation operation);
}
16 changes: 16 additions & 0 deletions src/main/java/core/basesyntax/strategy/OperationStrategyImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package core.basesyntax.strategy;

import java.util.Map;

public class OperationStrategyImpl implements OperationStrategy {
private final Map<FruitTransaction.Operation, OperationHandler> operationHandlers;

public OperationStrategyImpl(Map<FruitTransaction.Operation,
OperationHandler> operationHandlers) {
this.operationHandlers = operationHandlers;
}

public OperationHandler getOperationHandler(FruitTransaction.Operation operation) {
return operationHandlers.get(operation);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where the operationHandlers map does not contain a handler for the given operation. You might want to throw an exception or return a default handler in such cases.

Comment on lines +13 to +14

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where an operation does not have a corresponding handler in the map. You could throw an exception or return a default handler to prevent potential NullPointerException.

}
}
18 changes: 18 additions & 0 deletions src/main/java/core/basesyntax/strategy/PurchaseOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;

public class PurchaseOperation implements OperationHandler {
public void handle(FruitTransaction transaction) {
String fruit = transaction.getFruit();
int quantity = transaction.getQuantity();
int currentBalance = Storage.getAll().get(transaction.getFruit());

if (currentBalance - quantity < 0) {
throw new RuntimeException("Insufficient quantity of fruit: " + fruit
+ ". Current balance: " + currentBalance);
}

Storage.subtract(fruit, quantity);
}
}
9 changes: 9 additions & 0 deletions src/main/java/core/basesyntax/strategy/ReturnOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;

public class ReturnOperation implements OperationHandler {
public void handle(FruitTransaction transaction) {
Storage.add(transaction.getFruit(), transaction.getQuantity());
}
}
8 changes: 8 additions & 0 deletions src/main/java/core/basesyntax/strategy/ShopService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package core.basesyntax.strategy;

import java.util.List;

public interface ShopService {
void process(List<FruitTransaction> fruitTransactions);

}
20 changes: 20 additions & 0 deletions src/main/java/core/basesyntax/strategy/ShopServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package core.basesyntax.strategy;

import java.util.List;

public class ShopServiceImpl implements ShopService {
private final OperationStrategy operationStrategy;

public ShopServiceImpl(OperationStrategy operationStrategy) {
this.operationStrategy = operationStrategy;
}

@Override
public void process(List<FruitTransaction> fruitTransactions) {
for (FruitTransaction transaction : fruitTransactions) {
OperationHandler handler = operationStrategy
.getOperationHandler(transaction.getOperation());
handler.handle(transaction);
Comment on lines +15 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where getOperationHandler might return null if a handler is not found for a given operation. This will prevent potential NullPointerException and improve robustness.

Comment on lines +15 to +17

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a check to handle cases where getOperationHandler returns null. This could happen if a transaction's operation does not have a corresponding handler, leading to a NullPointerException when calling handle.

}
}
}
9 changes: 9 additions & 0 deletions src/main/java/core/basesyntax/strategy/SupplyOperation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package core.basesyntax.strategy;

import core.basesyntax.db.Storage;

public class SupplyOperation implements OperationHandler {
public void handle(FruitTransaction transaction) {
Storage.add(transaction.getFruit(), transaction.getQuantity());
}
}
3 changes: 3 additions & 0 deletions src/main/resources/finalReport.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fruit,quantity
banana,152
apple,90
9 changes: 9 additions & 0 deletions src/main/resources/toRead.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type,fruit,quantity
b,banana,20
b,apple,100
s,banana,100
p,banana,13
r,apple,10
p,apple,20
p,banana,5
s,banana,50
Loading