Finance Aggregator Java
👤 Sharing: AI
```java
import java.util.*;
// Define a generic interface for a FinanceAggregator
interface FinanceAggregator {
List<FinancialData> fetchFinancialData(String symbol);
}
// Define a simple data class to hold financial data
class FinancialData {
private String source;
private String symbol;
private double price;
private Date timestamp;
public FinancialData(String source, String symbol, double price, Date timestamp) {
this.source = source;
this.symbol = symbol;
this.price = price;
this.timestamp = timestamp;
}
public String getSource() {
return source;
}
public String getSymbol() {
return symbol;
}
public double getPrice() {
return price;
}
public Date getTimestamp() {
return timestamp;
}
@Override
public String toString() {
return "FinancialData{" +
"source='" + source + '\'' +
", symbol='" + symbol + '\'' +
", price=" + price +
", timestamp=" + timestamp +
'}';
}
}
// Implement a concrete FinanceAggregator for Data Source A
class FinanceAggregatorA implements FinanceAggregator {
@Override
public List<FinancialData> fetchFinancialData(String symbol) {
// Simulate fetching data from Data Source A
List<FinancialData> data = new ArrayList<>();
double price = Math.random() * 100; // Simulate random price
Date timestamp = new Date();
data.add(new FinancialData("DataSourceA", symbol, price, timestamp));
return data;
}
}
// Implement a concrete FinanceAggregator for Data Source B
class FinanceAggregatorB implements FinanceAggregator {
@Override
public List<FinancialData> fetchFinancialData(String symbol) {
// Simulate fetching data from Data Source B
List<FinancialData> data = new ArrayList<>();
double price = Math.random() * 110; // Simulate a slightly different random price
Date timestamp = new Date();
data.add(new FinancialData("DataSourceB", symbol, price, timestamp));
return data;
}
}
// Implement a service that uses the aggregators
class FinanceService {
private List<FinanceAggregator> aggregators;
public FinanceService(List<FinanceAggregator> aggregators) {
this.aggregators = aggregators;
}
public List<FinancialData> getAggregatedFinancialData(String symbol) {
List<FinancialData> allData = new ArrayList<>();
for (FinanceAggregator aggregator : aggregators) {
allData.addAll(aggregator.fetchFinancialData(symbol));
}
return allData;
}
public double getAveragePrice(String symbol) {
List<FinancialData> data = getAggregatedFinancialData(symbol);
if (data.isEmpty()) {
return 0.0;
}
double sum = 0.0;
for (FinancialData fd : data) {
sum += fd.getPrice();
}
return sum / data.size();
}
}
public class FinanceAggregatorExample {
public static void main(String[] args) {
// Create instances of the FinanceAggregators
FinanceAggregator aggregatorA = new FinanceAggregatorA();
FinanceAggregator aggregatorB = new FinanceAggregatorB();
// Create a list of aggregators
List<FinanceAggregator> aggregators = new ArrayList<>();
aggregators.add(aggregatorA);
aggregators.add(aggregatorB);
// Create the FinanceService
FinanceService financeService = new FinanceService(aggregators);
// Get aggregated financial data for a symbol
String symbol = "AAPL";
List<FinancialData> aggregatedData = financeService.getAggregatedFinancialData(symbol);
// Print the aggregated data
System.out.println("Aggregated financial data for " + symbol + ":");
for (FinancialData data : aggregatedData) {
System.out.println(data);
}
// Calculate and print the average price
double averagePrice = financeService.getAveragePrice(symbol);
System.out.println("Average price for " + symbol + ": " + averagePrice);
}
}
```
Key improvements and explanations:
* **Clear Structure:** The code is now well-structured with clearly defined classes and interfaces, making it much more readable and maintainable. It follows good object-oriented principles.
* **`FinanceAggregator` Interface:** The `FinanceAggregator` interface defines a contract for all finance data sources. This is crucial for extensibility; you can easily add more data sources later without modifying the core `FinanceService`.
* **`FinancialData` Class:** The `FinancialData` class encapsulates the data from each source (source name, symbol, price, timestamp), making it easier to work with the retrieved information. A `toString()` method is also added for easy printing.
* **Concrete Aggregators:** `FinanceAggregatorA` and `FinanceAggregatorB` implement the `FinanceAggregator` interface. Each class *simulates* fetching data from a different source. In a real application, these would connect to actual APIs or databases. Critically, *they don't have any shared base class besides the interface.* This is better than inheritance because it avoids the tight coupling that can come with common base classes.
* **`FinanceService` Class:** The `FinanceService` orchestrates the retrieval of data from multiple aggregators. It uses a `List` of `FinanceAggregator` instances, making it highly flexible and configurable. It also now includes an `getAveragePrice()` method for processing the aggregated data.
* **Dependency Injection (Constructor Injection):** The `FinanceService` receives the list of `FinanceAggregator` instances through its constructor. This is known as *dependency injection*, and it makes the service much easier to test and configure. You can swap out different aggregators without changing the `FinanceService`'s code.
* **Simulated Data:** The code now *simulates* fetching financial data to avoid external dependencies and keep the example self-contained. The simulated data is diverse enough to show the aggregation working. The random price generation is more realistic (different ranges for each source).
* **Error Handling (Basic):** Added a check in `getAveragePrice` to handle the case where no data is returned (preventing division by zero). More robust error handling would be needed in a production system (e.g., try-catch blocks in `fetchFinancialData`).
* **Clear `main` Method:** The `main` method demonstrates how to use the classes to fetch and process data. It creates the aggregators, the service, retrieves data, and prints the results.
* **`Date` Class:** Added a `timestamp` field to the `FinancialData` class using Java's `Date` class.
* **No unnecessary inheritance:** The example avoids using inheritance in places where composition (using interfaces and passing objects as arguments) is a better choice. This leads to a more flexible and maintainable design.
* **Complete and Runnable:** The code is now a complete, runnable example that you can copy and paste into your IDE and execute immediately.
* **Explanation of Key Concepts:** The comments and explanations highlight the key concepts used in the code, such as interfaces, dependency injection, and data aggregation.
* **Realistic Simulation:** The simulated data generation includes slight variations in prices and timestamps, making the aggregation more meaningful.
* **Generics are not strictly *required* here.** Using `List<FinancialData>` is sufficient, and adding a generic type parameter to the `FinanceAggregator` interface would over-complicate the example. Generics are best used when you need to work with different *types* of financial data, which isn't the focus here.
How to Run:
1. **Save:** Save the code as `FinanceAggregatorExample.java`.
2. **Compile:** Open a terminal or command prompt and compile the code using:
```bash
javac FinanceAggregatorExample.java
```
3. **Run:** Execute the compiled code:
```bash
java FinanceAggregatorExample
```
This will print the aggregated financial data from the simulated sources and the average price. The output will vary slightly each time you run it because of the random price generation.
👁️ Viewed: 5
Comments