Skip to content

Commit 65adc09

Browse files
committed
Work on iluwatar#381, added draft implementation of service stub pattern. Doing this to help @jdoetricksy get the hang of abstractions
1 parent d50139e commit 65adc09

File tree

13 files changed

+435
-0
lines changed

13 files changed

+435
-0
lines changed

service-stub/pom.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
4+
The MIT License
5+
Copyright (c) 2014 Ilkka Seppälä
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+
25+
-->
26+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
27+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
28+
<modelVersion>4.0.0</modelVersion>
29+
<parent>
30+
<groupId>com.iluwatar</groupId>
31+
<artifactId>java-design-patterns</artifactId>
32+
<version>1.13.0-SNAPSHOT</version>
33+
</parent>
34+
<artifactId>service-stub</artifactId>
35+
<dependencies>
36+
<dependency>
37+
<groupId>junit</groupId>
38+
<artifactId>junit</artifactId>
39+
<scope>test</scope>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.mockito</groupId>
43+
<artifactId>mockito-core</artifactId>
44+
<scope>test</scope>
45+
</dependency>
46+
<dependency>
47+
<groupId>com.yahoofinance-api</groupId>
48+
<artifactId>YahooFinanceAPI</artifactId>
49+
<version>3.1.0</version>
50+
</dependency>
51+
</dependencies>
52+
</project>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
6+
public class App {
7+
8+
public static void main(String[] args) throws Exception {
9+
ExecutorService executor = Executors.newSingleThreadExecutor();
10+
11+
try {
12+
YahooStockService service = new YahooStockService();
13+
14+
Portfolio portfolio = new Portfolio("iluwatar");
15+
BuyAtCurrentPriceCommand googleCurrentPriceBuy = new BuyAtCurrentPriceCommand(service, portfolio,
16+
new Stock("GOOG", "Google"), 100);
17+
googleCurrentPriceBuy.execute();
18+
19+
BuyAtCurrentPriceCommand yahooCurrentPriceBuy = new BuyAtCurrentPriceCommand(service, portfolio,
20+
new Stock("YHOO", "Yahoo"), 100);
21+
yahooCurrentPriceBuy.execute();
22+
23+
BuyAtLimitPriceCommand yahooLimitPriceBuy = new BuyAtLimitPriceCommand(service, portfolio,
24+
new Stock("YHOO", "Yahoo"), 100,service.getQuote(new Stock("YHOO", "Yahoo")).getCurrentPrice(),
25+
executor);
26+
27+
yahooLimitPriceBuy.execute().get();
28+
29+
System.out.println(portfolio);
30+
} finally {
31+
executor.shutdownNow();
32+
}
33+
}
34+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
import java.util.concurrent.Future;
5+
6+
public class BuyAtCurrentPriceCommand {
7+
8+
private StockService service;
9+
private Portfolio portfolio;
10+
private Stock stock;
11+
private int quantity;
12+
13+
public BuyAtCurrentPriceCommand(StockService service, Portfolio portfolio, Stock stock, int quantity) {
14+
this.service = service;
15+
this.portfolio = portfolio;
16+
this.stock = stock;
17+
this.quantity = quantity;
18+
}
19+
20+
public Future<Void> execute() {
21+
try {
22+
StockQuote stockQuote = service.getQuote(stock);
23+
portfolio.add(stock, quantity, stockQuote.getCurrentPrice());
24+
return CompletableFuture.completedFuture(null);
25+
} catch (Exception e) {
26+
CompletableFuture<Void> future = new CompletableFuture<>();
27+
future.completeExceptionally(e);
28+
return future;
29+
}
30+
}
31+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.math.BigDecimal;
4+
import java.util.concurrent.CompletableFuture;
5+
import java.util.concurrent.Executor;
6+
import java.util.concurrent.Future;
7+
import java.util.concurrent.TimeUnit;
8+
9+
public class BuyAtLimitPriceCommand {
10+
private StockService service;
11+
private Portfolio portfolio;
12+
private Stock stock;
13+
private int quantity;
14+
private BigDecimal priceLimit;
15+
private Executor executor;
16+
17+
public BuyAtLimitPriceCommand(StockService service, Portfolio portfolio, Stock stock,
18+
int quantity, BigDecimal priceLimit,
19+
Executor executor) {
20+
this.service = service;
21+
this.portfolio = portfolio;
22+
this.stock = stock;
23+
this.quantity = quantity;
24+
this.priceLimit = priceLimit;
25+
this.executor = executor;
26+
}
27+
28+
public Future<Void> execute() {
29+
CompletableFuture<Void> future = new CompletableFuture<>();
30+
executor.execute(() -> {
31+
try {
32+
while (true) {
33+
StockQuote stockQuote = service.getQuote(stock);
34+
35+
if (stockQuote.getCurrentPrice().compareTo(priceLimit) <= 0) {
36+
portfolio.add(stock, quantity, stockQuote.getCurrentPrice());
37+
future.complete(null);
38+
break;
39+
} else {
40+
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
41+
}
42+
}
43+
44+
} catch (Exception e) {
45+
future.completeExceptionally(e);
46+
}
47+
48+
});
49+
return future;
50+
}
51+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.math.BigDecimal;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
public class Portfolio {
8+
9+
private final String username;
10+
private final Map<Stock, StockInformation> stockToStockInformation = new HashMap<>();
11+
private BigDecimal totalAssets;
12+
13+
public Portfolio(String username) {
14+
this.username = username;
15+
this.totalAssets = new BigDecimal(0);
16+
}
17+
18+
public void add(Stock stock, int quantity, BigDecimal price) {
19+
StockInformation stockInformation = stockToStockInformation.get(stock);
20+
if (stockInformation == null) {
21+
stockInformation = new StockInformation(stock, price, quantity);
22+
stockToStockInformation.put(stock, stockInformation);
23+
} else {
24+
stockInformation.add(quantity, price);
25+
}
26+
totalAssets = totalAssets.add(price.multiply(new BigDecimal(quantity)));
27+
}
28+
29+
@Override
30+
public String toString() {
31+
32+
StringBuilder stringBuilder = new StringBuilder();
33+
stringBuilder.append(String.format("User: %s | Total assets worth: %f%n", username, totalAssets.floatValue()));
34+
for (StockInformation stockInformation : stockToStockInformation.values()) {
35+
stringBuilder.append(stockInformation.toString()).append("\n");
36+
}
37+
38+
return stringBuilder.toString();
39+
}
40+
41+
public StockInformation get(Stock stock) {
42+
return stockToStockInformation.get(stock);
43+
}
44+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
public class SellCommand {
4+
5+
6+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
public class Stock {
4+
5+
private final String symbol;
6+
private final String name;
7+
8+
public Stock(String symbol, String name) {
9+
this.symbol = symbol;
10+
this.name = name;
11+
}
12+
13+
public String getSymbol() {
14+
return symbol;
15+
}
16+
17+
public String getName() {
18+
return name;
19+
}
20+
21+
@Override
22+
public int hashCode() {
23+
final int prime = 31;
24+
int result = 1;
25+
result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
26+
return result;
27+
}
28+
29+
@Override
30+
public boolean equals(Object obj) {
31+
if (this == obj)
32+
return true;
33+
if (obj == null)
34+
return false;
35+
if (getClass() != obj.getClass())
36+
return false;
37+
Stock other = (Stock) obj;
38+
if (symbol == null) {
39+
if (other.symbol != null)
40+
return false;
41+
} else if (!symbol.equals(other.symbol))
42+
return false;
43+
return true;
44+
}
45+
46+
47+
48+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.math.BigDecimal;
4+
5+
public class StockInformation {
6+
7+
private final Stock stock;
8+
private BigDecimal totalStockPrice;
9+
private int quantity;
10+
11+
12+
public StockInformation(Stock stock, BigDecimal buyPrice, int quantity) {
13+
this.stock = stock;
14+
this.totalStockPrice = buyPrice.multiply(new BigDecimal(quantity));
15+
this.quantity = quantity;
16+
}
17+
18+
public Stock getStock() {
19+
return stock;
20+
}
21+
22+
public BigDecimal getAverageStockPrice() {
23+
return totalStockPrice.divide(new BigDecimal(quantity));
24+
}
25+
26+
public int getQuantity() {
27+
return quantity;
28+
}
29+
30+
public void add(int quantity, BigDecimal price) {
31+
this.quantity += quantity;
32+
this.totalStockPrice = totalStockPrice.add(price.multiply(new BigDecimal(quantity)));
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return String.format("Stock: %s | Quantity: %d | Avg.Price: %f", stock.getName(), quantity, getAverageStockPrice().floatValue());
38+
}
39+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.math.BigDecimal;
4+
5+
public class StockQuote {
6+
7+
private final BigDecimal currentPrice;
8+
9+
public StockQuote(BigDecimal currentPrice) {
10+
this.currentPrice = currentPrice;
11+
}
12+
13+
14+
public BigDecimal getCurrentPrice() {
15+
return currentPrice;
16+
}
17+
18+
@Override
19+
public String toString() {
20+
return String.format("Current trading price: %f", currentPrice.floatValue());
21+
}
22+
23+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
public interface StockService {
4+
5+
StockQuote getQuote(Stock stock) throws Exception;
6+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import java.math.BigDecimal;
4+
5+
public class StockServiceStub implements StockService {
6+
private StockQuote quote;
7+
8+
public StockServiceStub(BigDecimal quotePrice) {
9+
this.quote = new StockQuote(quotePrice);
10+
}
11+
12+
@Override
13+
public StockQuote getQuote(Stock stock) throws Exception {
14+
return quote;
15+
}
16+
17+
public void setQuotePrice(BigDecimal quotePrice) {
18+
this.quote = new StockQuote(quotePrice);
19+
}
20+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.iluwatar.servicestub.service;
2+
3+
import yahoofinance.Stock;
4+
import yahoofinance.YahooFinance;
5+
6+
public class YahooStockService implements StockService {
7+
8+
@Override
9+
public StockQuote getQuote(com.iluwatar.servicestub.service.Stock stock) throws Exception {
10+
Stock yahooStock = YahooFinance.get(stock.getSymbol());
11+
return new StockQuote(yahooStock.getQuote().getPrice());
12+
}
13+
14+
}

0 commit comments

Comments
 (0)