refactoring: issue#2376 (#2491)

Changed all the switch expression according to the JAVA 17.
This commit is contained in:
akshatarora0013 authored and GitHub committed 2023-04-01 17:48:38 +03:00
1 parent fc7e672419
commit 9d6ae392b8
23 files changed
+607 -723

No files matched your search

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