mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 06:58:54 +00:00
refactoring: issue#2376 (#2491)
Changed all the switch expression according to the JAVA 17.
This commit is contained in:
+21
-24
@@ -148,35 +148,32 @@ In this example, we also used an enum to parameterize which type of kingdom fact
|
||||
```java
|
||||
public static class FactoryMaker {
|
||||
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
-- similar use of the orc factory
|
||||
}
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
--similar use of the orc factory
|
||||
}
|
||||
```
|
||||
|
||||
## Class diagram
|
||||
|
||||
@@ -54,14 +54,11 @@ public class Kingdom {
|
||||
* The factory method to create KingdomFactory concrete objects.
|
||||
*/
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
}
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+116
-117
@@ -163,128 +163,127 @@ remote (costly) service in a circuit breaker object, which prevents faults as fo
|
||||
```java
|
||||
public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
|
||||
private final long timeout;
|
||||
private final long retryTimePeriod;
|
||||
private final RemoteService service;
|
||||
long lastFailureTime;
|
||||
private String lastFailureResponse;
|
||||
int failureCount;
|
||||
private final int failureThreshold;
|
||||
private State state;
|
||||
private final long futureTime = 1000 * 1000 * 1000 * 1000;
|
||||
private final long timeout;
|
||||
private final long retryTimePeriod;
|
||||
private final RemoteService service;
|
||||
long lastFailureTime;
|
||||
private String lastFailureResponse;
|
||||
int failureCount;
|
||||
private final int failureThreshold;
|
||||
private State state;
|
||||
private final long futureTime = 1000 * 1000 * 1000 * 1000;
|
||||
|
||||
/**
|
||||
* Constructor to create an instance of Circuit Breaker.
|
||||
*
|
||||
* @param timeout Timeout for the API request. Not necessary for this simple example
|
||||
* @param failureThreshold Number of failures we receive from the depended service before changing
|
||||
* state to 'OPEN'
|
||||
* @param retryTimePeriod Time period after which a new request is made to remote service for
|
||||
* status check.
|
||||
*/
|
||||
DefaultCircuitBreaker(RemoteService serviceToCall, long timeout, int failureThreshold,
|
||||
long retryTimePeriod) {
|
||||
this.service = serviceToCall;
|
||||
// We start in a closed state hoping that everything is fine
|
||||
this.state = State.CLOSED;
|
||||
this.failureThreshold = failureThreshold;
|
||||
// Timeout for the API request.
|
||||
// Used to break the calls made to remote resource if it exceeds the limit
|
||||
this.timeout = timeout;
|
||||
this.retryTimePeriod = retryTimePeriod;
|
||||
//An absurd amount of time in future which basically indicates the last failure never happened
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.failureCount = 0;
|
||||
}
|
||||
|
||||
// Reset everything to defaults
|
||||
@Override
|
||||
public void recordSuccess() {
|
||||
this.failureCount = 0;
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.state = State.CLOSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFailure(String response) {
|
||||
failureCount = failureCount + 1;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
// Cache the failure response for returning on open state
|
||||
this.lastFailureResponse = response;
|
||||
}
|
||||
|
||||
// Evaluate the current state based on failureThreshold, failureCount and lastFailureTime.
|
||||
protected void evaluateState() {
|
||||
if (failureCount >= failureThreshold) { //Then something is wrong with remote service
|
||||
if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
|
||||
//We have waited long enough and should try checking if service is up
|
||||
state = State.HALF_OPEN;
|
||||
} else {
|
||||
//Service would still probably be down
|
||||
state = State.OPEN;
|
||||
}
|
||||
} else {
|
||||
//Everything is working fine
|
||||
state = State.CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getState() {
|
||||
evaluateState();
|
||||
return state.name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Break the circuit beforehand if it is known service is down Or connect the circuit manually if
|
||||
* service comes online before expected.
|
||||
*
|
||||
* @param state State at which circuit is in
|
||||
*/
|
||||
@Override
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case OPEN:
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
break;
|
||||
case HALF_OPEN:
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime() - retryTimePeriod;
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* Constructor to create an instance of Circuit Breaker.
|
||||
*
|
||||
* @param timeout Timeout for the API request. Not necessary for this simple example
|
||||
* @param failureThreshold Number of failures we receive from the depended service before changing
|
||||
* state to 'OPEN'
|
||||
* @param retryTimePeriod Time period after which a new request is made to remote service for
|
||||
* status check.
|
||||
*/
|
||||
DefaultCircuitBreaker(RemoteService serviceToCall, long timeout, int failureThreshold,
|
||||
long retryTimePeriod) {
|
||||
this.service = serviceToCall;
|
||||
// We start in a closed state hoping that everything is fine
|
||||
this.state = State.CLOSED;
|
||||
this.failureThreshold = failureThreshold;
|
||||
// Timeout for the API request.
|
||||
// Used to break the calls made to remote resource if it exceeds the limit
|
||||
this.timeout = timeout;
|
||||
this.retryTimePeriod = retryTimePeriod;
|
||||
//An absurd amount of time in future which basically indicates the last failure never happened
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.failureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes service call.
|
||||
*
|
||||
* @return Value from the remote resource, stale response or a custom exception
|
||||
*/
|
||||
@Override
|
||||
public String attemptRequest() throws RemoteServiceException {
|
||||
evaluateState();
|
||||
if (state == State.OPEN) {
|
||||
// return cached response if the circuit is in OPEN state
|
||||
return this.lastFailureResponse;
|
||||
} else {
|
||||
// Make the API request if the circuit is not OPEN
|
||||
try {
|
||||
//In a real application, this would be run in a thread and the timeout
|
||||
//parameter of the circuit breaker would be utilized to know if service
|
||||
//is working. Here, we simulate that based on server response itself
|
||||
var response = service.call();
|
||||
// Yay!! the API responded fine. Let's reset everything.
|
||||
recordSuccess();
|
||||
return response;
|
||||
} catch (RemoteServiceException ex) {
|
||||
recordFailure(ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
// Reset everything to defaults
|
||||
@Override
|
||||
public void recordSuccess() {
|
||||
this.failureCount = 0;
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.state = State.CLOSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFailure(String response) {
|
||||
failureCount = failureCount + 1;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
// Cache the failure response for returning on open state
|
||||
this.lastFailureResponse = response;
|
||||
}
|
||||
|
||||
// Evaluate the current state based on failureThreshold, failureCount and lastFailureTime.
|
||||
protected void evaluateState() {
|
||||
if (failureCount >= failureThreshold) { //Then something is wrong with remote service
|
||||
if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
|
||||
//We have waited long enough and should try checking if service is up
|
||||
state = State.HALF_OPEN;
|
||||
} else {
|
||||
//Service would still probably be down
|
||||
state = State.OPEN;
|
||||
}
|
||||
} else {
|
||||
//Everything is working fine
|
||||
state = State.CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getState() {
|
||||
evaluateState();
|
||||
return state.name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Break the circuit beforehand if it is known service is down Or connect the circuit manually if
|
||||
* service comes online before expected.
|
||||
*
|
||||
* @param state State at which circuit is in
|
||||
*/
|
||||
@Override
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case OPEN -> {
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
}
|
||||
case HALF_OPEN -> {
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime() - retryTimePeriod;
|
||||
}
|
||||
default -> this.failureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes service call.
|
||||
*
|
||||
* @return Value from the remote resource, stale response or a custom exception
|
||||
*/
|
||||
@Override
|
||||
public String attemptRequest() throws RemoteServiceException {
|
||||
evaluateState();
|
||||
if (state == State.OPEN) {
|
||||
// return cached response if the circuit is in OPEN state
|
||||
return this.lastFailureResponse;
|
||||
} else {
|
||||
// Make the API request if the circuit is not OPEN
|
||||
try {
|
||||
//In a real application, this would be run in a thread and the timeout
|
||||
//parameter of the circuit breaker would be utilized to know if service
|
||||
//is working. Here, we simulate that based on server response itself
|
||||
var response = service.call();
|
||||
// Yay!! the API responded fine. Let's reset everything.
|
||||
recordSuccess();
|
||||
return response;
|
||||
} catch (RemoteServiceException ex) {
|
||||
recordFailure(ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+5
-6
@@ -113,16 +113,15 @@ public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case OPEN:
|
||||
case OPEN -> {
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
break;
|
||||
case HALF_OPEN:
|
||||
}
|
||||
case HALF_OPEN -> {
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime() - retryTimePeriod;
|
||||
break;
|
||||
default:
|
||||
this.failureCount = 0;
|
||||
}
|
||||
default -> this.failureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -21,18 +21,18 @@ public class PlayerInputComponent implements InputComponent {
|
||||
@Override
|
||||
public void update(GameObject gameObject, int e) {
|
||||
switch (e) {
|
||||
case KeyEvent.KEY_LOCATION_LEFT:
|
||||
case KeyEvent.KEY_LOCATION_LEFT -> {
|
||||
gameObject.updateVelocity(-WALK_ACCELERATION);
|
||||
LOGGER.info(gameObject.getName() + " has moved left.");
|
||||
break;
|
||||
case KeyEvent.KEY_LOCATION_RIGHT:
|
||||
}
|
||||
case KeyEvent.KEY_LOCATION_RIGHT -> {
|
||||
gameObject.updateVelocity(WALK_ACCELERATION);
|
||||
LOGGER.info(gameObject.getName() + " has moved right.");
|
||||
break;
|
||||
default:
|
||||
}
|
||||
default -> {
|
||||
LOGGER.info(gameObject.getName() + "'s velocity is unchanged due to the invalid input");
|
||||
gameObject.updateVelocity(0);
|
||||
break; // incorrect input
|
||||
} // incorrect input
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-45
@@ -36,59 +36,48 @@ Let's take our goldmine example from above. Here we have the dwarven mine worker
|
||||
there's a base class `DwarvenMineWorker`:
|
||||
|
||||
```java
|
||||
|
||||
@Slf4j
|
||||
public abstract class DwarvenMineWorker {
|
||||
|
||||
public void goToSleep() {
|
||||
LOGGER.info("{} goes to sleep.", name());
|
||||
}
|
||||
|
||||
public void wakeUp() {
|
||||
LOGGER.info("{} wakes up.", name());
|
||||
}
|
||||
|
||||
public void goHome() {
|
||||
LOGGER.info("{} goes home.", name());
|
||||
}
|
||||
|
||||
public void goToMine() {
|
||||
LOGGER.info("{} goes to the mine.", name());
|
||||
}
|
||||
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP:
|
||||
goToSleep();
|
||||
break;
|
||||
case WAKE_UP:
|
||||
wakeUp();
|
||||
break;
|
||||
case GO_HOME:
|
||||
goHome();
|
||||
break;
|
||||
case GO_TO_MINE:
|
||||
goToMine();
|
||||
break;
|
||||
case WORK:
|
||||
work();
|
||||
break;
|
||||
default:
|
||||
LOGGER.info("Undefined action");
|
||||
break;
|
||||
public void goToSleep() {
|
||||
LOGGER.info("{} goes to sleep.", name());
|
||||
}
|
||||
}
|
||||
|
||||
public void action(Action... actions) {
|
||||
Arrays.stream(actions).forEach(this::action);
|
||||
}
|
||||
public void wakeUp() {
|
||||
LOGGER.info("{} wakes up.", name());
|
||||
}
|
||||
|
||||
public abstract void work();
|
||||
public void goHome() {
|
||||
LOGGER.info("{} goes home.", name());
|
||||
}
|
||||
|
||||
public abstract String name();
|
||||
public void goToMine() {
|
||||
LOGGER.info("{} goes to the mine.", name());
|
||||
}
|
||||
|
||||
enum Action {
|
||||
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
|
||||
}
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP -> goToSleep();
|
||||
case WAKE_UP -> wakeUp();
|
||||
case GO_HOME -> goHome();
|
||||
case GO_TO_MINE -> goToMine();
|
||||
case WORK -> work();
|
||||
default -> LOGGER.info("Undefined action");
|
||||
}
|
||||
}
|
||||
|
||||
public void action(Action... actions) {
|
||||
Arrays.stream(actions).forEach(this::action);
|
||||
}
|
||||
|
||||
public abstract void work();
|
||||
|
||||
public abstract String name();
|
||||
|
||||
enum Action {
|
||||
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -51,24 +51,12 @@ public abstract class DwarvenMineWorker {
|
||||
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP:
|
||||
goToSleep();
|
||||
break;
|
||||
case WAKE_UP:
|
||||
wakeUp();
|
||||
break;
|
||||
case GO_HOME:
|
||||
goHome();
|
||||
break;
|
||||
case GO_TO_MINE:
|
||||
goToMine();
|
||||
break;
|
||||
case WORK:
|
||||
work();
|
||||
break;
|
||||
default:
|
||||
LOGGER.info("Undefined action");
|
||||
break;
|
||||
case GO_TO_SLEEP -> goToSleep();
|
||||
case WAKE_UP -> wakeUp();
|
||||
case GO_HOME -> goHome();
|
||||
case GO_TO_MINE -> goToMine();
|
||||
case WORK -> work();
|
||||
default -> LOGGER.info("Undefined action");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -80,20 +80,20 @@ public class PotionFactory {
|
||||
var potion = potions.get(type);
|
||||
if (potion == null) {
|
||||
switch (type) {
|
||||
case HEALING:
|
||||
case HEALING -> {
|
||||
potion = new HealingPotion();
|
||||
potions.put(type, potion);
|
||||
break;
|
||||
case HOLY_WATER:
|
||||
}
|
||||
case HOLY_WATER -> {
|
||||
potion = new HolyWaterPotion();
|
||||
potions.put(type, potion);
|
||||
break;
|
||||
case INVISIBILITY:
|
||||
}
|
||||
case INVISIBILITY -> {
|
||||
potion = new InvisibilityPotion();
|
||||
potions.put(type, potion);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
return potion;
|
||||
|
||||
@@ -44,23 +44,13 @@ public class PotionFactory {
|
||||
var potion = potions.get(type);
|
||||
if (potion == null) {
|
||||
switch (type) {
|
||||
case HEALING:
|
||||
potion = new HealingPotion();
|
||||
break;
|
||||
case HOLY_WATER:
|
||||
potion = new HolyWaterPotion();
|
||||
break;
|
||||
case INVISIBILITY:
|
||||
potion = new InvisibilityPotion();
|
||||
break;
|
||||
case POISON:
|
||||
potion = new PoisonPotion();
|
||||
break;
|
||||
case STRENGTH:
|
||||
potion = new StrengthPotion();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case HEALING -> potion = new HealingPotion();
|
||||
case HOLY_WATER -> potion = new HolyWaterPotion();
|
||||
case INVISIBILITY -> potion = new InvisibilityPotion();
|
||||
case POISON -> potion = new PoisonPotion();
|
||||
case STRENGTH -> potion = new StrengthPotion();
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
if (potion != null) {
|
||||
potions.put(type, potion);
|
||||
|
||||
@@ -101,13 +101,10 @@ public class App {
|
||||
* @return expression
|
||||
*/
|
||||
public static Expression getOperatorInstance(String s, Expression left, Expression right) {
|
||||
switch (s) {
|
||||
case "+":
|
||||
return new PlusExpression(left, right);
|
||||
case "-":
|
||||
return new MinusExpression(left, right);
|
||||
default:
|
||||
return new MultiplyExpression(left, right);
|
||||
}
|
||||
return switch (s) {
|
||||
case "+" -> new PlusExpression(left, right);
|
||||
case "-" -> new MinusExpression(left, right);
|
||||
default -> new MultiplyExpression(left, right);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,32 +105,32 @@ public abstract class AbstractInstance implements Instance, Runnable {
|
||||
*/
|
||||
private void processMessage(Message message) {
|
||||
switch (message.getType()) {
|
||||
case ELECTION:
|
||||
case ELECTION -> {
|
||||
LOGGER.info(INSTANCE + localId + " - Election Message handling...");
|
||||
handleElectionMessage(message);
|
||||
break;
|
||||
case LEADER:
|
||||
}
|
||||
case LEADER -> {
|
||||
LOGGER.info(INSTANCE + localId + " - Leader Message handling...");
|
||||
handleLeaderMessage(message);
|
||||
break;
|
||||
case HEARTBEAT:
|
||||
}
|
||||
case HEARTBEAT -> {
|
||||
LOGGER.info(INSTANCE + localId + " - Heartbeat Message handling...");
|
||||
handleHeartbeatMessage(message);
|
||||
break;
|
||||
case ELECTION_INVOKE:
|
||||
}
|
||||
case ELECTION_INVOKE -> {
|
||||
LOGGER.info(INSTANCE + localId + " - Election Invoke Message handling...");
|
||||
handleElectionInvokeMessage();
|
||||
break;
|
||||
case LEADER_INVOKE:
|
||||
}
|
||||
case LEADER_INVOKE -> {
|
||||
LOGGER.info(INSTANCE + localId + " - Leader Invoke Message handling...");
|
||||
handleLeaderInvokeMessage();
|
||||
break;
|
||||
case HEARTBEAT_INVOKE:
|
||||
}
|
||||
case HEARTBEAT_INVOKE -> {
|
||||
LOGGER.info(INSTANCE + localId + " - Heartbeat Invoke Message handling...");
|
||||
handleHeartbeatInvokeMessage();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,35 +150,32 @@ En este ejemplo también usamos un enum para parametrizar el tipo de factoría d
|
||||
```java
|
||||
public static class FactoryMaker {
|
||||
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
-- similar use of the orc factory
|
||||
}
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
--similar use of the orc factory
|
||||
}
|
||||
```
|
||||
|
||||
## Diagrama de clases
|
||||
|
||||
@@ -148,35 +148,32 @@ This is the elven Army!
|
||||
```java
|
||||
public static class FactoryMaker {
|
||||
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
-- similar use of the orc factory
|
||||
}
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
--similar use of the orc factory
|
||||
}
|
||||
```
|
||||
|
||||
## क्लास डायग्राम
|
||||
|
||||
@@ -145,39 +145,35 @@ Agora, podemos projetar uma fábrica para nossas diferentes fábricas do reino.
|
||||
O cliente pode usar o `FactoryMaker` para criar uma fatoração concreta, que uma vez, produzirá diferentes objetos concretos (derivados de `Army`, `King`, `Castle`).
|
||||
Neste exemplo, também usamos um enum para parametrizar qual tipo de fábrica do reino o cliente solicitará.
|
||||
|
||||
|
||||
```java
|
||||
public static class FactoryMaker {
|
||||
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
-- similar use of the orc factory
|
||||
}
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
--similar use of the orc factory
|
||||
}
|
||||
```
|
||||
|
||||
## Diagrama de classes
|
||||
|
||||
@@ -34,62 +34,51 @@ Wikipedia diz
|
||||
**Exemplo programático**
|
||||
|
||||
Vamos pegar nosso exemplo da mina de ouro acima. Aqui temos uma hierarquia de anão minerador.
|
||||
Primeiro há uma classe base `DwarvenMineWorker`:
|
||||
Primeiro há uma classe base `DwarvenMineWorker`:
|
||||
|
||||
```java
|
||||
|
||||
@Slf4j
|
||||
public abstract class DwarvenMineWorker {
|
||||
|
||||
public void goToSleep() {
|
||||
LOGGER.info("{} goes to sleep.", name());
|
||||
}
|
||||
|
||||
public void wakeUp() {
|
||||
LOGGER.info("{} wakes up.", name());
|
||||
}
|
||||
|
||||
public void goHome() {
|
||||
LOGGER.info("{} goes home.", name());
|
||||
}
|
||||
|
||||
public void goToMine() {
|
||||
LOGGER.info("{} goes to the mine.", name());
|
||||
}
|
||||
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP:
|
||||
goToSleep();
|
||||
break;
|
||||
case WAKE_UP:
|
||||
wakeUp();
|
||||
break;
|
||||
case GO_HOME:
|
||||
goHome();
|
||||
break;
|
||||
case GO_TO_MINE:
|
||||
goToMine();
|
||||
break;
|
||||
case WORK:
|
||||
work();
|
||||
break;
|
||||
default:
|
||||
LOGGER.info("Undefined action");
|
||||
break;
|
||||
public void goToSleep() {
|
||||
LOGGER.info("{} goes to sleep.", name());
|
||||
}
|
||||
}
|
||||
|
||||
public void action(Action... actions) {
|
||||
Arrays.stream(actions).forEach(this::action);
|
||||
}
|
||||
public void wakeUp() {
|
||||
LOGGER.info("{} wakes up.", name());
|
||||
}
|
||||
|
||||
public abstract void work();
|
||||
public void goHome() {
|
||||
LOGGER.info("{} goes home.", name());
|
||||
}
|
||||
|
||||
public abstract String name();
|
||||
public void goToMine() {
|
||||
LOGGER.info("{} goes to the mine.", name());
|
||||
}
|
||||
|
||||
enum Action {
|
||||
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
|
||||
}
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP -> goToSleep();
|
||||
case WAKE_UP -> wakeUp();
|
||||
case GO_HOME -> goHome();
|
||||
case GO_TO_MINE -> goToMine();
|
||||
case WORK -> work();
|
||||
default -> LOGGER.info("Undefined action");
|
||||
}
|
||||
}
|
||||
|
||||
public void action(Action... actions) {
|
||||
Arrays.stream(actions).forEach(this::action);
|
||||
}
|
||||
|
||||
public abstract void work();
|
||||
|
||||
public abstract String name();
|
||||
|
||||
enum Action {
|
||||
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -150,35 +150,32 @@ Trong ví dụ này, chúng tôi cũng sử dụng một enum để tham số h
|
||||
```java
|
||||
public static class FactoryMaker {
|
||||
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
-- Tương tự với nhà máy Orc
|
||||
}
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
--Tương tự với nhà máy Orc
|
||||
}
|
||||
```
|
||||
|
||||
## Sơ đồ lớp
|
||||
|
||||
@@ -132,35 +132,32 @@ This is the Elven Army!
|
||||
```java
|
||||
public static class FactoryMaker {
|
||||
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
switch (type) {
|
||||
case ELF:
|
||||
return new ElfKingdomFactory();
|
||||
case ORC:
|
||||
return new OrcKingdomFactory();
|
||||
default:
|
||||
throw new IllegalArgumentException("KingdomType not supported.");
|
||||
public enum KingdomType {
|
||||
ELF, ORC
|
||||
}
|
||||
|
||||
public static KingdomFactory makeFactory(KingdomType type) {
|
||||
return switch (type) {
|
||||
case ELF -> new ElfKingdomFactory();
|
||||
case ORC -> new OrcKingdomFactory();
|
||||
default -> throw new IllegalArgumentException("KingdomType not supported.");
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
public static void main(String[] args) {
|
||||
var app = new App();
|
||||
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
LOGGER.info("Elf Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
|
||||
LOGGER.info(app.getArmy().getDescription());
|
||||
LOGGER.info(app.getCastle().getDescription());
|
||||
LOGGER.info(app.getKing().getDescription());
|
||||
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
-- similar use of the orc factory
|
||||
}
|
||||
LOGGER.info("Orc Kingdom");
|
||||
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
|
||||
--similar use of the orc factory
|
||||
}
|
||||
```
|
||||
|
||||
## 类图
|
||||
|
||||
@@ -152,127 +152,126 @@ public class MonitoringService {
|
||||
```java
|
||||
public class DefaultCircuitBreaker implements CircuitBreaker {
|
||||
|
||||
private final long timeout;
|
||||
private final long retryTimePeriod;
|
||||
private final RemoteService service;
|
||||
long lastFailureTime;
|
||||
private String lastFailureResponse;
|
||||
int failureCount;
|
||||
private final int failureThreshold;
|
||||
private State state;
|
||||
private final long futureTime = 1000 * 1000 * 1000 * 1000;
|
||||
private final long timeout;
|
||||
private final long retryTimePeriod;
|
||||
private final RemoteService service;
|
||||
long lastFailureTime;
|
||||
private String lastFailureResponse;
|
||||
int failureCount;
|
||||
private final int failureThreshold;
|
||||
private State state;
|
||||
private final long futureTime = 1000 * 1000 * 1000 * 1000;
|
||||
|
||||
/**
|
||||
* Constructor to create an instance of Circuit Breaker.
|
||||
*
|
||||
* @param timeout Timeout for the API request. Not necessary for this simple example
|
||||
* @param failureThreshold Number of failures we receive from the depended service before changing
|
||||
* state to 'OPEN'
|
||||
* @param retryTimePeriod Time period after which a new request is made to remote service for
|
||||
* status check.
|
||||
*/
|
||||
DefaultCircuitBreaker(RemoteService serviceToCall, long timeout, int failureThreshold,
|
||||
long retryTimePeriod) {
|
||||
this.service = serviceToCall;
|
||||
// 我们从关闭状态开始希望一切都是正常的
|
||||
this.state = State.CLOSED;
|
||||
this.failureThreshold = failureThreshold;
|
||||
// API的超时时间.
|
||||
// 用于在超过限制时中断对远程资源的调用
|
||||
this.timeout = timeout;
|
||||
this.retryTimePeriod = retryTimePeriod;
|
||||
//An absurd amount of time in future which basically indicates the last failure never happened
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.failureCount = 0;
|
||||
}
|
||||
|
||||
// 重置所有
|
||||
@Override
|
||||
public void recordSuccess() {
|
||||
this.failureCount = 0;
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.state = State.CLOSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFailure(String response) {
|
||||
failureCount = failureCount + 1;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
// Cache the failure response for returning on open state
|
||||
this.lastFailureResponse = response;
|
||||
}
|
||||
|
||||
// 根据 failureThreshold、failureCount 和 lastFailureTime 评估当前状态。
|
||||
protected void evaluateState() {
|
||||
if (failureCount >= failureThreshold) { //Then something is wrong with remote service
|
||||
if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
|
||||
// 我们已经等得够久了,应该尝试检查服务是否已启动
|
||||
state = State.HALF_OPEN;
|
||||
} else {
|
||||
// 服务可能仍会出现故障
|
||||
state = State.OPEN;
|
||||
}
|
||||
} else {
|
||||
// 一切正常
|
||||
state = State.CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getState() {
|
||||
evaluateState();
|
||||
return state.name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Break the circuit beforehand if it is known service is down Or connect the circuit manually if
|
||||
* service comes online before expected.
|
||||
*
|
||||
* @param state State at which circuit is in
|
||||
*/
|
||||
@Override
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case OPEN:
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
break;
|
||||
case HALF_OPEN:
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime() - retryTimePeriod;
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* Constructor to create an instance of Circuit Breaker.
|
||||
*
|
||||
* @param timeout Timeout for the API request. Not necessary for this simple example
|
||||
* @param failureThreshold Number of failures we receive from the depended service before changing
|
||||
* state to 'OPEN'
|
||||
* @param retryTimePeriod Time period after which a new request is made to remote service for
|
||||
* status check.
|
||||
*/
|
||||
DefaultCircuitBreaker(RemoteService serviceToCall, long timeout, int failureThreshold,
|
||||
long retryTimePeriod) {
|
||||
this.service = serviceToCall;
|
||||
// 我们从关闭状态开始希望一切都是正常的
|
||||
this.state = State.CLOSED;
|
||||
this.failureThreshold = failureThreshold;
|
||||
// API的超时时间.
|
||||
// 用于在超过限制时中断对远程资源的调用
|
||||
this.timeout = timeout;
|
||||
this.retryTimePeriod = retryTimePeriod;
|
||||
//An absurd amount of time in future which basically indicates the last failure never happened
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.failureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes service call.
|
||||
*
|
||||
* @return Value from the remote resource, stale response or a custom exception
|
||||
*/
|
||||
@Override
|
||||
public String attemptRequest() throws RemoteServiceException {
|
||||
evaluateState();
|
||||
if (state == State.OPEN) {
|
||||
// 如果电路处于打开状态,则返回缓存的响应
|
||||
return this.lastFailureResponse;
|
||||
} else {
|
||||
// 如果电路未打开,则发出 API 请求
|
||||
try {
|
||||
//在实际应用程序中,这将在线程中运行,并且将利用断路器的超时参数来了解服务
|
||||
// 是否正在工作。 在这里,我们根据服务器响应本身模拟
|
||||
var response = service.call();
|
||||
// api 响应正常,重置所有。
|
||||
recordSuccess();
|
||||
return response;
|
||||
} catch (RemoteServiceException ex) {
|
||||
recordFailure(ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
// 重置所有
|
||||
@Override
|
||||
public void recordSuccess() {
|
||||
this.failureCount = 0;
|
||||
this.lastFailureTime = System.nanoTime() + futureTime;
|
||||
this.state = State.CLOSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFailure(String response) {
|
||||
failureCount = failureCount + 1;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
// Cache the failure response for returning on open state
|
||||
this.lastFailureResponse = response;
|
||||
}
|
||||
|
||||
// 根据 failureThreshold、failureCount 和 lastFailureTime 评估当前状态。
|
||||
protected void evaluateState() {
|
||||
if (failureCount >= failureThreshold) { //Then something is wrong with remote service
|
||||
if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
|
||||
// 我们已经等得够久了,应该尝试检查服务是否已启动
|
||||
state = State.HALF_OPEN;
|
||||
} else {
|
||||
// 服务可能仍会出现故障
|
||||
state = State.OPEN;
|
||||
}
|
||||
} else {
|
||||
// 一切正常
|
||||
state = State.CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getState() {
|
||||
evaluateState();
|
||||
return state.name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Break the circuit beforehand if it is known service is down Or connect the circuit manually if
|
||||
* service comes online before expected.
|
||||
*
|
||||
* @param state State at which circuit is in
|
||||
*/
|
||||
@Override
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case OPEN -> {
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime();
|
||||
}
|
||||
case HALF_OPEN -> {
|
||||
this.failureCount = failureThreshold;
|
||||
this.lastFailureTime = System.nanoTime() - retryTimePeriod;
|
||||
}
|
||||
default -> this.failureCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes service call.
|
||||
*
|
||||
* @return Value from the remote resource, stale response or a custom exception
|
||||
*/
|
||||
@Override
|
||||
public String attemptRequest() throws RemoteServiceException {
|
||||
evaluateState();
|
||||
if (state == State.OPEN) {
|
||||
// 如果电路处于打开状态,则返回缓存的响应
|
||||
return this.lastFailureResponse;
|
||||
} else {
|
||||
// 如果电路未打开,则发出 API 请求
|
||||
try {
|
||||
//在实际应用程序中,这将在线程中运行,并且将利用断路器的超时参数来了解服务
|
||||
// 是否正在工作。 在这里,我们根据服务器响应本身模拟
|
||||
var response = service.call();
|
||||
// api 响应正常,重置所有。
|
||||
recordSuccess();
|
||||
return response;
|
||||
} catch (RemoteServiceException ex) {
|
||||
recordFailure(ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -29,101 +29,90 @@ tag:
|
||||
使用上面金矿的例子。这里我们有矮人的矿工等级制度。
|
||||
|
||||
```java
|
||||
|
||||
@Slf4j
|
||||
public abstract class DwarvenMineWorker {
|
||||
|
||||
public void goToSleep() {
|
||||
LOGGER.info("{} goes to sleep.", name());
|
||||
}
|
||||
|
||||
public void wakeUp() {
|
||||
LOGGER.info("{} wakes up.", name());
|
||||
}
|
||||
|
||||
public void goHome() {
|
||||
LOGGER.info("{} goes home.", name());
|
||||
}
|
||||
|
||||
public void goToMine() {
|
||||
LOGGER.info("{} goes to the mine.", name());
|
||||
}
|
||||
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP:
|
||||
goToSleep();
|
||||
break;
|
||||
case WAKE_UP:
|
||||
wakeUp();
|
||||
break;
|
||||
case GO_HOME:
|
||||
goHome();
|
||||
break;
|
||||
case GO_TO_MINE:
|
||||
goToMine();
|
||||
break;
|
||||
case WORK:
|
||||
work();
|
||||
break;
|
||||
default:
|
||||
LOGGER.info("Undefined action");
|
||||
break;
|
||||
public void goToSleep() {
|
||||
LOGGER.info("{} goes to sleep.", name());
|
||||
}
|
||||
}
|
||||
|
||||
public void action(Action... actions) {
|
||||
Arrays.stream(actions).forEach(this::action);
|
||||
}
|
||||
public void wakeUp() {
|
||||
LOGGER.info("{} wakes up.", name());
|
||||
}
|
||||
|
||||
public abstract void work();
|
||||
public void goHome() {
|
||||
LOGGER.info("{} goes home.", name());
|
||||
}
|
||||
|
||||
public abstract String name();
|
||||
public void goToMine() {
|
||||
LOGGER.info("{} goes to the mine.", name());
|
||||
}
|
||||
|
||||
enum Action {
|
||||
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
|
||||
}
|
||||
private void action(Action action) {
|
||||
switch (action) {
|
||||
case GO_TO_SLEEP -> goToSleep();
|
||||
case WAKE_UP -> wakeUp();
|
||||
case GO_HOME -> goHome();
|
||||
case GO_TO_MINE -> goToMine();
|
||||
case WORK -> work();
|
||||
default -> LOGGER.info("Undefined action");
|
||||
}
|
||||
}
|
||||
|
||||
public void action(Action... actions) {
|
||||
Arrays.stream(actions).forEach(this::action);
|
||||
}
|
||||
|
||||
public abstract void work();
|
||||
|
||||
public abstract String name();
|
||||
|
||||
enum Action {
|
||||
GO_TO_SLEEP, WAKE_UP, GO_HOME, GO_TO_MINE, WORK
|
||||
}
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
public class DwarvenTunnelDigger extends DwarvenMineWorker {
|
||||
|
||||
@Override
|
||||
public void work() {
|
||||
LOGGER.info("{} creates another promising tunnel.", name());
|
||||
}
|
||||
@Override
|
||||
public void work() {
|
||||
LOGGER.info("{} creates another promising tunnel.", name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "Dwarven tunnel digger";
|
||||
}
|
||||
@Override
|
||||
public String name() {
|
||||
return "Dwarven tunnel digger";
|
||||
}
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
public class DwarvenGoldDigger extends DwarvenMineWorker {
|
||||
|
||||
@Override
|
||||
public void work() {
|
||||
LOGGER.info("{} digs for gold.", name());
|
||||
}
|
||||
@Override
|
||||
public void work() {
|
||||
LOGGER.info("{} digs for gold.", name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "Dwarf gold digger";
|
||||
}
|
||||
@Override
|
||||
public String name() {
|
||||
return "Dwarf gold digger";
|
||||
}
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
public class DwarvenCartOperator extends DwarvenMineWorker {
|
||||
|
||||
@Override
|
||||
public void work() {
|
||||
LOGGER.info("{} moves gold chunks out of the mine.", name());
|
||||
}
|
||||
@Override
|
||||
public void work() {
|
||||
LOGGER.info("{} moves gold chunks out of the mine.", name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "Dwarf cart operator";
|
||||
}
|
||||
@Override
|
||||
public String name() {
|
||||
return "Dwarf cart operator";
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+51
-59
@@ -56,70 +56,62 @@ public interface StarMemento {
|
||||
|
||||
public class Star {
|
||||
|
||||
private StarType type;
|
||||
private int ageYears;
|
||||
private int massTons;
|
||||
|
||||
public Star(StarType startType, int startAge, int startMass) {
|
||||
this.type = startType;
|
||||
this.ageYears = startAge;
|
||||
this.massTons = startMass;
|
||||
}
|
||||
|
||||
public void timePasses() {
|
||||
ageYears *= 2;
|
||||
massTons *= 8;
|
||||
switch (type) {
|
||||
case RED_GIANT:
|
||||
type = StarType.WHITE_DWARF;
|
||||
break;
|
||||
case SUN:
|
||||
type = StarType.RED_GIANT;
|
||||
break;
|
||||
case SUPERNOVA:
|
||||
type = StarType.DEAD;
|
||||
break;
|
||||
case WHITE_DWARF:
|
||||
type = StarType.SUPERNOVA;
|
||||
break;
|
||||
case DEAD:
|
||||
ageYears *= 2;
|
||||
massTons = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StarMemento getMemento() {
|
||||
var state = new StarMementoInternal();
|
||||
state.setAgeYears(ageYears);
|
||||
state.setMassTons(massTons);
|
||||
state.setType(type);
|
||||
return state;
|
||||
}
|
||||
|
||||
void setMemento(StarMemento memento) {
|
||||
var state = (StarMementoInternal) memento;
|
||||
this.type = state.getType();
|
||||
this.ageYears = state.getAgeYears();
|
||||
this.massTons = state.getMassTons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons);
|
||||
}
|
||||
|
||||
private static class StarMementoInternal implements StarMemento {
|
||||
|
||||
private StarType type;
|
||||
private int ageYears;
|
||||
private int massTons;
|
||||
|
||||
// setters and getters ->
|
||||
public Star(StarType startType, int startAge, int startMass) {
|
||||
this.type = startType;
|
||||
this.ageYears = startAge;
|
||||
this.massTons = startMass;
|
||||
}
|
||||
|
||||
public void timePasses() {
|
||||
ageYears *= 2;
|
||||
massTons *= 8;
|
||||
switch (type) {
|
||||
case RED_GIANT -> type = StarType.WHITE_DWARF;
|
||||
case SUN -> type = StarType.RED_GIANT;
|
||||
case SUPERNOVA -> type = StarType.DEAD;
|
||||
case WHITE_DWARF -> type = StarType.SUPERNOVA;
|
||||
case DEAD -> {
|
||||
ageYears *= 2;
|
||||
massTons = 0;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StarMemento getMemento() {
|
||||
var state = new StarMementoInternal();
|
||||
state.setAgeYears(ageYears);
|
||||
state.setMassTons(massTons);
|
||||
state.setType(type);
|
||||
return state;
|
||||
}
|
||||
|
||||
void setMemento(StarMemento memento) {
|
||||
var state = (StarMementoInternal) memento;
|
||||
this.type = state.getType();
|
||||
this.ageYears = state.getAgeYears();
|
||||
this.massTons = state.getMassTons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons);
|
||||
}
|
||||
|
||||
private static class StarMementoInternal implements StarMemento {
|
||||
|
||||
private StarType type;
|
||||
private int ageYears;
|
||||
private int massTons;
|
||||
|
||||
// setters and getters ->
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -49,24 +49,16 @@ public class Star {
|
||||
ageYears *= 2;
|
||||
massTons *= 8;
|
||||
switch (type) {
|
||||
case RED_GIANT:
|
||||
type = StarType.WHITE_DWARF;
|
||||
break;
|
||||
case SUN:
|
||||
type = StarType.RED_GIANT;
|
||||
break;
|
||||
case SUPERNOVA:
|
||||
type = StarType.DEAD;
|
||||
break;
|
||||
case WHITE_DWARF:
|
||||
type = StarType.SUPERNOVA;
|
||||
break;
|
||||
case DEAD:
|
||||
case RED_GIANT -> type = StarType.WHITE_DWARF;
|
||||
case SUN -> type = StarType.RED_GIANT;
|
||||
case SUPERNOVA -> type = StarType.DEAD;
|
||||
case WHITE_DWARF -> type = StarType.SUPERNOVA;
|
||||
case DEAD -> {
|
||||
ageYears *= 2;
|
||||
massTons = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-22
@@ -26,30 +26,17 @@ public final class CalculatorViewModel {
|
||||
*/
|
||||
void handleAction(final CalculatorAction action) {
|
||||
switch (action.tag()) {
|
||||
case AdditionCalculatorAction.TAG:
|
||||
add();
|
||||
break;
|
||||
|
||||
case SubtractionCalculatorAction.TAG:
|
||||
subtract();
|
||||
break;
|
||||
|
||||
case MultiplicationCalculatorAction.TAG:
|
||||
multiply();
|
||||
break;
|
||||
|
||||
case DivisionCalculatorAction.TAG:
|
||||
divide();
|
||||
break;
|
||||
|
||||
case SetVariableCalculatorAction.TAG:
|
||||
case AdditionCalculatorAction.TAG -> add();
|
||||
case SubtractionCalculatorAction.TAG -> subtract();
|
||||
case MultiplicationCalculatorAction.TAG -> multiply();
|
||||
case DivisionCalculatorAction.TAG -> divide();
|
||||
case SetVariableCalculatorAction.TAG -> {
|
||||
SetVariableCalculatorAction setVariableAction =
|
||||
(SetVariableCalculatorAction) action;
|
||||
(SetVariableCalculatorAction) action;
|
||||
setVariable(setVariableAction.getVariable());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,16 +45,12 @@ public class RangeShardManager extends ShardManager {
|
||||
@Override
|
||||
protected int allocateShard(Data data) {
|
||||
var type = data.getType();
|
||||
switch (type) {
|
||||
case TYPE_1:
|
||||
return 1;
|
||||
case TYPE_2:
|
||||
return 2;
|
||||
case TYPE_3:
|
||||
return 3;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return switch (type) {
|
||||
case TYPE_1 -> 1;
|
||||
case TYPE_2 -> 2;
|
||||
case TYPE_3 -> 3;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user