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
+608 -724

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
+35 -46
View File
@@ -34,62 +34,51 @@ Wikipedia diz
**Exemplo programático** **Exemplo programático**
Vamos pegar nosso exemplo da mina de ouro acima. Aqui temos uma hierarquia de anão minerador. 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 ```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;
}
} }
} }